diff --git a/.agents/skills/review-crds/SKILL.md b/.agents/skills/review-crds/SKILL.md index 2e3ea77fd0..b7c97652ef 100644 --- a/.agents/skills/review-crds/SKILL.md +++ b/.agents/skills/review-crds/SKILL.md @@ -29,7 +29,7 @@ Your output should be a list of violations conforming to the following JSON form ## Hints -- All CRDs are defined in `pkg/api/v1alpha1`. +- All CRDs are defined in `api/infra/k8s/ate/v1`. ## References - [Kubernetes API Conventions](references/api-conventions.md) diff --git a/.agents/skills/sync-upstream-main/SKILL.md b/.agents/skills/sync-upstream-main/SKILL.md index b7c2078519..6963783978 100644 --- a/.agents/skills/sync-upstream-main/SKILL.md +++ b/.agents/skills/sync-upstream-main/SKILL.md @@ -8,7 +8,10 @@ description: Merge agent-substrate/substrate upstream/main into the kagent-dev/s The fork uses merge-based synchronization. Start a branch from current `origin/main`, merge `upstream/main`, and submit that branch to `origin/main`. Preserve upstream ancestry so later synchronizations contain only new changes. -Do not replay fork commits, squash upstream history, force-push, or push to main. +Each sync PR must contain exactly one sync merge commit on top of `origin/main`, +with all conflict resolutions, integration fixes, and skill updates folded into +it. Preserve the incoming upstream commits; do not squash their history. +Do not replay fork commits or push to main. Creating a PR requires an explicit request or approval; approval to create it does not authorize merging it. @@ -31,9 +34,9 @@ does not authorize merging it. render check excludes preserved manifests, so passing it alone does not establish parity. Keep `charts/substrate-crds/templates` synchronized with generated CRDs. -6. Commit the merge with `git commit -s`. Keep any additional fixes or workflow - documentation in focused signed-off commits. Omit issue and PR references - from commit messages. +6. Commit the merge with `git commit -s`. Fold later fixes and documentation + into that same commit with `git commit --amend -s`; do not leave follow-up + commits on the sync branch. Omit issue and PR references from commit messages. ## Validate and investigate failures @@ -56,9 +59,18 @@ that the failure is resolved. Report test counts and skips when relevant. ## Publish the PR -Before publishing, fetch both refs again and incorporate any new main changes -with merges. Verify that both recorded main tips are ancestors of the branch, -the diff is intentional, and the worktree is clean. Push only the sync branch. +Before publishing, fetch both refs again. If either main tip changed, rebuild +the single merge from the latest `origin/main` and `upstream/main`, reapplying +and checking the integration fixes. Do not stack additional merge commits. +Verify that `git rev-list --first-parent --count origin/main..HEAD` returns `1` +and HEAD has exactly two parents: `origin/main` first, `upstream/main` second. +Check that the diff is intentional and the worktree is clean. + +Push only the sync branch. When amending an already published merge, verify +the remote still matches the last observed PR head and push with an explicit +`--force-with-lease=refs/heads/:`. Never force-push +unguarded or overwrite another contributor's changes. Verify that folding +commits preserved the intended tree, and report checks for the new commit SHA. When PR creation is authorized, open it against `kagent-dev/substrate:main`. Describe the upstream SHA, material changes, conflict resolutions, required diff --git a/.agents/skills/triage-issues/SKILL.md b/.agents/skills/triage-issues/SKILL.md index 205dcaf1f0..be21b1b5dd 100644 --- a/.agents/skills/triage-issues/SKILL.md +++ b/.agents/skills/triage-issues/SKILL.md @@ -48,7 +48,7 @@ Apply all areas that are touched. Most issues need one or two; a few need more. | Label | Scope | |---|---| -| `area/api` | User-facing Substrate API (`pkg/proto/ateapipb/`, proto definitions, API semantics, versioning) | +| `area/api` | User-facing Substrate API (`api/ateapi/v1/`, proto definitions, API semantics, versioning) | | `area/api-machinery` | API server internals: RPC handlers, storage layer, syncer, controllers (`cmd/ateapi/`, `cmd/atecontroller/`) | | `area/network` | Networking: atenet-router, Envoy, ext_proc, DNS, xDS, ingress (`cmd/atenet/`) | | `area/node` | Node agent and worker lifecycle: atelet, sandbox launch, OCI, cgroups (`cmd/atelet/`) | diff --git a/.github/SECURITY.md b/.github/SECURITY.md index cd1640ace0..d5acdcc747 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -6,26 +6,31 @@ vulnerabilities.** Use [GitHub Private Vulnerability Reporting](https://github.com/agent-substrate/substrate/security/advisories/new) -to report security vulnerabilities privately. Note that this project is not -eligible for the -[Google Open Source Software Vulnerability Rewards Program](https://bughunters.google.com/open-source-security). +to report security vulnerabilities privately. Verify that there is no existing +open GitHub issue covering the problem before creating a report. -Please include: +Please ensure your report is concise and clearly articulates the bug. It should +include: +- How the issue is reachable and exploitable by untrusted code running inside an + actor sandbox. Or a statement that it isn't exploitable from inside an actor + sandbox. +- The security impact resulting from exploitation of the bug. - The affected component and version or commit SHA. -- Steps to reproduce, or a proof of concept. -- The potential impact, and mitigations if known. +- Detailed steps to fully reproduce, or a proof of concept. +- Mitigations if known. ### When to report - You found a potential security vulnerability in Agent Substrate. -- You are unsure whether a security issue affects Agent Substrate. - You found a vulnerability in a project Agent Substrate depends on and it is exploitable through Agent Substrate. If that project has its own disclosure process, please report it there as well. ### When not to report +- Theoretical bugs from static analysis without demonstration of an exploitable + security issue. - You need help securing or tuning a deployment (open a regular issue or discussion). - The issue is not security related. @@ -76,8 +81,7 @@ from most to least severe: - Sample applications under `demos/` and load-testing harnesses under `benchmarking/`. - Documented scope boundaries and future capabilities listed in - [docs/security.md](../docs/security.md) and - [docs/roadmap.md](../docs/roadmap.md) at the time of your report. If you are + [docs/security.md](../docs/security.md) at the time of your report. If you are unsure whether a finding is covered by a documented limitation, report it privately anyway and let a maintainer make the call. diff --git a/.golangci-kal.yaml b/.golangci-kal.yaml index cc773f3336..e7abfc8cb5 100644 --- a/.golangci-kal.yaml +++ b/.golangci-kal.yaml @@ -13,7 +13,7 @@ # limitations under the License. # Config for kube-api-linter (github.com/kubernetes-sigs/kube-api-linter), -# run by hack/verify/kube-api-linter.sh against the API types in pkg/api/. +# run by hack/verify/kube-api-linter.sh against the API types in api/infra/. # It is a separate file from .golangci.yaml because the kubeapilinter module # plugin only exists in the golangci-lint-kube-api-linter binary, not in the # regular golangci-lint one. @@ -75,34 +75,34 @@ linters: rules: # Pre-existing findings from rules that require Go API changes # (pointer fields, omitempty/omitzero tags, map-to-list refactors) - # on the existing v1alpha1 types. Each rule names the fields it + # on the existing ate/v1 types. Each rule names the fields it # excuses, so a field added to one of these types is still checked. # Fixing these on the existing types is tracked in issue #207. - - path: 'pkg/api/v1alpha1/sandboxconfig_types\.go' + - path: 'api/infra/k8s/ate/v1/sandboxconfig_types\.go' text: '^requiredfields: .*\bAssetFile\.(SHA256|URL)\b' - - path: 'pkg/api/v1alpha1/sandboxconfig_types\.go' + - path: 'api/infra/k8s/ate/v1/sandboxconfig_types\.go' text: '^(optionalfields|requiredfields): .*\bSandboxConfigSpec\.SandboxClass\b' - - path: 'pkg/api/v1alpha1/sandboxconfig_types\.go' + - path: 'api/infra/k8s/ate/v1/sandboxconfig_types\.go' text: '^(nomaps|optionalfields): .*\bSandboxVersionConfig\.Assets\b' - - path: 'pkg/api/v1alpha1/sandboxconfig_types\.go' + - path: 'api/infra/k8s/ate/v1/sandboxconfig_types\.go' text: '^(nonpointerstructs|requiredfields): .*\bSandboxConfig\.Spec\b' - - path: 'pkg/api/v1alpha1/csidriverconfig_types\.go' + - path: 'api/infra/k8s/ate/v1/csidriverconfig_types\.go' text: '^requiredfields: .*\bCSIDriverConfigSpec\.(ControllerEndpoint|DriverName)\b' - - path: 'pkg/api/v1alpha1/csidriverconfig_types\.go' + - path: 'api/infra/k8s/ate/v1/csidriverconfig_types\.go' text: '^optionalfields: .*\bCSIDriverConfigSpec\.NodeSocketOverride\b' - - path: 'pkg/api/v1alpha1/csidriverconfig_types\.go' + - path: 'api/infra/k8s/ate/v1/csidriverconfig_types\.go' text: '^requiredfields: .*\bCSIDriverTLSConfig\.Enabled\b' - - path: 'pkg/api/v1alpha1/csidriverconfig_types\.go' + - path: 'api/infra/k8s/ate/v1/csidriverconfig_types\.go' text: '^optionalfields: .*\bCSIDriverTLSConfig\.(ServerName|UsePodIdentity)\b' - - path: 'pkg/api/v1alpha1/csidriverconfig_types\.go' + - path: 'api/infra/k8s/ate/v1/csidriverconfig_types\.go' text: '^(nonpointerstructs|requiredfields): .*\bCSIDriverConfig\.Spec\b' - - path: 'pkg/api/v1alpha1/workerpool_types\.go' + - path: 'api/infra/k8s/ate/v1/workerpool_types\.go' text: '^optionalfields: .*\bWorkerPoolPodTemplate\.PriorityClassName\b' - - path: 'pkg/api/v1alpha1/workerpool_types\.go' + - path: 'api/infra/k8s/ate/v1/workerpool_types\.go' text: '^(optionalfields|requiredfields): .*\bWorkerPoolSpec\.(Replicas|WorkerImage)\b' - - path: 'pkg/api/v1alpha1/workerpool_types\.go' + - path: 'api/infra/k8s/ate/v1/workerpool_types\.go' text: '^optionalfields: .*\bWorkerPoolStatus\.(ReadyReplicas|Replicas|Selector)\b' - - path: 'pkg/api/v1alpha1/workerpool_types\.go' + - path: 'api/infra/k8s/ate/v1/workerpool_types\.go' text: '^(optionalfields|requiredfields): .*\bWorkerPool\.(Spec|Status)\b' issues: diff --git a/AGENTS.md b/AGENTS.md index e0d6250cca..6494966a1c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -25,6 +25,7 @@ ### Scope - Keep each PR to one change. Send refactors, cleanups and follow-ups as separate PRs. For how to batch small fixes, see "Sizing PRs for review" in `CONTRIBUTING.md`. +- Split a PR into commits that are easy to review in order. PRs are squash-merged, so only the branch `HEAD` needs to build and pass tests. - Follow "Contribution process" in `CONTRIBUTING.md`: open an issue first for anything beyond a small fix, and search open PRs and issues before you start. - Start the PR description with why the change is needed, or link the issue. Only write "Fixes #N" if the PR fully fixes it, and keep the description in sync with the final diff. - Rebase onto upstream `main` before opening a PR, and don't merge main into your branch. This file may have changed there. Follow that version. @@ -68,6 +69,7 @@ See `hack/install-ate.sh` and `tools/setup-gcp` for provisioning and deploying c ## Repository Layout ``` +api/ # Public APIs: protos and CRD types, one directory per API and version cmd/ # One subdirectory per binary (ateapi, atelet, atenet, …) internal/ # Shared packages, internal to this module only pkg/ # Shared packages intended for external import @@ -86,11 +88,12 @@ tools/ # Standalone Go tools (go run ./tools/) for Dev/CI | Only used by one binary | `cmd//internal/` | | Shared across binaries, not for external import | `internal/` | | Public API for external consumers | `pkg/` | -| Public proto (control-plane gRPC API) | `pkg/proto/` | +| Public gRPC API | `api//` | +| Kubernetes CRD types | `api/infra/k8s//` | | Internal proto (atelet / ateworker) | `internal/proto/` | | Dev/CI scripts | `hack/` | | Standalone Go dev/CI tools | `tools/` with its own `go.mod` | -| Self-contained plugin that nothing in the repo depends on | `internal/plugins/` with its own `go.mod`, importing only `pkg/`; see `internal/plugins/README.md` | +| Self-contained plugin that nothing in the repo depends on | `internal/plugins/` with its own `go.mod`, importing only `api/` and `pkg/`; see `internal/plugins/README.md` | See `docs/dev/code-layout.md` for the full rationale and per-directory details. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b8af87a341..6b716b883f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -70,7 +70,8 @@ down, small PRs get merged. * **Large PRs**: split huge changes into a series of smaller PRs, each a logically distinct feature. When the intermediate steps are not useful on their own, keep the change as one PR split into commits at logical - break points, and preserve those commits on merge. + break points for review. PRs are squash-merged, so only the branch + `HEAD` needs to build and pass tests. * **Small and bulk PRs**: if you find a typo, review the whole file and fix everything in one pass rather than sending the single edit. Group related typo, doc, and single-line cleanup fixes into one PR rather diff --git a/README.md b/README.md index 2508d717bd..dc686a2640 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) -[Quickstart](#quickstart-development) · [Security](docs/security.md) · [Architecture](docs/architecture.md) · [Roadmap](docs/roadmap.md) · [Contributing](CONTRIBUTING.md) +[Quickstart](#quickstart-development) · [Security](docs/security.md) · [Architecture](docs/architecture.md) · [Contributing](CONTRIBUTING.md) @@ -260,7 +260,6 @@ We provide several sample applications demonstrating Agent Substrate's capabilit * [Upgrade Runbook](docs/upgrade.md): Upgrade a running install to a newer supported release, and roll back if needed. * [Node Storage](docs/node-storage.md): How to give snapshot I/O its own disk. * [Security Guide](docs/security.md): Security overview, security principles, and threat modeling. -* [Roadmap](docs/roadmap.md): Current limitations and what is planned next. * [Benchmarking Guide](benchmarking/README.md): Locust-based load tests, monitoring stack, and the orchestrated benchmark harness. ## Tour diff --git a/pkg/proto/ateapipb/AGENTS.md b/api/ateapi/v1/AGENTS.md similarity index 97% rename from pkg/proto/ateapipb/AGENTS.md rename to api/ateapi/v1/AGENTS.md index 3da3ae6db7..511e64317d 100644 --- a/pkg/proto/ateapipb/AGENTS.md +++ b/api/ateapi/v1/AGENTS.md @@ -1,4 +1,4 @@ -# ateapipb +# ateapi `ateapi.proto` defines Substrate's public API. diff --git a/pkg/proto/ateapipb/ateapi.pb.go b/api/ateapi/v1/ateapi.pb.go similarity index 72% rename from pkg/proto/ateapipb/ateapi.pb.go rename to api/ateapi/v1/ateapi.pb.go index 2a7a62178f..250a2f5968 100644 --- a/pkg/proto/ateapipb/ateapi.pb.go +++ b/api/ateapi/v1/ateapi.pb.go @@ -16,9 +16,9 @@ // versions: // protoc-gen-go v1.36.11-devel // protoc v4.25.3 -// source: ateapi.proto +// source: api/ateapi/v1/ateapi.proto -package ateapipb +package ateapi import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -73,11 +73,11 @@ func (x SnapshotOwner) String() string { } func (SnapshotOwner) Descriptor() protoreflect.EnumDescriptor { - return file_ateapi_proto_enumTypes[0].Descriptor() + return file_api_ateapi_v1_ateapi_proto_enumTypes[0].Descriptor() } func (SnapshotOwner) Type() protoreflect.EnumType { - return &file_ateapi_proto_enumTypes[0] + return &file_api_ateapi_v1_ateapi_proto_enumTypes[0] } func (x SnapshotOwner) Number() protoreflect.EnumNumber { @@ -86,7 +86,7 @@ func (x SnapshotOwner) Number() protoreflect.EnumNumber { // Deprecated: Use SnapshotOwner.Descriptor instead. func (SnapshotOwner) EnumDescriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{0} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{0} } // SnapshotStorageStatus indicates the lifecycle stage of a durable snapshot. @@ -125,11 +125,11 @@ func (x SnapshotStorageStatus) String() string { } func (SnapshotStorageStatus) Descriptor() protoreflect.EnumDescriptor { - return file_ateapi_proto_enumTypes[1].Descriptor() + return file_api_ateapi_v1_ateapi_proto_enumTypes[1].Descriptor() } func (SnapshotStorageStatus) Type() protoreflect.EnumType { - return &file_ateapi_proto_enumTypes[1] + return &file_api_ateapi_v1_ateapi_proto_enumTypes[1] } func (x SnapshotStorageStatus) Number() protoreflect.EnumNumber { @@ -138,7 +138,7 @@ func (x SnapshotStorageStatus) Number() protoreflect.EnumNumber { // Deprecated: Use SnapshotStorageStatus.Descriptor instead. func (SnapshotStorageStatus) EnumDescriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{1} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{1} } // SnapshotFidelity orders the state layers a snapshot can hold, lowest to @@ -185,11 +185,11 @@ func (x SnapshotFidelity) String() string { } func (SnapshotFidelity) Descriptor() protoreflect.EnumDescriptor { - return file_ateapi_proto_enumTypes[2].Descriptor() + return file_api_ateapi_v1_ateapi_proto_enumTypes[2].Descriptor() } func (SnapshotFidelity) Type() protoreflect.EnumType { - return &file_ateapi_proto_enumTypes[2] + return &file_api_ateapi_v1_ateapi_proto_enumTypes[2] } func (x SnapshotFidelity) Number() protoreflect.EnumNumber { @@ -198,7 +198,7 @@ func (x SnapshotFidelity) Number() protoreflect.EnumNumber { // Deprecated: Use SnapshotFidelity.Descriptor instead. func (SnapshotFidelity) EnumDescriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{2} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{2} } type TagScope int32 @@ -238,11 +238,11 @@ func (x TagScope) String() string { } func (TagScope) Descriptor() protoreflect.EnumDescriptor { - return file_ateapi_proto_enumTypes[3].Descriptor() + return file_api_ateapi_v1_ateapi_proto_enumTypes[3].Descriptor() } func (TagScope) Type() protoreflect.EnumType { - return &file_ateapi_proto_enumTypes[3] + return &file_api_ateapi_v1_ateapi_proto_enumTypes[3] } func (x TagScope) Number() protoreflect.EnumNumber { @@ -251,7 +251,7 @@ func (x TagScope) Number() protoreflect.EnumNumber { // Deprecated: Use TagScope.Descriptor instead. func (TagScope) EnumDescriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{3} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{3} } type ActorState int32 @@ -302,11 +302,11 @@ func (x ActorState) String() string { } func (ActorState) Descriptor() protoreflect.EnumDescriptor { - return file_ateapi_proto_enumTypes[4].Descriptor() + return file_api_ateapi_v1_ateapi_proto_enumTypes[4].Descriptor() } func (ActorState) Type() protoreflect.EnumType { - return &file_ateapi_proto_enumTypes[4] + return &file_api_ateapi_v1_ateapi_proto_enumTypes[4] } func (x ActorState) Number() protoreflect.EnumNumber { @@ -315,7 +315,7 @@ func (x ActorState) Number() protoreflect.EnumNumber { // Deprecated: Use ActorState.Descriptor instead. func (ActorState) EnumDescriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{4} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{4} } // GoldenSnapshotMode selects whether a template builds a golden snapshot. @@ -352,11 +352,11 @@ func (x GoldenSnapshotMode) String() string { } func (GoldenSnapshotMode) Descriptor() protoreflect.EnumDescriptor { - return file_ateapi_proto_enumTypes[5].Descriptor() + return file_api_ateapi_v1_ateapi_proto_enumTypes[5].Descriptor() } func (GoldenSnapshotMode) Type() protoreflect.EnumType { - return &file_ateapi_proto_enumTypes[5] + return &file_api_ateapi_v1_ateapi_proto_enumTypes[5] } func (x GoldenSnapshotMode) Number() protoreflect.EnumNumber { @@ -365,7 +365,7 @@ func (x GoldenSnapshotMode) Number() protoreflect.EnumNumber { // Deprecated: Use GoldenSnapshotMode.Descriptor instead. func (GoldenSnapshotMode) EnumDescriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{5} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{5} } // ActorMetadataField selects one identity field of the actor. @@ -405,11 +405,11 @@ func (x ActorMetadataField) String() string { } func (ActorMetadataField) Descriptor() protoreflect.EnumDescriptor { - return file_ateapi_proto_enumTypes[6].Descriptor() + return file_api_ateapi_v1_ateapi_proto_enumTypes[6].Descriptor() } func (ActorMetadataField) Type() protoreflect.EnumType { - return &file_ateapi_proto_enumTypes[6] + return &file_api_ateapi_v1_ateapi_proto_enumTypes[6] } func (x ActorMetadataField) Number() protoreflect.EnumNumber { @@ -418,7 +418,7 @@ func (x ActorMetadataField) Number() protoreflect.EnumNumber { // Deprecated: Use ActorMetadataField.Descriptor instead. func (ActorMetadataField) EnumDescriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{6} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{6} } // DurabilityMode selects when a suspend is acknowledged relative to its @@ -462,11 +462,11 @@ func (x DurabilityMode) String() string { } func (DurabilityMode) Descriptor() protoreflect.EnumDescriptor { - return file_ateapi_proto_enumTypes[7].Descriptor() + return file_api_ateapi_v1_ateapi_proto_enumTypes[7].Descriptor() } func (DurabilityMode) Type() protoreflect.EnumType { - return &file_ateapi_proto_enumTypes[7] + return &file_api_ateapi_v1_ateapi_proto_enumTypes[7] } func (x DurabilityMode) Number() protoreflect.EnumNumber { @@ -475,7 +475,7 @@ func (x DurabilityMode) Number() protoreflect.EnumNumber { // Deprecated: Use DurabilityMode.Descriptor instead. func (DurabilityMode) EnumDescriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{7} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{7} } type WorkerState int32 @@ -519,11 +519,11 @@ func (x WorkerState) String() string { } func (WorkerState) Descriptor() protoreflect.EnumDescriptor { - return file_ateapi_proto_enumTypes[8].Descriptor() + return file_api_ateapi_v1_ateapi_proto_enumTypes[8].Descriptor() } func (WorkerState) Type() protoreflect.EnumType { - return &file_ateapi_proto_enumTypes[8] + return &file_api_ateapi_v1_ateapi_proto_enumTypes[8] } func (x WorkerState) Number() protoreflect.EnumNumber { @@ -532,7 +532,7 @@ func (x WorkerState) Number() protoreflect.EnumNumber { // Deprecated: Use WorkerState.Descriptor instead. func (WorkerState) EnumDescriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{8} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{8} } // Scope is whether a top-level resource belongs to an atespace. @@ -572,11 +572,11 @@ func (x Scope) String() string { } func (Scope) Descriptor() protoreflect.EnumDescriptor { - return file_ateapi_proto_enumTypes[9].Descriptor() + return file_api_ateapi_v1_ateapi_proto_enumTypes[9].Descriptor() } func (Scope) Type() protoreflect.EnumType { - return &file_ateapi_proto_enumTypes[9] + return &file_api_ateapi_v1_ateapi_proto_enumTypes[9] } func (x Scope) Number() protoreflect.EnumNumber { @@ -585,7 +585,7 @@ func (x Scope) Number() protoreflect.EnumNumber { // Deprecated: Use Scope.Descriptor instead. func (Scope) EnumDescriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{9} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{9} } // ObjectSnapshot addresses a snapshot held in object storage. @@ -602,7 +602,7 @@ type ObjectSnapshot struct { func (x *ObjectSnapshot) Reset() { *x = ObjectSnapshot{} - mi := &file_ateapi_proto_msgTypes[0] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -614,7 +614,7 @@ func (x *ObjectSnapshot) String() string { func (*ObjectSnapshot) ProtoMessage() {} func (x *ObjectSnapshot) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[0] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -627,7 +627,7 @@ func (x *ObjectSnapshot) ProtoReflect() protoreflect.Message { // Deprecated: Use ObjectSnapshot.ProtoReflect.Descriptor instead. func (*ObjectSnapshot) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{0} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{0} } func (x *ObjectSnapshot) GetSnapshotUri() string { @@ -645,7 +645,7 @@ type SnapshotStorage struct { // +k8s:required // +k8s:minimum=1 // +k8s:maximum=2 # keep this in sync with the SnapshotStorageStatus enum - Status SnapshotStorageStatus `protobuf:"varint,1,opt,name=status,proto3,enum=ateapi.SnapshotStorageStatus" json:"status,omitempty"` + Status SnapshotStorageStatus `protobuf:"varint,1,opt,name=status,proto3,enum=substrate.ateapi.v1.SnapshotStorageStatus" json:"status,omitempty"` // object snapshot is stored in object storage. // // +k8s:required @@ -656,7 +656,7 @@ type SnapshotStorage struct { func (x *SnapshotStorage) Reset() { *x = SnapshotStorage{} - mi := &file_ateapi_proto_msgTypes[1] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -668,7 +668,7 @@ func (x *SnapshotStorage) String() string { func (*SnapshotStorage) ProtoMessage() {} func (x *SnapshotStorage) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[1] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -681,7 +681,7 @@ func (x *SnapshotStorage) ProtoReflect() protoreflect.Message { // Deprecated: Use SnapshotStorage.ProtoReflect.Descriptor instead. func (*SnapshotStorage) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{1} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{1} } func (x *SnapshotStorage) GetStatus() SnapshotStorageStatus { @@ -719,13 +719,13 @@ type Snapshot struct { // +k8s:required // +k8s:minimum=1 // +k8s:maximum=2 # keep this in sync with the SnapshotOwner enum - Owner SnapshotOwner `protobuf:"varint,3,opt,name=owner,proto3,enum=ateapi.SnapshotOwner" json:"owner,omitempty"` + Owner SnapshotOwner `protobuf:"varint,3,opt,name=owner,proto3,enum=substrate.ateapi.v1.SnapshotOwner" json:"owner,omitempty"` // fidelity is what this snapshot holds. // // +k8s:required // +k8s:minimum=1 // +k8s:maximum=3 # keep this in sync with the SnapshotFidelity enum - Fidelity SnapshotFidelity `protobuf:"varint,4,opt,name=fidelity,proto3,enum=ateapi.SnapshotFidelity" json:"fidelity,omitempty"` + Fidelity SnapshotFidelity `protobuf:"varint,4,opt,name=fidelity,proto3,enum=substrate.ateapi.v1.SnapshotFidelity" json:"fidelity,omitempty"` // UID of the ActorTemplate whose sandbox this snapshot's guest state was // captured from. // @@ -756,7 +756,7 @@ type Snapshot struct { func (x *Snapshot) Reset() { *x = Snapshot{} - mi := &file_ateapi_proto_msgTypes[2] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -768,7 +768,7 @@ func (x *Snapshot) String() string { func (*Snapshot) ProtoMessage() {} func (x *Snapshot) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[2] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -781,7 +781,7 @@ func (x *Snapshot) ProtoReflect() protoreflect.Message { // Deprecated: Use Snapshot.ProtoReflect.Descriptor instead. func (*Snapshot) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{2} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{2} } func (x *Snapshot) GetUuid() string { @@ -859,7 +859,7 @@ type Selector struct { func (x *Selector) Reset() { *x = Selector{} - mi := &file_ateapi_proto_msgTypes[3] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -871,7 +871,7 @@ func (x *Selector) String() string { func (*Selector) ProtoMessage() {} func (x *Selector) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[3] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -884,7 +884,7 @@ func (x *Selector) ProtoReflect() protoreflect.Message { // Deprecated: Use Selector.ProtoReflect.Descriptor instead. func (*Selector) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{3} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{3} } func (x *Selector) GetMatchLabels() map[string]string { @@ -963,7 +963,7 @@ type ResourceMetadata struct { func (x *ResourceMetadata) Reset() { *x = ResourceMetadata{} - mi := &file_ateapi_proto_msgTypes[4] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -975,7 +975,7 @@ func (x *ResourceMetadata) String() string { func (*ResourceMetadata) ProtoMessage() {} func (x *ResourceMetadata) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[4] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -988,7 +988,7 @@ func (x *ResourceMetadata) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceMetadata.ProtoReflect.Descriptor instead. func (*ResourceMetadata) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{4} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{4} } func (x *ResourceMetadata) GetAtespace() string { @@ -1058,7 +1058,7 @@ type ExternalVolumes struct { func (x *ExternalVolumes) Reset() { *x = ExternalVolumes{} - mi := &file_ateapi_proto_msgTypes[5] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1070,7 +1070,7 @@ func (x *ExternalVolumes) String() string { func (*ExternalVolumes) ProtoMessage() {} func (x *ExternalVolumes) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[5] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1083,7 +1083,7 @@ func (x *ExternalVolumes) ProtoReflect() protoreflect.Message { // Deprecated: Use ExternalVolumes.ProtoReflect.Descriptor instead. func (*ExternalVolumes) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{5} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{5} } func (x *ExternalVolumes) GetVolumes() []*ExternalVolumeStatus { @@ -1142,7 +1142,7 @@ type ExternalVolumeStatus struct { func (x *ExternalVolumeStatus) Reset() { *x = ExternalVolumeStatus{} - mi := &file_ateapi_proto_msgTypes[6] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1154,7 +1154,7 @@ func (x *ExternalVolumeStatus) String() string { func (*ExternalVolumeStatus) ProtoMessage() {} func (x *ExternalVolumeStatus) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[6] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1167,7 +1167,7 @@ func (x *ExternalVolumeStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use ExternalVolumeStatus.ProtoReflect.Descriptor instead. func (*ExternalVolumeStatus) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{6} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{6} } func (x *ExternalVolumeStatus) GetName() string { @@ -1237,7 +1237,7 @@ type Actor struct { func (x *Actor) Reset() { *x = Actor{} - mi := &file_ateapi_proto_msgTypes[7] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1249,7 +1249,7 @@ func (x *Actor) String() string { func (*Actor) ProtoMessage() {} func (x *Actor) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[7] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1262,7 +1262,7 @@ func (x *Actor) ProtoReflect() protoreflect.Message { // Deprecated: Use Actor.ProtoReflect.Descriptor instead. func (*Actor) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{7} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{7} } func (x *Actor) GetMetadata() *ResourceMetadata { @@ -1340,7 +1340,7 @@ type EgressPolicy struct { func (x *EgressPolicy) Reset() { *x = EgressPolicy{} - mi := &file_ateapi_proto_msgTypes[8] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1352,7 +1352,7 @@ func (x *EgressPolicy) String() string { func (*EgressPolicy) ProtoMessage() {} func (x *EgressPolicy) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[8] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1365,7 +1365,7 @@ func (x *EgressPolicy) ProtoReflect() protoreflect.Message { // Deprecated: Use EgressPolicy.ProtoReflect.Descriptor instead. func (*EgressPolicy) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{8} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{8} } func (x *EgressPolicy) GetMetadata() *ResourceMetadata { @@ -1402,7 +1402,7 @@ type EgressPolicyTemplate struct { func (x *EgressPolicyTemplate) Reset() { *x = EgressPolicyTemplate{} - mi := &file_ateapi_proto_msgTypes[9] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1414,7 +1414,7 @@ func (x *EgressPolicyTemplate) String() string { func (*EgressPolicyTemplate) ProtoMessage() {} func (x *EgressPolicyTemplate) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[9] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1427,7 +1427,7 @@ func (x *EgressPolicyTemplate) ProtoReflect() protoreflect.Message { // Deprecated: Use EgressPolicyTemplate.ProtoReflect.Descriptor instead. func (*EgressPolicyTemplate) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{9} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{9} } func (x *EgressPolicyTemplate) GetRules() []*EgressRule { @@ -1470,7 +1470,7 @@ type EgressRule struct { func (x *EgressRule) Reset() { *x = EgressRule{} - mi := &file_ateapi_proto_msgTypes[10] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1482,7 +1482,7 @@ func (x *EgressRule) String() string { func (*EgressRule) ProtoMessage() {} func (x *EgressRule) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[10] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1495,7 +1495,7 @@ func (x *EgressRule) ProtoReflect() protoreflect.Message { // Deprecated: Use EgressRule.ProtoReflect.Descriptor instead. func (*EgressRule) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{10} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{10} } func (x *EgressRule) GetHttp() *HttpRule { @@ -1563,7 +1563,7 @@ type HttpRule struct { func (x *HttpRule) Reset() { *x = HttpRule{} - mi := &file_ateapi_proto_msgTypes[11] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1575,7 +1575,7 @@ func (x *HttpRule) String() string { func (*HttpRule) ProtoMessage() {} func (x *HttpRule) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[11] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1588,7 +1588,7 @@ func (x *HttpRule) ProtoReflect() protoreflect.Message { // Deprecated: Use HttpRule.ProtoReflect.Descriptor instead. func (*HttpRule) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{11} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{11} } func (x *HttpRule) GetHostnames() []string { @@ -1648,7 +1648,7 @@ type HttpsRule struct { func (x *HttpsRule) Reset() { *x = HttpsRule{} - mi := &file_ateapi_proto_msgTypes[12] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1660,7 +1660,7 @@ func (x *HttpsRule) String() string { func (*HttpsRule) ProtoMessage() {} func (x *HttpsRule) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[12] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1673,7 +1673,7 @@ func (x *HttpsRule) ProtoReflect() protoreflect.Message { // Deprecated: Use HttpsRule.ProtoReflect.Descriptor instead. func (*HttpsRule) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{12} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{12} } func (x *HttpsRule) GetHostnames() []string { @@ -1724,7 +1724,7 @@ type TlsPassthroughRule struct { func (x *TlsPassthroughRule) Reset() { *x = TlsPassthroughRule{} - mi := &file_ateapi_proto_msgTypes[13] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1736,7 +1736,7 @@ func (x *TlsPassthroughRule) String() string { func (*TlsPassthroughRule) ProtoMessage() {} func (x *TlsPassthroughRule) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[13] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1749,7 +1749,7 @@ func (x *TlsPassthroughRule) ProtoReflect() protoreflect.Message { // Deprecated: Use TlsPassthroughRule.ProtoReflect.Descriptor instead. func (*TlsPassthroughRule) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{13} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{13} } func (x *TlsPassthroughRule) GetHostnames() []string { @@ -1790,7 +1790,7 @@ type Ports struct { func (x *Ports) Reset() { *x = Ports{} - mi := &file_ateapi_proto_msgTypes[14] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1802,7 +1802,7 @@ func (x *Ports) String() string { func (*Ports) ProtoMessage() {} func (x *Ports) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[14] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1815,7 +1815,7 @@ func (x *Ports) ProtoReflect() protoreflect.Message { // Deprecated: Use Ports.ProtoReflect.Descriptor instead. func (*Ports) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{14} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{14} } func (x *Ports) GetAll() *AllPorts { @@ -1841,7 +1841,7 @@ type AllPorts struct { func (x *AllPorts) Reset() { *x = AllPorts{} - mi := &file_ateapi_proto_msgTypes[15] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1853,7 +1853,7 @@ func (x *AllPorts) String() string { func (*AllPorts) ProtoMessage() {} func (x *AllPorts) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[15] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1866,7 +1866,7 @@ func (x *AllPorts) ProtoReflect() protoreflect.Message { // Deprecated: Use AllPorts.ProtoReflect.Descriptor instead. func (*AllPorts) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{15} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{15} } // HttpRuleEffects contains effects applied by a matching HTTP or HTTPS rule. @@ -1900,7 +1900,7 @@ type HttpRuleEffects struct { func (x *HttpRuleEffects) Reset() { *x = HttpRuleEffects{} - mi := &file_ateapi_proto_msgTypes[16] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1912,7 +1912,7 @@ func (x *HttpRuleEffects) String() string { func (*HttpRuleEffects) ProtoMessage() {} func (x *HttpRuleEffects) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[16] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1925,7 +1925,7 @@ func (x *HttpRuleEffects) ProtoReflect() protoreflect.Message { // Deprecated: Use HttpRuleEffects.ProtoReflect.Descriptor instead. func (*HttpRuleEffects) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{16} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{16} } func (x *HttpRuleEffects) GetReplaceHeaders() []*CredentialHeader { @@ -1975,7 +1975,7 @@ type CredentialHeader struct { func (x *CredentialHeader) Reset() { *x = CredentialHeader{} - mi := &file_ateapi_proto_msgTypes[17] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1987,7 +1987,7 @@ func (x *CredentialHeader) String() string { func (*CredentialHeader) ProtoMessage() {} func (x *CredentialHeader) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[17] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2000,7 +2000,7 @@ func (x *CredentialHeader) ProtoReflect() protoreflect.Message { // Deprecated: Use CredentialHeader.ProtoReflect.Descriptor instead. func (*CredentialHeader) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{17} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{17} } func (x *CredentialHeader) GetHeader() string { @@ -2057,7 +2057,7 @@ type ActorJwtSource struct { func (x *ActorJwtSource) Reset() { *x = ActorJwtSource{} - mi := &file_ateapi_proto_msgTypes[18] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2069,7 +2069,7 @@ func (x *ActorJwtSource) String() string { func (*ActorJwtSource) ProtoMessage() {} func (x *ActorJwtSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[18] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2082,7 +2082,7 @@ func (x *ActorJwtSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorJwtSource.ProtoReflect.Descriptor instead. func (*ActorJwtSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{18} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{18} } func (x *ActorJwtSource) GetAudiences() []string { @@ -2106,7 +2106,7 @@ type ActorStatus struct { // +k8s:required // +k8s:minimum=1 // +k8s:maximum=7 # keep this in sync with the ActorState enum - State ActorState `protobuf:"varint,1,opt,name=state,proto3,enum=ateapi.ActorState" json:"state,omitempty"` + State ActorState `protobuf:"varint,1,opt,name=state,proto3,enum=substrate.ateapi.v1.ActorState" json:"state,omitempty"` // worker_assignment points at the worker currently hosting this Actor. // Unset whenever the Actor has no worker (SUSPENDED, CRASHED). // @@ -2158,7 +2158,7 @@ type ActorStatus struct { func (x *ActorStatus) Reset() { *x = ActorStatus{} - mi := &file_ateapi_proto_msgTypes[19] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2170,7 +2170,7 @@ func (x *ActorStatus) String() string { func (*ActorStatus) ProtoMessage() {} func (x *ActorStatus) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[19] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2183,7 +2183,7 @@ func (x *ActorStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorStatus.ProtoReflect.Descriptor instead. func (*ActorStatus) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{19} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{19} } func (x *ActorStatus) GetState() ActorState { @@ -2253,7 +2253,7 @@ type ActorCrash struct { func (x *ActorCrash) Reset() { *x = ActorCrash{} - mi := &file_ateapi_proto_msgTypes[20] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2265,7 +2265,7 @@ func (x *ActorCrash) String() string { func (*ActorCrash) ProtoMessage() {} func (x *ActorCrash) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[20] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2278,7 +2278,7 @@ func (x *ActorCrash) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorCrash.ProtoReflect.Descriptor instead. func (*ActorCrash) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{20} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{20} } func (x *ActorCrash) GetMessage() string { @@ -2384,7 +2384,7 @@ type WorkerAssignment struct { func (x *WorkerAssignment) Reset() { *x = WorkerAssignment{} - mi := &file_ateapi_proto_msgTypes[21] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2396,7 +2396,7 @@ func (x *WorkerAssignment) String() string { func (*WorkerAssignment) ProtoMessage() {} func (x *WorkerAssignment) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[21] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2409,7 +2409,7 @@ func (x *WorkerAssignment) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerAssignment.ProtoReflect.Descriptor instead. func (*WorkerAssignment) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{21} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{21} } func (x *WorkerAssignment) GetWorker() *ObjectRef { @@ -2509,7 +2509,7 @@ type TagStatus struct { func (x *TagStatus) Reset() { *x = TagStatus{} - mi := &file_ateapi_proto_msgTypes[22] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2521,7 +2521,7 @@ func (x *TagStatus) String() string { func (*TagStatus) ProtoMessage() {} func (x *TagStatus) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[22] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2534,7 +2534,7 @@ func (x *TagStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use TagStatus.ProtoReflect.Descriptor instead. func (*TagStatus) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{22} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{22} } func (x *TagStatus) GetSnapshot() *Snapshot { @@ -2571,7 +2571,7 @@ type Tag struct { // +k8s:required // +k8s:minimum=1 // +k8s:maximum=2 # keep this in sync with the TagScope enum - Scope TagScope `protobuf:"varint,3,opt,name=scope,proto3,enum=ateapi.TagScope" json:"scope,omitempty"` + Scope TagScope `protobuf:"varint,3,opt,name=scope,proto3,enum=substrate.ateapi.v1.TagScope" json:"scope,omitempty"` // source_actor is the suspended Actor whose external snapshot this tag // captures. The tag lives in this Actor's Atespace. Set once at creation and // immutable afterward. @@ -2586,7 +2586,7 @@ type Tag struct { func (x *Tag) Reset() { *x = Tag{} - mi := &file_ateapi_proto_msgTypes[23] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2598,7 +2598,7 @@ func (x *Tag) String() string { func (*Tag) ProtoMessage() {} func (x *Tag) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[23] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2611,7 +2611,7 @@ func (x *Tag) ProtoReflect() protoreflect.Message { // Deprecated: Use Tag.ProtoReflect.Descriptor instead. func (*Tag) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{23} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{23} } func (x *Tag) GetMetadata() *ResourceMetadata { @@ -2657,7 +2657,7 @@ type Atespace struct { func (x *Atespace) Reset() { *x = Atespace{} - mi := &file_ateapi_proto_msgTypes[24] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2669,7 +2669,7 @@ func (x *Atespace) String() string { func (*Atespace) ProtoMessage() {} func (x *Atespace) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[24] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2682,7 +2682,7 @@ func (x *Atespace) ProtoReflect() protoreflect.Message { // Deprecated: Use Atespace.ProtoReflect.Descriptor instead. func (*Atespace) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{24} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{24} } func (x *Atespace) GetMetadata() *ResourceMetadata { @@ -2715,7 +2715,7 @@ type ObjectRef struct { func (x *ObjectRef) Reset() { *x = ObjectRef{} - mi := &file_ateapi_proto_msgTypes[25] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2727,7 +2727,7 @@ func (x *ObjectRef) String() string { func (*ObjectRef) ProtoMessage() {} func (x *ObjectRef) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[25] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2740,7 +2740,7 @@ func (x *ObjectRef) ProtoReflect() protoreflect.Message { // Deprecated: Use ObjectRef.ProtoReflect.Descriptor instead. func (*ObjectRef) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{25} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{25} } func (x *ObjectRef) GetAtespace() string { @@ -2816,7 +2816,7 @@ type ActorTemplate struct { func (x *ActorTemplate) Reset() { *x = ActorTemplate{} - mi := &file_ateapi_proto_msgTypes[26] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2828,7 +2828,7 @@ func (x *ActorTemplate) String() string { func (*ActorTemplate) ProtoMessage() {} func (x *ActorTemplate) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[26] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2841,7 +2841,7 @@ func (x *ActorTemplate) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorTemplate.ProtoReflect.Descriptor instead. func (*ActorTemplate) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{26} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{26} } func (x *ActorTemplate) GetMetadata() *ResourceMetadata { @@ -2913,7 +2913,7 @@ type ResourceRequirements struct { func (x *ResourceRequirements) Reset() { *x = ResourceRequirements{} - mi := &file_ateapi_proto_msgTypes[27] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2925,7 +2925,7 @@ func (x *ResourceRequirements) String() string { func (*ResourceRequirements) ProtoMessage() {} func (x *ResourceRequirements) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[27] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2938,7 +2938,7 @@ func (x *ResourceRequirements) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceRequirements.ProtoReflect.Descriptor instead. func (*ResourceRequirements) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{27} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{27} } func (x *ResourceRequirements) GetLimits() *Resources { @@ -2968,7 +2968,7 @@ type Resources struct { func (x *Resources) Reset() { *x = Resources{} - mi := &file_ateapi_proto_msgTypes[28] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2980,7 +2980,7 @@ func (x *Resources) String() string { func (*Resources) ProtoMessage() {} func (x *Resources) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[28] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2993,7 +2993,7 @@ func (x *Resources) ProtoReflect() protoreflect.Message { // Deprecated: Use Resources.ProtoReflect.Descriptor instead. func (*Resources) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{28} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{28} } func (x *Resources) GetCpuMillicores() int64 { @@ -3034,7 +3034,7 @@ type GoldenSnapshotStatus struct { func (x *GoldenSnapshotStatus) Reset() { *x = GoldenSnapshotStatus{} - mi := &file_ateapi_proto_msgTypes[29] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3046,7 +3046,7 @@ func (x *GoldenSnapshotStatus) String() string { func (*GoldenSnapshotStatus) ProtoMessage() {} func (x *GoldenSnapshotStatus) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[29] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3059,7 +3059,7 @@ func (x *GoldenSnapshotStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use GoldenSnapshotStatus.ProtoReflect.Descriptor instead. func (*GoldenSnapshotStatus) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{29} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{29} } func (x *GoldenSnapshotStatus) GetGoldenTag() *ObjectRef { @@ -3093,7 +3093,7 @@ type ActorTemplateStatus struct { func (x *ActorTemplateStatus) Reset() { *x = ActorTemplateStatus{} - mi := &file_ateapi_proto_msgTypes[30] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3105,7 +3105,7 @@ func (x *ActorTemplateStatus) String() string { func (*ActorTemplateStatus) ProtoMessage() {} func (x *ActorTemplateStatus) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[30] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3118,7 +3118,7 @@ func (x *ActorTemplateStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorTemplateStatus.ProtoReflect.Descriptor instead. func (*ActorTemplateStatus) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{30} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{30} } func (x *ActorTemplateStatus) GetGoldenSnapshotStatus() *GoldenSnapshotStatus { @@ -3153,7 +3153,7 @@ type SnapshotConfig struct { // +k8s:required // +k8s:minimum=1 // +k8s:maximum=3 # keep this in sync with the SnapshotFidelity enum - PreferredFidelity SnapshotFidelity `protobuf:"varint,2,opt,name=preferred_fidelity,json=preferredFidelity,proto3,enum=ateapi.SnapshotFidelity" json:"preferred_fidelity,omitempty"` + PreferredFidelity SnapshotFidelity `protobuf:"varint,2,opt,name=preferred_fidelity,json=preferredFidelity,proto3,enum=substrate.ateapi.v1.SnapshotFidelity" json:"preferred_fidelity,omitempty"` // golden_snapshot_config configures automated golden snapshot creation. // Golden snapshots are enabled when this config is omitted. // @@ -3165,7 +3165,7 @@ type SnapshotConfig struct { func (x *SnapshotConfig) Reset() { *x = SnapshotConfig{} - mi := &file_ateapi_proto_msgTypes[31] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3177,7 +3177,7 @@ func (x *SnapshotConfig) String() string { func (*SnapshotConfig) ProtoMessage() {} func (x *SnapshotConfig) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[31] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3190,7 +3190,7 @@ func (x *SnapshotConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use SnapshotConfig.ProtoReflect.Descriptor instead. func (*SnapshotConfig) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{31} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{31} } func (x *SnapshotConfig) GetStorageLocation() string { @@ -3223,14 +3223,14 @@ type GoldenSnapshotConfig struct { // +k8s:required // +k8s:minimum=1 // +k8s:maximum=2 # keep this in sync with the GoldenSnapshotMode enum - Mode GoldenSnapshotMode `protobuf:"varint,1,opt,name=mode,proto3,enum=ateapi.GoldenSnapshotMode" json:"mode,omitempty"` + Mode GoldenSnapshotMode `protobuf:"varint,1,opt,name=mode,proto3,enum=substrate.ateapi.v1.GoldenSnapshotMode" json:"mode,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *GoldenSnapshotConfig) Reset() { *x = GoldenSnapshotConfig{} - mi := &file_ateapi_proto_msgTypes[32] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3242,7 +3242,7 @@ func (x *GoldenSnapshotConfig) String() string { func (*GoldenSnapshotConfig) ProtoMessage() {} func (x *GoldenSnapshotConfig) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[32] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3255,7 +3255,7 @@ func (x *GoldenSnapshotConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use GoldenSnapshotConfig.ProtoReflect.Descriptor instead. func (*GoldenSnapshotConfig) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{32} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{32} } func (x *GoldenSnapshotConfig) GetMode() GoldenSnapshotMode { @@ -3335,7 +3335,7 @@ type Container struct { func (x *Container) Reset() { *x = Container{} - mi := &file_ateapi_proto_msgTypes[33] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3347,7 +3347,7 @@ func (x *Container) String() string { func (*Container) ProtoMessage() {} func (x *Container) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[33] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3360,7 +3360,7 @@ func (x *Container) ProtoReflect() protoreflect.Message { // Deprecated: Use Container.ProtoReflect.Descriptor instead. func (*Container) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{33} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{33} } func (x *Container) GetName() string { @@ -3440,7 +3440,7 @@ type SecurityContext struct { func (x *SecurityContext) Reset() { *x = SecurityContext{} - mi := &file_ateapi_proto_msgTypes[34] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3452,7 +3452,7 @@ func (x *SecurityContext) String() string { func (*SecurityContext) ProtoMessage() {} func (x *SecurityContext) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[34] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3465,7 +3465,7 @@ func (x *SecurityContext) ProtoReflect() protoreflect.Message { // Deprecated: Use SecurityContext.ProtoReflect.Descriptor instead. func (*SecurityContext) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{34} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{34} } func (x *SecurityContext) GetCapabilities() *Capabilities { @@ -3503,7 +3503,7 @@ type Capabilities struct { func (x *Capabilities) Reset() { *x = Capabilities{} - mi := &file_ateapi_proto_msgTypes[35] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3515,7 +3515,7 @@ func (x *Capabilities) String() string { func (*Capabilities) ProtoMessage() {} func (x *Capabilities) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[35] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3528,7 +3528,7 @@ func (x *Capabilities) ProtoReflect() protoreflect.Message { // Deprecated: Use Capabilities.ProtoReflect.Descriptor instead. func (*Capabilities) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{35} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{35} } func (x *Capabilities) GetAdd() []string { @@ -3566,7 +3566,7 @@ type EnvVar struct { func (x *EnvVar) Reset() { *x = EnvVar{} - mi := &file_ateapi_proto_msgTypes[36] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3578,7 +3578,7 @@ func (x *EnvVar) String() string { func (*EnvVar) ProtoMessage() {} func (x *EnvVar) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[36] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3591,7 +3591,7 @@ func (x *EnvVar) ProtoReflect() protoreflect.Message { // Deprecated: Use EnvVar.ProtoReflect.Descriptor instead. func (*EnvVar) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{36} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{36} } func (x *EnvVar) GetName() string { @@ -3631,7 +3631,7 @@ type WakeupProbe struct { func (x *WakeupProbe) Reset() { *x = WakeupProbe{} - mi := &file_ateapi_proto_msgTypes[37] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3643,7 +3643,7 @@ func (x *WakeupProbe) String() string { func (*WakeupProbe) ProtoMessage() {} func (x *WakeupProbe) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[37] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3656,7 +3656,7 @@ func (x *WakeupProbe) ProtoReflect() protoreflect.Message { // Deprecated: Use WakeupProbe.ProtoReflect.Descriptor instead. func (*WakeupProbe) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{37} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{37} } func (x *WakeupProbe) GetHttpGet() *HttpGetAction { @@ -3696,7 +3696,7 @@ type HttpGetAction struct { func (x *HttpGetAction) Reset() { *x = HttpGetAction{} - mi := &file_ateapi_proto_msgTypes[38] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3708,7 +3708,7 @@ func (x *HttpGetAction) String() string { func (*HttpGetAction) ProtoMessage() {} func (x *HttpGetAction) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[38] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3721,7 +3721,7 @@ func (x *HttpGetAction) ProtoReflect() protoreflect.Message { // Deprecated: Use HttpGetAction.ProtoReflect.Descriptor instead. func (*HttpGetAction) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{38} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{38} } func (x *HttpGetAction) GetPath() string { @@ -3772,7 +3772,7 @@ type Volume struct { func (x *Volume) Reset() { *x = Volume{} - mi := &file_ateapi_proto_msgTypes[39] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3784,7 +3784,7 @@ func (x *Volume) String() string { func (*Volume) ProtoMessage() {} func (x *Volume) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[39] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3797,7 +3797,7 @@ func (x *Volume) ProtoReflect() protoreflect.Message { // Deprecated: Use Volume.ProtoReflect.Descriptor instead. func (*Volume) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{39} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{39} } func (x *Volume) GetName() string { @@ -3850,7 +3850,7 @@ type ExternalVolumeSource struct { func (x *ExternalVolumeSource) Reset() { *x = ExternalVolumeSource{} - mi := &file_ateapi_proto_msgTypes[40] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3862,7 +3862,7 @@ func (x *ExternalVolumeSource) String() string { func (*ExternalVolumeSource) ProtoMessage() {} func (x *ExternalVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[40] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3875,7 +3875,7 @@ func (x *ExternalVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ExternalVolumeSource.ProtoReflect.Descriptor instead. func (*ExternalVolumeSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{40} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{40} } func (x *ExternalVolumeSource) GetTemplate() *ExternalVolumeTemplate { @@ -3903,7 +3903,7 @@ type ImageVolumeSource struct { func (x *ImageVolumeSource) Reset() { *x = ImageVolumeSource{} - mi := &file_ateapi_proto_msgTypes[41] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3915,7 +3915,7 @@ func (x *ImageVolumeSource) String() string { func (*ImageVolumeSource) ProtoMessage() {} func (x *ImageVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[41] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3928,7 +3928,7 @@ func (x *ImageVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageVolumeSource.ProtoReflect.Descriptor instead. func (*ImageVolumeSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{41} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{41} } func (x *ImageVolumeSource) GetReference() string { @@ -3948,7 +3948,7 @@ type DurableDirVolumeSource struct { func (x *DurableDirVolumeSource) Reset() { *x = DurableDirVolumeSource{} - mi := &file_ateapi_proto_msgTypes[42] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3960,7 +3960,7 @@ func (x *DurableDirVolumeSource) String() string { func (*DurableDirVolumeSource) ProtoMessage() {} func (x *DurableDirVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[42] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3973,7 +3973,7 @@ func (x *DurableDirVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use DurableDirVolumeSource.ProtoReflect.Descriptor instead. func (*DurableDirVolumeSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{42} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{42} } // ExternalVolumeTemplate provisions an external volume per actor; the volume @@ -3997,7 +3997,7 @@ type ExternalVolumeTemplate struct { func (x *ExternalVolumeTemplate) Reset() { *x = ExternalVolumeTemplate{} - mi := &file_ateapi_proto_msgTypes[43] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4009,7 +4009,7 @@ func (x *ExternalVolumeTemplate) String() string { func (*ExternalVolumeTemplate) ProtoMessage() {} func (x *ExternalVolumeTemplate) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[43] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4022,7 +4022,7 @@ func (x *ExternalVolumeTemplate) ProtoReflect() protoreflect.Message { // Deprecated: Use ExternalVolumeTemplate.ProtoReflect.Descriptor instead. func (*ExternalVolumeTemplate) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{43} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{43} } func (x *ExternalVolumeTemplate) GetCapacityBytes() int64 { @@ -4059,7 +4059,7 @@ type SystemInfoVolumeSource struct { func (x *SystemInfoVolumeSource) Reset() { *x = SystemInfoVolumeSource{} - mi := &file_ateapi_proto_msgTypes[44] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4071,7 +4071,7 @@ func (x *SystemInfoVolumeSource) String() string { func (*SystemInfoVolumeSource) ProtoMessage() {} func (x *SystemInfoVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[44] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4084,7 +4084,7 @@ func (x *SystemInfoVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use SystemInfoVolumeSource.ProtoReflect.Descriptor instead. func (*SystemInfoVolumeSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{44} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{44} } func (x *SystemInfoVolumeSource) GetDataSources() []*SystemInfoDataSource { @@ -4110,7 +4110,7 @@ type SystemInfoDataSource struct { func (x *SystemInfoDataSource) Reset() { *x = SystemInfoDataSource{} - mi := &file_ateapi_proto_msgTypes[45] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4122,7 +4122,7 @@ func (x *SystemInfoDataSource) String() string { func (*SystemInfoDataSource) ProtoMessage() {} func (x *SystemInfoDataSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[45] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4135,7 +4135,7 @@ func (x *SystemInfoDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use SystemInfoDataSource.ProtoReflect.Descriptor instead. func (*SystemInfoDataSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{45} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{45} } func (x *SystemInfoDataSource) GetActorMetadata() *ActorMetadataDataSource { @@ -4172,7 +4172,7 @@ type ActorMetadataDataSource struct { func (x *ActorMetadataDataSource) Reset() { *x = ActorMetadataDataSource{} - mi := &file_ateapi_proto_msgTypes[46] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4184,7 +4184,7 @@ func (x *ActorMetadataDataSource) String() string { func (*ActorMetadataDataSource) ProtoMessage() {} func (x *ActorMetadataDataSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[46] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4197,7 +4197,7 @@ func (x *ActorMetadataDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorMetadataDataSource.ProtoReflect.Descriptor instead. func (*ActorMetadataDataSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{46} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{46} } func (x *ActorMetadataDataSource) GetItems() []*ActorMetadataItem { @@ -4214,7 +4214,7 @@ type ActorMetadataItem struct { // +k8s:required // +k8s:minimum=1 // +k8s:maximum=3 # keep this in sync with the ActorMetadataField enum - Field ActorMetadataField `protobuf:"varint,1,opt,name=field,proto3,enum=ateapi.ActorMetadataField" json:"field,omitempty"` + Field ActorMetadataField `protobuf:"varint,1,opt,name=field,proto3,enum=substrate.ateapi.v1.ActorMetadataField" json:"field,omitempty"` // path must be a clean relative Unix path: at most 16 '/'-separated // segments, none of them empty, '.' or '..', and no NUL byte. // @@ -4229,7 +4229,7 @@ type ActorMetadataItem struct { func (x *ActorMetadataItem) Reset() { *x = ActorMetadataItem{} - mi := &file_ateapi_proto_msgTypes[47] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4241,7 +4241,7 @@ func (x *ActorMetadataItem) String() string { func (*ActorMetadataItem) ProtoMessage() {} func (x *ActorMetadataItem) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[47] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4254,7 +4254,7 @@ func (x *ActorMetadataItem) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorMetadataItem.ProtoReflect.Descriptor instead. func (*ActorMetadataItem) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{47} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{47} } func (x *ActorMetadataItem) GetField() ActorMetadataField { @@ -4306,7 +4306,7 @@ type TrustBundleDataSource struct { func (x *TrustBundleDataSource) Reset() { *x = TrustBundleDataSource{} - mi := &file_ateapi_proto_msgTypes[48] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4318,7 +4318,7 @@ func (x *TrustBundleDataSource) String() string { func (*TrustBundleDataSource) ProtoMessage() {} func (x *TrustBundleDataSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[48] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4331,7 +4331,7 @@ func (x *TrustBundleDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use TrustBundleDataSource.ProtoReflect.Descriptor instead. func (*TrustBundleDataSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{48} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{48} } func (x *TrustBundleDataSource) GetNames() []string { @@ -4370,7 +4370,7 @@ type VolumeMount struct { func (x *VolumeMount) Reset() { *x = VolumeMount{} - mi := &file_ateapi_proto_msgTypes[49] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4382,7 +4382,7 @@ func (x *VolumeMount) String() string { func (*VolumeMount) ProtoMessage() {} func (x *VolumeMount) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[49] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4395,7 +4395,7 @@ func (x *VolumeMount) ProtoReflect() protoreflect.Message { // Deprecated: Use VolumeMount.ProtoReflect.Descriptor instead. func (*VolumeMount) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{49} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{49} } func (x *VolumeMount) GetName() string { @@ -4424,7 +4424,7 @@ type CreateAtespaceRequest struct { func (x *CreateAtespaceRequest) Reset() { *x = CreateAtespaceRequest{} - mi := &file_ateapi_proto_msgTypes[50] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4436,7 +4436,7 @@ func (x *CreateAtespaceRequest) String() string { func (*CreateAtespaceRequest) ProtoMessage() {} func (x *CreateAtespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[50] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4449,7 +4449,7 @@ func (x *CreateAtespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateAtespaceRequest.ProtoReflect.Descriptor instead. func (*CreateAtespaceRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{50} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{50} } func (x *CreateAtespaceRequest) GetAtespace() *Atespace { @@ -4470,7 +4470,7 @@ type GetAtespaceRequest struct { func (x *GetAtespaceRequest) Reset() { *x = GetAtespaceRequest{} - mi := &file_ateapi_proto_msgTypes[51] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4482,7 +4482,7 @@ func (x *GetAtespaceRequest) String() string { func (*GetAtespaceRequest) ProtoMessage() {} func (x *GetAtespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[51] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4495,7 +4495,7 @@ func (x *GetAtespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAtespaceRequest.ProtoReflect.Descriptor instead. func (*GetAtespaceRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{51} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{51} } func (x *GetAtespaceRequest) GetAtespace() *ObjectRef { @@ -4517,7 +4517,7 @@ type ListAtespacesRequest struct { func (x *ListAtespacesRequest) Reset() { *x = ListAtespacesRequest{} - mi := &file_ateapi_proto_msgTypes[52] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4529,7 +4529,7 @@ func (x *ListAtespacesRequest) String() string { func (*ListAtespacesRequest) ProtoMessage() {} func (x *ListAtespacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[52] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4542,7 +4542,7 @@ func (x *ListAtespacesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAtespacesRequest.ProtoReflect.Descriptor instead. func (*ListAtespacesRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{52} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{52} } func (x *ListAtespacesRequest) GetOptions() *ListOptions { @@ -4564,7 +4564,7 @@ type ListAtespacesResponse struct { func (x *ListAtespacesResponse) Reset() { *x = ListAtespacesResponse{} - mi := &file_ateapi_proto_msgTypes[53] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4576,7 +4576,7 @@ func (x *ListAtespacesResponse) String() string { func (*ListAtespacesResponse) ProtoMessage() {} func (x *ListAtespacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[53] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4589,7 +4589,7 @@ func (x *ListAtespacesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAtespacesResponse.ProtoReflect.Descriptor instead. func (*ListAtespacesResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{53} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{53} } func (x *ListAtespacesResponse) GetAtespaces() []*Atespace { @@ -4621,7 +4621,7 @@ type DeleteAtespaceRequest struct { func (x *DeleteAtespaceRequest) Reset() { *x = DeleteAtespaceRequest{} - mi := &file_ateapi_proto_msgTypes[54] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4633,7 +4633,7 @@ func (x *DeleteAtespaceRequest) String() string { func (*DeleteAtespaceRequest) ProtoMessage() {} func (x *DeleteAtespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[54] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4646,7 +4646,7 @@ func (x *DeleteAtespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteAtespaceRequest.ProtoReflect.Descriptor instead. func (*DeleteAtespaceRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{54} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{54} } func (x *DeleteAtespaceRequest) GetAtespace() *ObjectRef { @@ -4677,7 +4677,7 @@ type CreateActorTemplateRequest struct { func (x *CreateActorTemplateRequest) Reset() { *x = CreateActorTemplateRequest{} - mi := &file_ateapi_proto_msgTypes[55] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4689,7 +4689,7 @@ func (x *CreateActorTemplateRequest) String() string { func (*CreateActorTemplateRequest) ProtoMessage() {} func (x *CreateActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[55] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4702,7 +4702,7 @@ func (x *CreateActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorTemplateRequest.ProtoReflect.Descriptor instead. func (*CreateActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{55} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{55} } func (x *CreateActorTemplateRequest) GetActorTemplate() *ActorTemplate { @@ -4723,7 +4723,7 @@ type GetActorTemplateRequest struct { func (x *GetActorTemplateRequest) Reset() { *x = GetActorTemplateRequest{} - mi := &file_ateapi_proto_msgTypes[56] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4735,7 +4735,7 @@ func (x *GetActorTemplateRequest) String() string { func (*GetActorTemplateRequest) ProtoMessage() {} func (x *GetActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[56] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4748,7 +4748,7 @@ func (x *GetActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorTemplateRequest.ProtoReflect.Descriptor instead. func (*GetActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{56} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{56} } func (x *GetActorTemplateRequest) GetActorTemplate() *ObjectRef { @@ -4776,7 +4776,7 @@ type ListActorTemplatesRequest struct { func (x *ListActorTemplatesRequest) Reset() { *x = ListActorTemplatesRequest{} - mi := &file_ateapi_proto_msgTypes[57] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4788,7 +4788,7 @@ func (x *ListActorTemplatesRequest) String() string { func (*ListActorTemplatesRequest) ProtoMessage() {} func (x *ListActorTemplatesRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[57] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4801,7 +4801,7 @@ func (x *ListActorTemplatesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorTemplatesRequest.ProtoReflect.Descriptor instead. func (*ListActorTemplatesRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{57} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{57} } func (x *ListActorTemplatesRequest) GetAtespace() string { @@ -4831,7 +4831,7 @@ type ListActorTemplatesResponse struct { func (x *ListActorTemplatesResponse) Reset() { *x = ListActorTemplatesResponse{} - mi := &file_ateapi_proto_msgTypes[58] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4843,7 +4843,7 @@ func (x *ListActorTemplatesResponse) String() string { func (*ListActorTemplatesResponse) ProtoMessage() {} func (x *ListActorTemplatesResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[58] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4856,7 +4856,7 @@ func (x *ListActorTemplatesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorTemplatesResponse.ProtoReflect.Descriptor instead. func (*ListActorTemplatesResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{58} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{58} } func (x *ListActorTemplatesResponse) GetActorTemplates() []*ActorTemplate { @@ -4888,7 +4888,7 @@ type DeleteActorTemplateRequest struct { func (x *DeleteActorTemplateRequest) Reset() { *x = DeleteActorTemplateRequest{} - mi := &file_ateapi_proto_msgTypes[59] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4900,7 +4900,7 @@ func (x *DeleteActorTemplateRequest) String() string { func (*DeleteActorTemplateRequest) ProtoMessage() {} func (x *DeleteActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[59] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4913,7 +4913,7 @@ func (x *DeleteActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorTemplateRequest.ProtoReflect.Descriptor instead. func (*DeleteActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{59} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{59} } func (x *DeleteActorTemplateRequest) GetActorTemplate() *ObjectRef { @@ -4941,7 +4941,7 @@ type GetActorRequest struct { func (x *GetActorRequest) Reset() { *x = GetActorRequest{} - mi := &file_ateapi_proto_msgTypes[60] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4953,7 +4953,7 @@ func (x *GetActorRequest) String() string { func (*GetActorRequest) ProtoMessage() {} func (x *GetActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[60] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4966,7 +4966,7 @@ func (x *GetActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorRequest.ProtoReflect.Descriptor instead. func (*GetActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{60} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{60} } func (x *GetActorRequest) GetActor() *ObjectRef { @@ -4989,7 +4989,7 @@ type CreateActorRequest struct { func (x *CreateActorRequest) Reset() { *x = CreateActorRequest{} - mi := &file_ateapi_proto_msgTypes[61] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5001,7 +5001,7 @@ func (x *CreateActorRequest) String() string { func (*CreateActorRequest) ProtoMessage() {} func (x *CreateActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[61] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5014,7 +5014,7 @@ func (x *CreateActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorRequest.ProtoReflect.Descriptor instead. func (*CreateActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{61} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{61} } func (x *CreateActorRequest) GetActor() *Actor { @@ -5045,7 +5045,7 @@ type UpdateActorRequest struct { func (x *UpdateActorRequest) Reset() { *x = UpdateActorRequest{} - mi := &file_ateapi_proto_msgTypes[62] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5057,7 +5057,7 @@ func (x *UpdateActorRequest) String() string { func (*UpdateActorRequest) ProtoMessage() {} func (x *UpdateActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[62] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5070,7 +5070,7 @@ func (x *UpdateActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateActorRequest.ProtoReflect.Descriptor instead. func (*UpdateActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{62} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{62} } func (x *UpdateActorRequest) GetActor() *Actor { @@ -5095,7 +5095,7 @@ type SuspendActorRequest struct { func (x *SuspendActorRequest) Reset() { *x = SuspendActorRequest{} - mi := &file_ateapi_proto_msgTypes[63] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5107,7 +5107,7 @@ func (x *SuspendActorRequest) String() string { func (*SuspendActorRequest) ProtoMessage() {} func (x *SuspendActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[63] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5120,7 +5120,7 @@ func (x *SuspendActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SuspendActorRequest.ProtoReflect.Descriptor instead. func (*SuspendActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{63} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{63} } func (x *SuspendActorRequest) GetActor() *ObjectRef { @@ -5146,7 +5146,7 @@ type SuspendActorResponse struct { func (x *SuspendActorResponse) Reset() { *x = SuspendActorResponse{} - mi := &file_ateapi_proto_msgTypes[64] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5158,7 +5158,7 @@ func (x *SuspendActorResponse) String() string { func (*SuspendActorResponse) ProtoMessage() {} func (x *SuspendActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[64] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5171,7 +5171,7 @@ func (x *SuspendActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SuspendActorResponse.ProtoReflect.Descriptor instead. func (*SuspendActorResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{64} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{64} } func (x *SuspendActorResponse) GetActor() *Actor { @@ -5190,14 +5190,14 @@ type SuspendOptions struct { // +k8s:optional // +k8s:minimum=1 // +k8s:maximum=2 # keep this in sync with the DurabilityMode enum - Mode DurabilityMode `protobuf:"varint,1,opt,name=mode,proto3,enum=ateapi.DurabilityMode" json:"mode,omitempty"` + Mode DurabilityMode `protobuf:"varint,1,opt,name=mode,proto3,enum=substrate.ateapi.v1.DurabilityMode" json:"mode,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *SuspendOptions) Reset() { *x = SuspendOptions{} - mi := &file_ateapi_proto_msgTypes[65] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5209,7 +5209,7 @@ func (x *SuspendOptions) String() string { func (*SuspendOptions) ProtoMessage() {} func (x *SuspendOptions) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[65] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5222,7 +5222,7 @@ func (x *SuspendOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use SuspendOptions.ProtoReflect.Descriptor instead. func (*SuspendOptions) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{65} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{65} } func (x *SuspendOptions) GetMode() DurabilityMode { @@ -5243,7 +5243,7 @@ type ResumeActorRequest struct { func (x *ResumeActorRequest) Reset() { *x = ResumeActorRequest{} - mi := &file_ateapi_proto_msgTypes[66] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5255,7 +5255,7 @@ func (x *ResumeActorRequest) String() string { func (*ResumeActorRequest) ProtoMessage() {} func (x *ResumeActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[66] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5268,7 +5268,7 @@ func (x *ResumeActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResumeActorRequest.ProtoReflect.Descriptor instead. func (*ResumeActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{66} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{66} } func (x *ResumeActorRequest) GetActor() *ObjectRef { @@ -5290,7 +5290,7 @@ type ResumeActorResponse struct { func (x *ResumeActorResponse) Reset() { *x = ResumeActorResponse{} - mi := &file_ateapi_proto_msgTypes[67] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5302,7 +5302,7 @@ func (x *ResumeActorResponse) String() string { func (*ResumeActorResponse) ProtoMessage() {} func (x *ResumeActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[67] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5315,7 +5315,7 @@ func (x *ResumeActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResumeActorResponse.ProtoReflect.Descriptor instead. func (*ResumeActorResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{67} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{67} } func (x *ResumeActorResponse) GetActor() *Actor { @@ -5345,7 +5345,7 @@ type RevertActorRequest struct { func (x *RevertActorRequest) Reset() { *x = RevertActorRequest{} - mi := &file_ateapi_proto_msgTypes[68] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5357,7 +5357,7 @@ func (x *RevertActorRequest) String() string { func (*RevertActorRequest) ProtoMessage() {} func (x *RevertActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[68] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5370,7 +5370,7 @@ func (x *RevertActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RevertActorRequest.ProtoReflect.Descriptor instead. func (*RevertActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{68} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{68} } func (x *RevertActorRequest) GetActor() *ObjectRef { @@ -5392,7 +5392,7 @@ type RevertActorResponse struct { func (x *RevertActorResponse) Reset() { *x = RevertActorResponse{} - mi := &file_ateapi_proto_msgTypes[69] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5404,7 +5404,7 @@ func (x *RevertActorResponse) String() string { func (*RevertActorResponse) ProtoMessage() {} func (x *RevertActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[69] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5417,7 +5417,7 @@ func (x *RevertActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RevertActorResponse.ProtoReflect.Descriptor instead. func (*RevertActorResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{69} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{69} } func (x *RevertActorResponse) GetActor() *Actor { @@ -5442,7 +5442,7 @@ type DeleteActorRequest struct { func (x *DeleteActorRequest) Reset() { *x = DeleteActorRequest{} - mi := &file_ateapi_proto_msgTypes[70] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5454,7 +5454,7 @@ func (x *DeleteActorRequest) String() string { func (*DeleteActorRequest) ProtoMessage() {} func (x *DeleteActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[70] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5467,7 +5467,7 @@ func (x *DeleteActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorRequest.ProtoReflect.Descriptor instead. func (*DeleteActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{70} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{70} } func (x *DeleteActorRequest) GetActor() *ObjectRef { @@ -5504,7 +5504,7 @@ type GetActorEgressPolicyRequest struct { func (x *GetActorEgressPolicyRequest) Reset() { *x = GetActorEgressPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[71] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5516,7 +5516,7 @@ func (x *GetActorEgressPolicyRequest) String() string { func (*GetActorEgressPolicyRequest) ProtoMessage() {} func (x *GetActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[71] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5529,7 +5529,7 @@ func (x *GetActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*GetActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{71} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{71} } func (x *GetActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5567,7 +5567,7 @@ type CreateActorEgressPolicyRequest struct { func (x *CreateActorEgressPolicyRequest) Reset() { *x = CreateActorEgressPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[72] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5579,7 +5579,7 @@ func (x *CreateActorEgressPolicyRequest) String() string { func (*CreateActorEgressPolicyRequest) ProtoMessage() {} func (x *CreateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[72] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5592,7 +5592,7 @@ func (x *CreateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{72} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{72} } func (x *CreateActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5630,7 +5630,7 @@ type UpdateActorEgressPolicyRequest struct { func (x *UpdateActorEgressPolicyRequest) Reset() { *x = UpdateActorEgressPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[73] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5642,7 +5642,7 @@ func (x *UpdateActorEgressPolicyRequest) String() string { func (*UpdateActorEgressPolicyRequest) ProtoMessage() {} func (x *UpdateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[73] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5655,7 +5655,7 @@ func (x *UpdateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{73} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{73} } func (x *UpdateActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5696,7 +5696,7 @@ type DeleteActorEgressPolicyRequest struct { func (x *DeleteActorEgressPolicyRequest) Reset() { *x = DeleteActorEgressPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[74] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5708,7 +5708,7 @@ func (x *DeleteActorEgressPolicyRequest) String() string { func (*DeleteActorEgressPolicyRequest) ProtoMessage() {} func (x *DeleteActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[74] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5721,7 +5721,7 @@ func (x *DeleteActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*DeleteActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{74} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{74} } func (x *DeleteActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5756,7 +5756,7 @@ type GetTagRequest struct { func (x *GetTagRequest) Reset() { *x = GetTagRequest{} - mi := &file_ateapi_proto_msgTypes[75] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5768,7 +5768,7 @@ func (x *GetTagRequest) String() string { func (*GetTagRequest) ProtoMessage() {} func (x *GetTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[75] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5781,7 +5781,7 @@ func (x *GetTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTagRequest.ProtoReflect.Descriptor instead. func (*GetTagRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{75} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{75} } func (x *GetTagRequest) GetTag() *ObjectRef { @@ -5820,7 +5820,7 @@ type MintActorJwtRequest struct { func (x *MintActorJwtRequest) Reset() { *x = MintActorJwtRequest{} - mi := &file_ateapi_proto_msgTypes[76] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5832,7 +5832,7 @@ func (x *MintActorJwtRequest) String() string { func (*MintActorJwtRequest) ProtoMessage() {} func (x *MintActorJwtRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[76] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5845,7 +5845,7 @@ func (x *MintActorJwtRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorJwtRequest.ProtoReflect.Descriptor instead. func (*MintActorJwtRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{76} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{76} } func (x *MintActorJwtRequest) GetActor() *ObjectRef { @@ -5900,7 +5900,7 @@ type MintActorJwtResponse struct { func (x *MintActorJwtResponse) Reset() { *x = MintActorJwtResponse{} - mi := &file_ateapi_proto_msgTypes[77] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5912,7 +5912,7 @@ func (x *MintActorJwtResponse) String() string { func (*MintActorJwtResponse) ProtoMessage() {} func (x *MintActorJwtResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[77] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5925,7 +5925,7 @@ func (x *MintActorJwtResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorJwtResponse.ProtoReflect.Descriptor instead. func (*MintActorJwtResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{77} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{77} } func (x *MintActorJwtResponse) GetActorJwt() string { @@ -5970,7 +5970,7 @@ type MintActorCertificateRequest struct { func (x *MintActorCertificateRequest) Reset() { *x = MintActorCertificateRequest{} - mi := &file_ateapi_proto_msgTypes[78] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5982,7 +5982,7 @@ func (x *MintActorCertificateRequest) String() string { func (*MintActorCertificateRequest) ProtoMessage() {} func (x *MintActorCertificateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[78] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5995,7 +5995,7 @@ func (x *MintActorCertificateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorCertificateRequest.ProtoReflect.Descriptor instead. func (*MintActorCertificateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{78} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{78} } func (x *MintActorCertificateRequest) GetActor() *ObjectRef { @@ -6032,7 +6032,7 @@ type MintActorCertificateResponse struct { func (x *MintActorCertificateResponse) Reset() { *x = MintActorCertificateResponse{} - mi := &file_ateapi_proto_msgTypes[79] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6044,7 +6044,7 @@ func (x *MintActorCertificateResponse) String() string { func (*MintActorCertificateResponse) ProtoMessage() {} func (x *MintActorCertificateResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[79] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6057,7 +6057,7 @@ func (x *MintActorCertificateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorCertificateResponse.ProtoReflect.Descriptor instead. func (*MintActorCertificateResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{79} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{79} } func (x *MintActorCertificateResponse) GetActorCertificates() [][]byte { @@ -6084,7 +6084,7 @@ type ListTagsRequest struct { func (x *ListTagsRequest) Reset() { *x = ListTagsRequest{} - mi := &file_ateapi_proto_msgTypes[80] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6096,7 +6096,7 @@ func (x *ListTagsRequest) String() string { func (*ListTagsRequest) ProtoMessage() {} func (x *ListTagsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[80] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6109,7 +6109,7 @@ func (x *ListTagsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTagsRequest.ProtoReflect.Descriptor instead. func (*ListTagsRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{80} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{80} } func (x *ListTagsRequest) GetAtespace() string { @@ -6136,7 +6136,7 @@ type ListTagsResponse struct { func (x *ListTagsResponse) Reset() { *x = ListTagsResponse{} - mi := &file_ateapi_proto_msgTypes[81] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6148,7 +6148,7 @@ func (x *ListTagsResponse) String() string { func (*ListTagsResponse) ProtoMessage() {} func (x *ListTagsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[81] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6161,7 +6161,7 @@ func (x *ListTagsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTagsResponse.ProtoReflect.Descriptor instead. func (*ListTagsResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{81} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{81} } func (x *ListTagsResponse) GetTags() []*Tag { @@ -6206,7 +6206,7 @@ type CreateTagRequest struct { func (x *CreateTagRequest) Reset() { *x = CreateTagRequest{} - mi := &file_ateapi_proto_msgTypes[82] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6218,7 +6218,7 @@ func (x *CreateTagRequest) String() string { func (*CreateTagRequest) ProtoMessage() {} func (x *CreateTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[82] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6231,7 +6231,7 @@ func (x *CreateTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateTagRequest.ProtoReflect.Descriptor instead. func (*CreateTagRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{82} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{82} } func (x *CreateTagRequest) GetTag() *Tag { @@ -6261,7 +6261,7 @@ type UpdateTagRequest struct { func (x *UpdateTagRequest) Reset() { *x = UpdateTagRequest{} - mi := &file_ateapi_proto_msgTypes[83] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6273,7 +6273,7 @@ func (x *UpdateTagRequest) String() string { func (*UpdateTagRequest) ProtoMessage() {} func (x *UpdateTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[83] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6286,7 +6286,7 @@ func (x *UpdateTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateTagRequest.ProtoReflect.Descriptor instead. func (*UpdateTagRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{83} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{83} } func (x *UpdateTagRequest) GetTag() *Tag { @@ -6311,7 +6311,7 @@ type DeleteTagRequest struct { func (x *DeleteTagRequest) Reset() { *x = DeleteTagRequest{} - mi := &file_ateapi_proto_msgTypes[84] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6323,7 +6323,7 @@ func (x *DeleteTagRequest) String() string { func (*DeleteTagRequest) ProtoMessage() {} func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[84] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6336,7 +6336,7 @@ func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteTagRequest.ProtoReflect.Descriptor instead. func (*DeleteTagRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{84} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{84} } func (x *DeleteTagRequest) GetTag() *ObjectRef { @@ -6375,7 +6375,7 @@ type DeleteOptions struct { func (x *DeleteOptions) Reset() { *x = DeleteOptions{} - mi := &file_ateapi_proto_msgTypes[85] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6387,7 +6387,7 @@ func (x *DeleteOptions) String() string { func (*DeleteOptions) ProtoMessage() {} func (x *DeleteOptions) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[85] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6400,7 +6400,7 @@ func (x *DeleteOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteOptions.ProtoReflect.Descriptor instead. func (*DeleteOptions) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{85} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{85} } func (x *DeleteOptions) GetVersion() int64 { @@ -6439,7 +6439,7 @@ type ListOptions struct { func (x *ListOptions) Reset() { *x = ListOptions{} - mi := &file_ateapi_proto_msgTypes[86] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6451,7 +6451,7 @@ func (x *ListOptions) String() string { func (*ListOptions) ProtoMessage() {} func (x *ListOptions) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[86] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6464,7 +6464,7 @@ func (x *ListOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use ListOptions.ProtoReflect.Descriptor instead. func (*ListOptions) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{86} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{86} } func (x *ListOptions) GetPageSize() int32 { @@ -6500,7 +6500,7 @@ type ListWorkerActorAssignmentsRequest struct { func (x *ListWorkerActorAssignmentsRequest) Reset() { *x = ListWorkerActorAssignmentsRequest{} - mi := &file_ateapi_proto_msgTypes[87] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6512,7 +6512,7 @@ func (x *ListWorkerActorAssignmentsRequest) String() string { func (*ListWorkerActorAssignmentsRequest) ProtoMessage() {} func (x *ListWorkerActorAssignmentsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[87] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6525,7 +6525,7 @@ func (x *ListWorkerActorAssignmentsRequest) ProtoReflect() protoreflect.Message // Deprecated: Use ListWorkerActorAssignmentsRequest.ProtoReflect.Descriptor instead. func (*ListWorkerActorAssignmentsRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{87} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{87} } func (x *ListWorkerActorAssignmentsRequest) GetWorker() *ObjectRef { @@ -6555,7 +6555,7 @@ type ListWorkerActorAssignmentsResponse struct { func (x *ListWorkerActorAssignmentsResponse) Reset() { *x = ListWorkerActorAssignmentsResponse{} - mi := &file_ateapi_proto_msgTypes[88] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6567,7 +6567,7 @@ func (x *ListWorkerActorAssignmentsResponse) String() string { func (*ListWorkerActorAssignmentsResponse) ProtoMessage() {} func (x *ListWorkerActorAssignmentsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[88] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6580,7 +6580,7 @@ func (x *ListWorkerActorAssignmentsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ListWorkerActorAssignmentsResponse.ProtoReflect.Descriptor instead. func (*ListWorkerActorAssignmentsResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{88} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{88} } func (x *ListWorkerActorAssignmentsResponse) GetActorAssignments() []*ActorAssignment { @@ -6609,7 +6609,7 @@ type ListWorkersRequest struct { func (x *ListWorkersRequest) Reset() { *x = ListWorkersRequest{} - mi := &file_ateapi_proto_msgTypes[89] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6621,7 +6621,7 @@ func (x *ListWorkersRequest) String() string { func (*ListWorkersRequest) ProtoMessage() {} func (x *ListWorkersRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[89] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6634,7 +6634,7 @@ func (x *ListWorkersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkersRequest.ProtoReflect.Descriptor instead. func (*ListWorkersRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{89} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{89} } func (x *ListWorkersRequest) GetOptions() *ListOptions { @@ -6656,7 +6656,7 @@ type ListWorkersResponse struct { func (x *ListWorkersResponse) Reset() { *x = ListWorkersResponse{} - mi := &file_ateapi_proto_msgTypes[90] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6668,7 +6668,7 @@ func (x *ListWorkersResponse) String() string { func (*ListWorkersResponse) ProtoMessage() {} func (x *ListWorkersResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[90] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6681,7 +6681,7 @@ func (x *ListWorkersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkersResponse.ProtoReflect.Descriptor instead. func (*ListWorkersResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{90} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{90} } func (x *ListWorkersResponse) GetWorkers() []*Worker { @@ -6711,7 +6711,7 @@ type GetWorkerRequest struct { func (x *GetWorkerRequest) Reset() { *x = GetWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[91] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6723,7 +6723,7 @@ func (x *GetWorkerRequest) String() string { func (*GetWorkerRequest) ProtoMessage() {} func (x *GetWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[91] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6736,7 +6736,7 @@ func (x *GetWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkerRequest.ProtoReflect.Descriptor instead. func (*GetWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{91} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{91} } func (x *GetWorkerRequest) GetWorker() *ObjectRef { @@ -6758,7 +6758,7 @@ type CreateWorkerRequest struct { func (x *CreateWorkerRequest) Reset() { *x = CreateWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[92] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6770,7 +6770,7 @@ func (x *CreateWorkerRequest) String() string { func (*CreateWorkerRequest) ProtoMessage() {} func (x *CreateWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[92] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6783,7 +6783,7 @@ func (x *CreateWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkerRequest.ProtoReflect.Descriptor instead. func (*CreateWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{92} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{92} } func (x *CreateWorkerRequest) GetWorker() *Worker { @@ -6818,7 +6818,7 @@ type UpdateWorkerRequest struct { func (x *UpdateWorkerRequest) Reset() { *x = UpdateWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[93] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6830,7 +6830,7 @@ func (x *UpdateWorkerRequest) String() string { func (*UpdateWorkerRequest) ProtoMessage() {} func (x *UpdateWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[93] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6843,7 +6843,7 @@ func (x *UpdateWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateWorkerRequest.ProtoReflect.Descriptor instead. func (*UpdateWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{93} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{93} } func (x *UpdateWorkerRequest) GetWorker() *Worker { @@ -6870,7 +6870,7 @@ type DeleteWorkerRequest struct { func (x *DeleteWorkerRequest) Reset() { *x = DeleteWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[94] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6882,7 +6882,7 @@ func (x *DeleteWorkerRequest) String() string { func (*DeleteWorkerRequest) ProtoMessage() {} func (x *DeleteWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[94] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6895,7 +6895,7 @@ func (x *DeleteWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkerRequest.ProtoReflect.Descriptor instead. func (*DeleteWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{94} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{94} } func (x *DeleteWorkerRequest) GetWorker() *ObjectRef { @@ -6925,7 +6925,7 @@ type DrainWorkerRequest struct { func (x *DrainWorkerRequest) Reset() { *x = DrainWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[95] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6937,7 +6937,7 @@ func (x *DrainWorkerRequest) String() string { func (*DrainWorkerRequest) ProtoMessage() {} func (x *DrainWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[95] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6950,7 +6950,7 @@ func (x *DrainWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DrainWorkerRequest.ProtoReflect.Descriptor instead. func (*DrainWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{95} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{95} } func (x *DrainWorkerRequest) GetWorker() *ObjectRef { @@ -6971,7 +6971,7 @@ type DrainWorkerResponse struct { func (x *DrainWorkerResponse) Reset() { *x = DrainWorkerResponse{} - mi := &file_ateapi_proto_msgTypes[96] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6983,7 +6983,7 @@ func (x *DrainWorkerResponse) String() string { func (*DrainWorkerResponse) ProtoMessage() {} func (x *DrainWorkerResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[96] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6996,7 +6996,7 @@ func (x *DrainWorkerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DrainWorkerResponse.ProtoReflect.Descriptor instead. func (*DrainWorkerResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{96} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{96} } func (x *DrainWorkerResponse) GetWorker() *Worker { @@ -7020,7 +7020,7 @@ type MarkWorkerAvailableRequest struct { func (x *MarkWorkerAvailableRequest) Reset() { *x = MarkWorkerAvailableRequest{} - mi := &file_ateapi_proto_msgTypes[97] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7032,7 +7032,7 @@ func (x *MarkWorkerAvailableRequest) String() string { func (*MarkWorkerAvailableRequest) ProtoMessage() {} func (x *MarkWorkerAvailableRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[97] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7045,7 +7045,7 @@ func (x *MarkWorkerAvailableRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerAvailableRequest.ProtoReflect.Descriptor instead. func (*MarkWorkerAvailableRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{97} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{97} } func (x *MarkWorkerAvailableRequest) GetWorker() *ObjectRef { @@ -7066,7 +7066,7 @@ type MarkWorkerAvailableResponse struct { func (x *MarkWorkerAvailableResponse) Reset() { *x = MarkWorkerAvailableResponse{} - mi := &file_ateapi_proto_msgTypes[98] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7078,7 +7078,7 @@ func (x *MarkWorkerAvailableResponse) String() string { func (*MarkWorkerAvailableResponse) ProtoMessage() {} func (x *MarkWorkerAvailableResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[98] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7091,7 +7091,7 @@ func (x *MarkWorkerAvailableResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerAvailableResponse.ProtoReflect.Descriptor instead. func (*MarkWorkerAvailableResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{98} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{98} } func (x *MarkWorkerAvailableResponse) GetWorker() *Worker { @@ -7115,7 +7115,7 @@ type MarkWorkerUnavailableRequest struct { func (x *MarkWorkerUnavailableRequest) Reset() { *x = MarkWorkerUnavailableRequest{} - mi := &file_ateapi_proto_msgTypes[99] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7127,7 +7127,7 @@ func (x *MarkWorkerUnavailableRequest) String() string { func (*MarkWorkerUnavailableRequest) ProtoMessage() {} func (x *MarkWorkerUnavailableRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[99] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7140,7 +7140,7 @@ func (x *MarkWorkerUnavailableRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerUnavailableRequest.ProtoReflect.Descriptor instead. func (*MarkWorkerUnavailableRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{99} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{99} } func (x *MarkWorkerUnavailableRequest) GetWorker() *ObjectRef { @@ -7161,7 +7161,7 @@ type MarkWorkerUnavailableResponse struct { func (x *MarkWorkerUnavailableResponse) Reset() { *x = MarkWorkerUnavailableResponse{} - mi := &file_ateapi_proto_msgTypes[100] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7173,7 +7173,7 @@ func (x *MarkWorkerUnavailableResponse) String() string { func (*MarkWorkerUnavailableResponse) ProtoMessage() {} func (x *MarkWorkerUnavailableResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[100] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7186,7 +7186,7 @@ func (x *MarkWorkerUnavailableResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerUnavailableResponse.ProtoReflect.Descriptor instead. func (*MarkWorkerUnavailableResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{100} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{100} } func (x *MarkWorkerUnavailableResponse) GetWorker() *Worker { @@ -7215,7 +7215,7 @@ type ListActorsRequest struct { func (x *ListActorsRequest) Reset() { *x = ListActorsRequest{} - mi := &file_ateapi_proto_msgTypes[101] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7227,7 +7227,7 @@ func (x *ListActorsRequest) String() string { func (*ListActorsRequest) ProtoMessage() {} func (x *ListActorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[101] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7240,7 +7240,7 @@ func (x *ListActorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorsRequest.ProtoReflect.Descriptor instead. func (*ListActorsRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{101} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{101} } func (x *ListActorsRequest) GetAtespace() string { @@ -7269,7 +7269,7 @@ type ListActorsResponse struct { func (x *ListActorsResponse) Reset() { *x = ListActorsResponse{} - mi := &file_ateapi_proto_msgTypes[102] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7281,7 +7281,7 @@ func (x *ListActorsResponse) String() string { func (*ListActorsResponse) ProtoMessage() {} func (x *ListActorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[102] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7294,7 +7294,7 @@ func (x *ListActorsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorsResponse.ProtoReflect.Descriptor instead. func (*ListActorsResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{102} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{102} } func (x *ListActorsResponse) GetActors() []*Actor { @@ -7382,7 +7382,7 @@ type Worker struct { func (x *Worker) Reset() { *x = Worker{} - mi := &file_ateapi_proto_msgTypes[103] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7394,7 +7394,7 @@ func (x *Worker) String() string { func (*Worker) ProtoMessage() {} func (x *Worker) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[103] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7407,7 +7407,7 @@ func (x *Worker) ProtoReflect() protoreflect.Message { // Deprecated: Use Worker.ProtoReflect.Descriptor instead. func (*Worker) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{103} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{103} } func (x *Worker) GetMetadata() *ResourceMetadata { @@ -7478,7 +7478,7 @@ type WorkerStatus struct { // +k8s:required // +k8s:minimum=1 // +k8s:maximum=3 # keep this in sync with the WorkerState enum - State WorkerState `protobuf:"varint,1,opt,name=state,proto3,enum=ateapi.WorkerState" json:"state,omitempty"` + State WorkerState `protobuf:"varint,1,opt,name=state,proto3,enum=substrate.ateapi.v1.WorkerState" json:"state,omitempty"` // The total resource capacity of the Worker. // // A Worker should report every dimension of resources it has available to be @@ -7548,7 +7548,7 @@ type WorkerStatus struct { func (x *WorkerStatus) Reset() { *x = WorkerStatus{} - mi := &file_ateapi_proto_msgTypes[104] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7560,7 +7560,7 @@ func (x *WorkerStatus) String() string { func (*WorkerStatus) ProtoMessage() {} func (x *WorkerStatus) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[104] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7573,7 +7573,7 @@ func (x *WorkerStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerStatus.ProtoReflect.Descriptor instead. func (*WorkerStatus) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{104} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{104} } func (x *WorkerStatus) GetState() WorkerState { @@ -7661,7 +7661,7 @@ type WorkerSandboxClass struct { func (x *WorkerSandboxClass) Reset() { *x = WorkerSandboxClass{} - mi := &file_ateapi_proto_msgTypes[105] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7673,7 +7673,7 @@ func (x *WorkerSandboxClass) String() string { func (*WorkerSandboxClass) ProtoMessage() {} func (x *WorkerSandboxClass) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[105] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7686,7 +7686,7 @@ func (x *WorkerSandboxClass) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerSandboxClass.ProtoReflect.Descriptor instead. func (*WorkerSandboxClass) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{105} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{105} } func (x *WorkerSandboxClass) GetSandboxClass() string { @@ -7729,7 +7729,7 @@ type WorkerSandboxRuntime struct { func (x *WorkerSandboxRuntime) Reset() { *x = WorkerSandboxRuntime{} - mi := &file_ateapi_proto_msgTypes[106] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7741,7 +7741,7 @@ func (x *WorkerSandboxRuntime) String() string { func (*WorkerSandboxRuntime) ProtoMessage() {} func (x *WorkerSandboxRuntime) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[106] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7754,7 +7754,7 @@ func (x *WorkerSandboxRuntime) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerSandboxRuntime.ProtoReflect.Descriptor instead. func (*WorkerSandboxRuntime) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{106} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{106} } func (x *WorkerSandboxRuntime) GetVersion() *VersionedSandboxCompat { @@ -7786,7 +7786,7 @@ type ActorSandboxRuntime struct { func (x *ActorSandboxRuntime) Reset() { *x = ActorSandboxRuntime{} - mi := &file_ateapi_proto_msgTypes[107] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7798,7 +7798,7 @@ func (x *ActorSandboxRuntime) String() string { func (*ActorSandboxRuntime) ProtoMessage() {} func (x *ActorSandboxRuntime) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[107] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7811,7 +7811,7 @@ func (x *ActorSandboxRuntime) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorSandboxRuntime.ProtoReflect.Descriptor instead. func (*ActorSandboxRuntime) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{107} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{107} } func (x *ActorSandboxRuntime) GetSandboxClass() string { @@ -7862,7 +7862,7 @@ type VersionedSandboxCompat struct { func (x *VersionedSandboxCompat) Reset() { *x = VersionedSandboxCompat{} - mi := &file_ateapi_proto_msgTypes[108] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7874,7 +7874,7 @@ func (x *VersionedSandboxCompat) String() string { func (*VersionedSandboxCompat) ProtoMessage() {} func (x *VersionedSandboxCompat) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[108] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7887,7 +7887,7 @@ func (x *VersionedSandboxCompat) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionedSandboxCompat.ProtoReflect.Descriptor instead. func (*VersionedSandboxCompat) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{108} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{108} } func (x *VersionedSandboxCompat) GetSchemaVersion() string { @@ -7923,7 +7923,7 @@ type AttributeEntry struct { func (x *AttributeEntry) Reset() { *x = AttributeEntry{} - mi := &file_ateapi_proto_msgTypes[109] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7935,7 +7935,7 @@ func (x *AttributeEntry) String() string { func (*AttributeEntry) ProtoMessage() {} func (x *AttributeEntry) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[109] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7948,7 +7948,7 @@ func (x *AttributeEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributeEntry.ProtoReflect.Descriptor instead. func (*AttributeEntry) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{109} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{109} } func (x *AttributeEntry) GetKey() string { @@ -7995,7 +7995,7 @@ type WorkerResources struct { func (x *WorkerResources) Reset() { *x = WorkerResources{} - mi := &file_ateapi_proto_msgTypes[110] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8007,7 +8007,7 @@ func (x *WorkerResources) String() string { func (*WorkerResources) ProtoMessage() {} func (x *WorkerResources) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[110] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8020,7 +8020,7 @@ func (x *WorkerResources) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerResources.ProtoReflect.Descriptor instead. func (*WorkerResources) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{110} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{110} } func (x *WorkerResources) GetCpuMillicores() int64 { @@ -8075,7 +8075,7 @@ type ActorAssignment struct { func (x *ActorAssignment) Reset() { *x = ActorAssignment{} - mi := &file_ateapi_proto_msgTypes[111] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8087,7 +8087,7 @@ func (x *ActorAssignment) String() string { func (*ActorAssignment) ProtoMessage() {} func (x *ActorAssignment) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[111] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8100,7 +8100,7 @@ func (x *ActorAssignment) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorAssignment.ProtoReflect.Descriptor instead. func (*ActorAssignment) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{111} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{111} } func (x *ActorAssignment) GetMetadata() *ResourceMetadata { @@ -8145,7 +8145,7 @@ type AcquireWorkerEpochRequest struct { func (x *AcquireWorkerEpochRequest) Reset() { *x = AcquireWorkerEpochRequest{} - mi := &file_ateapi_proto_msgTypes[112] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8157,7 +8157,7 @@ func (x *AcquireWorkerEpochRequest) String() string { func (*AcquireWorkerEpochRequest) ProtoMessage() {} func (x *AcquireWorkerEpochRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[112] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8170,7 +8170,7 @@ func (x *AcquireWorkerEpochRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AcquireWorkerEpochRequest.ProtoReflect.Descriptor instead. func (*AcquireWorkerEpochRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{112} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{112} } func (x *AcquireWorkerEpochRequest) GetWorker() *ObjectRef { @@ -8190,7 +8190,7 @@ type AcquireWorkerEpochResponse struct { func (x *AcquireWorkerEpochResponse) Reset() { *x = AcquireWorkerEpochResponse{} - mi := &file_ateapi_proto_msgTypes[113] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8202,7 +8202,7 @@ func (x *AcquireWorkerEpochResponse) String() string { func (*AcquireWorkerEpochResponse) ProtoMessage() {} func (x *AcquireWorkerEpochResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[113] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8215,7 +8215,7 @@ func (x *AcquireWorkerEpochResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AcquireWorkerEpochResponse.ProtoReflect.Descriptor instead. func (*AcquireWorkerEpochResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{113} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{113} } func (x *AcquireWorkerEpochResponse) GetEpoch() int64 { @@ -8258,7 +8258,7 @@ type RegisterWorkerRequest struct { func (x *RegisterWorkerRequest) Reset() { *x = RegisterWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[114] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8270,7 +8270,7 @@ func (x *RegisterWorkerRequest) String() string { func (*RegisterWorkerRequest) ProtoMessage() {} func (x *RegisterWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[114] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8283,7 +8283,7 @@ func (x *RegisterWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterWorkerRequest.ProtoReflect.Descriptor instead. func (*RegisterWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{114} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{114} } func (x *RegisterWorkerRequest) GetWorker() *ObjectRef { @@ -8324,7 +8324,7 @@ type RegisterWorkerResponse struct { func (x *RegisterWorkerResponse) Reset() { *x = RegisterWorkerResponse{} - mi := &file_ateapi_proto_msgTypes[115] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8336,7 +8336,7 @@ func (x *RegisterWorkerResponse) String() string { func (*RegisterWorkerResponse) ProtoMessage() {} func (x *RegisterWorkerResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[115] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8349,7 +8349,7 @@ func (x *RegisterWorkerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterWorkerResponse.ProtoReflect.Descriptor instead. func (*RegisterWorkerResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{115} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{115} } func (x *RegisterWorkerResponse) GetWorker() *Worker { @@ -8389,7 +8389,7 @@ type SetWorkerSandboxRuntimesRequest struct { func (x *SetWorkerSandboxRuntimesRequest) Reset() { *x = SetWorkerSandboxRuntimesRequest{} - mi := &file_ateapi_proto_msgTypes[116] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8401,7 +8401,7 @@ func (x *SetWorkerSandboxRuntimesRequest) String() string { func (*SetWorkerSandboxRuntimesRequest) ProtoMessage() {} func (x *SetWorkerSandboxRuntimesRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[116] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8414,7 +8414,7 @@ func (x *SetWorkerSandboxRuntimesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWorkerSandboxRuntimesRequest.ProtoReflect.Descriptor instead. func (*SetWorkerSandboxRuntimesRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{116} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{116} } func (x *SetWorkerSandboxRuntimesRequest) GetWorker() *ObjectRef { @@ -8448,7 +8448,7 @@ type SetWorkerSandboxRuntimesResponse struct { func (x *SetWorkerSandboxRuntimesResponse) Reset() { *x = SetWorkerSandboxRuntimesResponse{} - mi := &file_ateapi_proto_msgTypes[117] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8460,7 +8460,7 @@ func (x *SetWorkerSandboxRuntimesResponse) String() string { func (*SetWorkerSandboxRuntimesResponse) ProtoMessage() {} func (x *SetWorkerSandboxRuntimesResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[117] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8473,7 +8473,7 @@ func (x *SetWorkerSandboxRuntimesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWorkerSandboxRuntimesResponse.ProtoReflect.Descriptor instead. func (*SetWorkerSandboxRuntimesResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{117} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{117} } func (x *SetWorkerSandboxRuntimesResponse) GetWorker() *Worker { @@ -8520,7 +8520,7 @@ type MintWorkerActorCertificateRequest struct { func (x *MintWorkerActorCertificateRequest) Reset() { *x = MintWorkerActorCertificateRequest{} - mi := &file_ateapi_proto_msgTypes[118] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8532,7 +8532,7 @@ func (x *MintWorkerActorCertificateRequest) String() string { func (*MintWorkerActorCertificateRequest) ProtoMessage() {} func (x *MintWorkerActorCertificateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[118] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8545,7 +8545,7 @@ func (x *MintWorkerActorCertificateRequest) ProtoReflect() protoreflect.Message // Deprecated: Use MintWorkerActorCertificateRequest.ProtoReflect.Descriptor instead. func (*MintWorkerActorCertificateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{118} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{118} } func (x *MintWorkerActorCertificateRequest) GetActor() *ObjectRef { @@ -8589,7 +8589,7 @@ type MintWorkerActorCertificateResponse struct { func (x *MintWorkerActorCertificateResponse) Reset() { *x = MintWorkerActorCertificateResponse{} - mi := &file_ateapi_proto_msgTypes[119] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8601,7 +8601,7 @@ func (x *MintWorkerActorCertificateResponse) String() string { func (*MintWorkerActorCertificateResponse) ProtoMessage() {} func (x *MintWorkerActorCertificateResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[119] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8614,7 +8614,7 @@ func (x *MintWorkerActorCertificateResponse) ProtoReflect() protoreflect.Message // Deprecated: Use MintWorkerActorCertificateResponse.ProtoReflect.Descriptor instead. func (*MintWorkerActorCertificateResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{119} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{119} } func (x *MintWorkerActorCertificateResponse) GetActorCertificates() [][]byte { @@ -8655,7 +8655,7 @@ type MintWorkerActorJwtRequest struct { func (x *MintWorkerActorJwtRequest) Reset() { *x = MintWorkerActorJwtRequest{} - mi := &file_ateapi_proto_msgTypes[120] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8667,7 +8667,7 @@ func (x *MintWorkerActorJwtRequest) String() string { func (*MintWorkerActorJwtRequest) ProtoMessage() {} func (x *MintWorkerActorJwtRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[120] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8680,7 +8680,7 @@ func (x *MintWorkerActorJwtRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintWorkerActorJwtRequest.ProtoReflect.Descriptor instead. func (*MintWorkerActorJwtRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{120} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{120} } func (x *MintWorkerActorJwtRequest) GetActor() *ObjectRef { @@ -8728,7 +8728,7 @@ type MintWorkerActorJwtResponse struct { func (x *MintWorkerActorJwtResponse) Reset() { *x = MintWorkerActorJwtResponse{} - mi := &file_ateapi_proto_msgTypes[121] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8740,7 +8740,7 @@ func (x *MintWorkerActorJwtResponse) String() string { func (*MintWorkerActorJwtResponse) ProtoMessage() {} func (x *MintWorkerActorJwtResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[121] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8753,7 +8753,7 @@ func (x *MintWorkerActorJwtResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MintWorkerActorJwtResponse.ProtoReflect.Descriptor instead. func (*MintWorkerActorJwtResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{121} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{121} } func (x *MintWorkerActorJwtResponse) GetActorJwt() string { @@ -8801,7 +8801,7 @@ type RequestActorSuspendRequest struct { func (x *RequestActorSuspendRequest) Reset() { *x = RequestActorSuspendRequest{} - mi := &file_ateapi_proto_msgTypes[122] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8813,7 +8813,7 @@ func (x *RequestActorSuspendRequest) String() string { func (*RequestActorSuspendRequest) ProtoMessage() {} func (x *RequestActorSuspendRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[122] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8826,7 +8826,7 @@ func (x *RequestActorSuspendRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestActorSuspendRequest.ProtoReflect.Descriptor instead. func (*RequestActorSuspendRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{122} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{122} } func (x *RequestActorSuspendRequest) GetWorker() *ObjectRef { @@ -8860,7 +8860,7 @@ type RequestActorSuspendResponse struct { func (x *RequestActorSuspendResponse) Reset() { *x = RequestActorSuspendResponse{} - mi := &file_ateapi_proto_msgTypes[123] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8872,7 +8872,7 @@ func (x *RequestActorSuspendResponse) String() string { func (*RequestActorSuspendResponse) ProtoMessage() {} func (x *RequestActorSuspendResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[123] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8885,7 +8885,7 @@ func (x *RequestActorSuspendResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestActorSuspendResponse.ProtoReflect.Descriptor instead. func (*RequestActorSuspendResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{123} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{123} } func (x *RequestActorSuspendResponse) GetActor() *Actor { @@ -8925,7 +8925,7 @@ type ReportActorCrashedRequest struct { func (x *ReportActorCrashedRequest) Reset() { *x = ReportActorCrashedRequest{} - mi := &file_ateapi_proto_msgTypes[124] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8937,7 +8937,7 @@ func (x *ReportActorCrashedRequest) String() string { func (*ReportActorCrashedRequest) ProtoMessage() {} func (x *ReportActorCrashedRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[124] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8950,7 +8950,7 @@ func (x *ReportActorCrashedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorCrashedRequest.ProtoReflect.Descriptor instead. func (*ReportActorCrashedRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{124} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{124} } func (x *ReportActorCrashedRequest) GetWorker() *ObjectRef { @@ -8991,7 +8991,7 @@ type ReportActorCrashedResponse struct { func (x *ReportActorCrashedResponse) Reset() { *x = ReportActorCrashedResponse{} - mi := &file_ateapi_proto_msgTypes[125] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9003,7 +9003,7 @@ func (x *ReportActorCrashedResponse) String() string { func (*ReportActorCrashedResponse) ProtoMessage() {} func (x *ReportActorCrashedResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[125] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9016,7 +9016,7 @@ func (x *ReportActorCrashedResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorCrashedResponse.ProtoReflect.Descriptor instead. func (*ReportActorCrashedResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{125} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{125} } func (x *ReportActorCrashedResponse) GetActor() *Actor { @@ -9047,7 +9047,7 @@ type ReportActorSnapshotStateRequest struct { func (x *ReportActorSnapshotStateRequest) Reset() { *x = ReportActorSnapshotStateRequest{} - mi := &file_ateapi_proto_msgTypes[126] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9059,7 +9059,7 @@ func (x *ReportActorSnapshotStateRequest) String() string { func (*ReportActorSnapshotStateRequest) ProtoMessage() {} func (x *ReportActorSnapshotStateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[126] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9072,7 +9072,7 @@ func (x *ReportActorSnapshotStateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorSnapshotStateRequest.ProtoReflect.Descriptor instead. func (*ReportActorSnapshotStateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{126} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{126} } func (x *ReportActorSnapshotStateRequest) GetActor() *ObjectRef { @@ -9104,7 +9104,7 @@ type ReportActorSnapshotStateResponse struct { func (x *ReportActorSnapshotStateResponse) Reset() { *x = ReportActorSnapshotStateResponse{} - mi := &file_ateapi_proto_msgTypes[127] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9116,7 +9116,7 @@ func (x *ReportActorSnapshotStateResponse) String() string { func (*ReportActorSnapshotStateResponse) ProtoMessage() {} func (x *ReportActorSnapshotStateResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[127] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[127] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9129,7 +9129,7 @@ func (x *ReportActorSnapshotStateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorSnapshotStateResponse.ProtoReflect.Descriptor instead. func (*ReportActorSnapshotStateResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{127} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{127} } // ActorSnapshotState is what atelet holds for one Actor on its node. It @@ -9163,7 +9163,7 @@ type ActorSnapshotState struct { func (x *ActorSnapshotState) Reset() { *x = ActorSnapshotState{} - mi := &file_ateapi_proto_msgTypes[128] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[128] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9175,7 +9175,7 @@ func (x *ActorSnapshotState) String() string { func (*ActorSnapshotState) ProtoMessage() {} func (x *ActorSnapshotState) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[128] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[128] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9188,7 +9188,7 @@ func (x *ActorSnapshotState) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorSnapshotState.ProtoReflect.Descriptor instead. func (*ActorSnapshotState) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{128} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{128} } func (x *ActorSnapshotState) GetLatestLocal() *SnapshotReport { @@ -9238,7 +9238,7 @@ type SnapshotReport struct { // +k8s:required // +k8s:minimum=1 // +k8s:maximum=3 # keep this in sync with the SnapshotFidelity enum - Fidelity SnapshotFidelity `protobuf:"varint,3,opt,name=fidelity,proto3,enum=ateapi.SnapshotFidelity" json:"fidelity,omitempty"` + Fidelity SnapshotFidelity `protobuf:"varint,3,opt,name=fidelity,proto3,enum=substrate.ateapi.v1.SnapshotFidelity" json:"fidelity,omitempty"` // Where the snapshot's durable copy is, or will be, uploaded. // // +k8s:required @@ -9260,7 +9260,7 @@ type SnapshotReport struct { func (x *SnapshotReport) Reset() { *x = SnapshotReport{} - mi := &file_ateapi_proto_msgTypes[129] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9272,7 +9272,7 @@ func (x *SnapshotReport) String() string { func (*SnapshotReport) ProtoMessage() {} func (x *SnapshotReport) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[129] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[129] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9285,7 +9285,7 @@ func (x *SnapshotReport) ProtoReflect() protoreflect.Message { // Deprecated: Use SnapshotReport.ProtoReflect.Descriptor instead. func (*SnapshotReport) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{129} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{129} } func (x *SnapshotReport) GetUuid() string { @@ -9355,7 +9355,7 @@ type AccessPolicy struct { func (x *AccessPolicy) Reset() { *x = AccessPolicy{} - mi := &file_ateapi_proto_msgTypes[130] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[130] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9367,7 +9367,7 @@ func (x *AccessPolicy) String() string { func (*AccessPolicy) ProtoMessage() {} func (x *AccessPolicy) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[130] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[130] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9380,7 +9380,7 @@ func (x *AccessPolicy) ProtoReflect() protoreflect.Message { // Deprecated: Use AccessPolicy.ProtoReflect.Descriptor instead. func (*AccessPolicy) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{130} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{130} } func (x *AccessPolicy) GetMetadata() *ResourceMetadata { @@ -9422,7 +9422,7 @@ type Binding struct { func (x *Binding) Reset() { *x = Binding{} - mi := &file_ateapi_proto_msgTypes[131] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[131] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9434,7 +9434,7 @@ func (x *Binding) String() string { func (*Binding) ProtoMessage() {} func (x *Binding) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[131] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[131] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9447,7 +9447,7 @@ func (x *Binding) ProtoReflect() protoreflect.Message { // Deprecated: Use Binding.ProtoReflect.Descriptor instead. func (*Binding) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{131} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{131} } func (x *Binding) GetRole() string { @@ -9479,7 +9479,7 @@ type GetGlobalAccessPolicyRequest struct { func (x *GetGlobalAccessPolicyRequest) Reset() { *x = GetGlobalAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[132] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[132] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9491,7 +9491,7 @@ func (x *GetGlobalAccessPolicyRequest) String() string { func (*GetGlobalAccessPolicyRequest) ProtoMessage() {} func (x *GetGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[132] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[132] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9504,7 +9504,7 @@ func (x *GetGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*GetGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{132} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{132} } func (x *GetGlobalAccessPolicyRequest) GetName() string { @@ -9528,7 +9528,7 @@ type CreateGlobalAccessPolicyRequest struct { func (x *CreateGlobalAccessPolicyRequest) Reset() { *x = CreateGlobalAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[133] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[133] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9540,7 +9540,7 @@ func (x *CreateGlobalAccessPolicyRequest) String() string { func (*CreateGlobalAccessPolicyRequest) ProtoMessage() {} func (x *CreateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[133] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[133] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9553,7 +9553,7 @@ func (x *CreateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{133} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{133} } func (x *CreateGlobalAccessPolicyRequest) GetAccessPolicy() *AccessPolicy { @@ -9577,7 +9577,7 @@ type UpdateGlobalAccessPolicyRequest struct { func (x *UpdateGlobalAccessPolicyRequest) Reset() { *x = UpdateGlobalAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[134] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[134] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9589,7 +9589,7 @@ func (x *UpdateGlobalAccessPolicyRequest) String() string { func (*UpdateGlobalAccessPolicyRequest) ProtoMessage() {} func (x *UpdateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[134] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[134] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9602,7 +9602,7 @@ func (x *UpdateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{134} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{134} } func (x *UpdateGlobalAccessPolicyRequest) GetAccessPolicy() *AccessPolicy { @@ -9632,7 +9632,7 @@ type GetAtespaceAccessPolicyRequest struct { func (x *GetAtespaceAccessPolicyRequest) Reset() { *x = GetAtespaceAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[135] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[135] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9644,7 +9644,7 @@ func (x *GetAtespaceAccessPolicyRequest) String() string { func (*GetAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *GetAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[135] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[135] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9657,7 +9657,7 @@ func (x *GetAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*GetAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{135} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{135} } func (x *GetAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9693,7 +9693,7 @@ type CreateAtespaceAccessPolicyRequest struct { func (x *CreateAtespaceAccessPolicyRequest) Reset() { *x = CreateAtespaceAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[136] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[136] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9705,7 +9705,7 @@ func (x *CreateAtespaceAccessPolicyRequest) String() string { func (*CreateAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *CreateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[136] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[136] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9718,7 +9718,7 @@ func (x *CreateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use CreateAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{136} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{136} } func (x *CreateAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9754,7 +9754,7 @@ type UpdateAtespaceAccessPolicyRequest struct { func (x *UpdateAtespaceAccessPolicyRequest) Reset() { *x = UpdateAtespaceAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[137] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[137] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9766,7 +9766,7 @@ func (x *UpdateAtespaceAccessPolicyRequest) String() string { func (*UpdateAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *UpdateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[137] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[137] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9779,7 +9779,7 @@ func (x *UpdateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use UpdateAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{137} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{137} } func (x *UpdateAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9820,7 +9820,7 @@ type DeleteAtespaceAccessPolicyRequest struct { func (x *DeleteAtespaceAccessPolicyRequest) Reset() { *x = DeleteAtespaceAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[138] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[138] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9832,7 +9832,7 @@ func (x *DeleteAtespaceAccessPolicyRequest) String() string { func (*DeleteAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *DeleteAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[138] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[138] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9845,7 +9845,7 @@ func (x *DeleteAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use DeleteAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*DeleteAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{138} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{138} } func (x *DeleteAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9881,7 +9881,7 @@ type ResourceAnnotation struct { Singleton bool `protobuf:"varint,2,opt,name=singleton,proto3" json:"singleton,omitempty"` // Whether a top-level resource belongs to an atespace. Set only on a // top-level resource: a subresource has its parent's scope. - Scope Scope `protobuf:"varint,3,opt,name=scope,proto3,enum=ateapi.Scope" json:"scope,omitempty"` + Scope Scope `protobuf:"varint,3,opt,name=scope,proto3,enum=substrate.ateapi.v1.Scope" json:"scope,omitempty"` // The resource's plural name, as List methods and their response fields // use it. For example, "AccessPolicies" for AccessPolicy. Plural string `protobuf:"bytes,4,opt,name=plural,proto3" json:"plural,omitempty"` @@ -9891,7 +9891,7 @@ type ResourceAnnotation struct { func (x *ResourceAnnotation) Reset() { *x = ResourceAnnotation{} - mi := &file_ateapi_proto_msgTypes[139] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[139] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9903,7 +9903,7 @@ func (x *ResourceAnnotation) String() string { func (*ResourceAnnotation) ProtoMessage() {} func (x *ResourceAnnotation) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[139] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[139] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9916,7 +9916,7 @@ func (x *ResourceAnnotation) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceAnnotation.ProtoReflect.Descriptor instead. func (*ResourceAnnotation) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{139} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{139} } func (x *ResourceAnnotation) GetParents() []string { @@ -9959,7 +9959,7 @@ type MethodAnnotation struct { func (x *MethodAnnotation) Reset() { *x = MethodAnnotation{} - mi := &file_ateapi_proto_msgTypes[140] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[140] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9971,7 +9971,7 @@ func (x *MethodAnnotation) String() string { func (*MethodAnnotation) ProtoMessage() {} func (x *MethodAnnotation) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[140] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[140] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9984,7 +9984,7 @@ func (x *MethodAnnotation) ProtoReflect() protoreflect.Message { // Deprecated: Use MethodAnnotation.ProtoReflect.Descriptor instead. func (*MethodAnnotation) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{140} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{140} } func (x *MethodAnnotation) GetResource() string { @@ -9994,60 +9994,60 @@ func (x *MethodAnnotation) GetResource() string { return "" } -var file_ateapi_proto_extTypes = []protoimpl.ExtensionInfo{ +var file_api_ateapi_v1_ateapi_proto_extTypes = []protoimpl.ExtensionInfo{ { ExtendedType: (*descriptorpb.MessageOptions)(nil), ExtensionType: (*ResourceAnnotation)(nil), Field: 50000, - Name: "ateapi.resource", + Name: "substrate.ateapi.v1.resource", Tag: "bytes,50000,opt,name=resource", - Filename: "ateapi.proto", + Filename: "api/ateapi/v1/ateapi.proto", }, { ExtendedType: (*descriptorpb.MethodOptions)(nil), ExtensionType: (*MethodAnnotation)(nil), Field: 50000, - Name: "ateapi.method", + Name: "substrate.ateapi.v1.method", Tag: "bytes,50000,opt,name=method", - Filename: "ateapi.proto", + Filename: "api/ateapi/v1/ateapi.proto", }, } // Extension fields to descriptorpb.MessageOptions. var ( - // optional ateapi.ResourceAnnotation resource = 50000; - E_Resource = &file_ateapi_proto_extTypes[0] + // optional substrate.ateapi.v1.ResourceAnnotation resource = 50000; + E_Resource = &file_api_ateapi_v1_ateapi_proto_extTypes[0] ) // Extension fields to descriptorpb.MethodOptions. var ( - // optional ateapi.MethodAnnotation method = 50000; - E_Method = &file_ateapi_proto_extTypes[1] + // optional substrate.ateapi.v1.MethodAnnotation method = 50000; + E_Method = &file_api_ateapi_v1_ateapi_proto_extTypes[1] ) -var File_ateapi_proto protoreflect.FileDescriptor +var File_api_ateapi_v1_ateapi_proto protoreflect.FileDescriptor -const file_ateapi_proto_rawDesc = "" + +const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\n" + - "\fateapi.proto\x12\x06ateapi\x1a google/protobuf/descriptor.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"3\n" + + "\x1aapi/ateapi/v1/ateapi.proto\x12\x13substrate.ateapi.v1\x1a google/protobuf/descriptor.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"3\n" + "\x0eObjectSnapshot\x12!\n" + - "\fsnapshot_uri\x18\x01 \x01(\tR\vsnapshotUri\"x\n" + - "\x0fSnapshotStorage\x125\n" + - "\x06status\x18\x01 \x01(\x0e2\x1d.ateapi.SnapshotStorageStatusR\x06status\x12.\n" + - "\x06object\x18\x02 \x01(\v2\x16.ateapi.ObjectSnapshotR\x06object\"\xf5\x02\n" + + "\fsnapshot_uri\x18\x01 \x01(\tR\vsnapshotUri\"\x92\x01\n" + + "\x0fSnapshotStorage\x12B\n" + + "\x06status\x18\x01 \x01(\x0e2*.substrate.ateapi.v1.SnapshotStorageStatusR\x06status\x12;\n" + + "\x06object\x18\x02 \x01(\v2#.substrate.ateapi.v1.ObjectSnapshotR\x06object\"\xa9\x03\n" + "\bSnapshot\x12\x12\n" + "\x04uuid\x18\x01 \x01(\tR\x04uuid\x12\x1e\n" + "\n" + "generation\x18\x02 \x01(\x05R\n" + - "generation\x12+\n" + - "\x05owner\x18\x03 \x01(\x0e2\x15.ateapi.SnapshotOwnerR\x05owner\x124\n" + - "\bfidelity\x18\x04 \x01(\x0e2\x18.ateapi.SnapshotFidelityR\bfidelity\x12,\n" + + "generation\x128\n" + + "\x05owner\x18\x03 \x01(\x0e2\".substrate.ateapi.v1.SnapshotOwnerR\x05owner\x12A\n" + + "\bfidelity\x18\x04 \x01(\x0e2%.substrate.ateapi.v1.SnapshotFidelityR\bfidelity\x12,\n" + "\x12actor_template_uid\x18\x05 \x01(\tR\x10actorTemplateUid\x12\x1a\n" + - "\blocality\x18\x06 \x01(\tR\blocality\x12B\n" + - "\x10durable_snapshot\x18\a \x01(\v2\x17.ateapi.SnapshotStorageR\x0fdurableSnapshot\x12D\n" + - "\x0fsandbox_runtime\x18\b \x01(\v2\x1b.ateapi.ActorSandboxRuntimeR\x0esandboxRuntime\"\x90\x01\n" + - "\bSelector\x12D\n" + - "\fmatch_labels\x18\x01 \x03(\v2!.ateapi.Selector.MatchLabelsEntryR\vmatchLabels\x1a>\n" + + "\blocality\x18\x06 \x01(\tR\blocality\x12O\n" + + "\x10durable_snapshot\x18\a \x01(\v2$.substrate.ateapi.v1.SnapshotStorageR\x0fdurableSnapshot\x12Q\n" + + "\x0fsandbox_runtime\x18\b \x01(\v2(.substrate.ateapi.v1.ActorSandboxRuntimeR\x0esandboxRuntime\"\x9d\x01\n" + + "\bSelector\x12Q\n" + + "\fmatch_labels\x18\x01 \x03(\v2..substrate.ateapi.v1.Selector.MatchLabelsEntryR\vmatchLabels\x1a>\n" + "\x10MatchLabelsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xa5\x02\n" + @@ -10061,78 +10061,78 @@ const file_ateapi_proto_rawDesc = "" + "\vupdate_time\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\n" + "updateTime\x12;\n" + "\vdelete_time\x18\a \x01(\v2\x1a.google.protobuf.TimestampR\n" + - "deleteTime\"I\n" + - "\x0fExternalVolumes\x126\n" + - "\avolumes\x18\x01 \x03(\v2\x1c.ateapi.ExternalVolumeStatusR\avolumes\"\x91\x02\n" + + "deleteTime\"V\n" + + "\x0fExternalVolumes\x12C\n" + + "\avolumes\x18\x01 \x03(\v2).substrate.ateapi.v1.ExternalVolumeStatusR\avolumes\"\x9e\x02\n" + "\x14ExternalVolumeStatus\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12*\n" + "\x11storage_volume_id\x18\x02 \x01(\tR\x0fstorageVolumeId\x12\x1f\n" + "\vvolume_type\x18\x03 \x01(\tR\n" + - "volumeType\x12V\n" + - "\x0evolume_context\x18\x04 \x03(\v2/.ateapi.ExternalVolumeStatus.VolumeContextEntryR\rvolumeContext\x1a@\n" + + "volumeType\x12c\n" + + "\x0evolume_context\x18\x04 \x03(\v2<.substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntryR\rvolumeContext\x1a@\n" + "\x12VolumeContextEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xa1\x02\n" + - "\x05Actor\x124\n" + - "\bmetadata\x18\x01 \x01(\v2\x18.ateapi.ResourceMetadataR\bmetadata\x128\n" + - "\x0eactor_template\x18\x02 \x01(\v2\x11.ateapi.ObjectRefR\ractorTemplate\x129\n" + - "\x0fworker_selector\x18\x03 \x01(\v2\x10.ateapi.SelectorR\x0eworkerSelector\x120\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xe2\x02\n" + + "\x05Actor\x12A\n" + + "\bmetadata\x18\x01 \x01(\v2%.substrate.ateapi.v1.ResourceMetadataR\bmetadata\x12E\n" + + "\x0eactor_template\x18\x02 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\ractorTemplate\x12F\n" + + "\x0fworker_selector\x18\x03 \x01(\v2\x1d.substrate.ateapi.v1.SelectorR\x0eworkerSelector\x12=\n" + "\n" + - "source_tag\x18\x04 \x01(\v2\x11.ateapi.ObjectRefR\tsourceTag\x12+\n" + - "\x06status\x18\x05 \x01(\v2\x13.ateapi.ActorStatusR\x06status:\x0e\x82\xb5\x18\n" + - "\x18\x01\"\x06Actors\"\x8d\x01\n" + - "\fEgressPolicy\x124\n" + - "\bmetadata\x18\x01 \x01(\v2\x18.ateapi.ResourceMetadataR\bmetadata\x12(\n" + - "\x05rules\x18\x02 \x03(\v2\x12.ateapi.EgressRuleR\x05rules:\x1d\x82\xb5\x18\x19\n" + - "\x05Actor\x10\x01\"\x0eEgressPolicies\"@\n" + - "\x14EgressPolicyTemplate\x12(\n" + - "\x05rules\x18\x01 \x03(\v2\x12.ateapi.EgressRuleR\x05rules\"\xa0\x01\n" + + "source_tag\x18\x04 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\tsourceTag\x128\n" + + "\x06status\x18\x05 \x01(\v2 .substrate.ateapi.v1.ActorStatusR\x06status:\x0e\x82\xb5\x18\n" + + "\x18\x01\"\x06Actors\"\xa7\x01\n" + + "\fEgressPolicy\x12A\n" + + "\bmetadata\x18\x01 \x01(\v2%.substrate.ateapi.v1.ResourceMetadataR\bmetadata\x125\n" + + "\x05rules\x18\x02 \x03(\v2\x1f.substrate.ateapi.v1.EgressRuleR\x05rules:\x1d\x82\xb5\x18\x19\n" + + "\x05Actor\x10\x01\"\x0eEgressPolicies\"M\n" + + "\x14EgressPolicyTemplate\x125\n" + + "\x05rules\x18\x01 \x03(\v2\x1f.substrate.ateapi.v1.EgressRuleR\x05rules\"\xc7\x01\n" + "\n" + - "EgressRule\x12$\n" + - "\x04http\x18\x01 \x01(\v2\x10.ateapi.HttpRuleR\x04http\x12'\n" + - "\x05https\x18\x02 \x01(\v2\x11.ateapi.HttpsRuleR\x05https\x12C\n" + - "\x0ftls_passthrough\x18\x03 \x01(\v2\x1a.ateapi.TlsPassthroughRuleR\x0etlsPassthrough\"\x80\x01\n" + + "EgressRule\x121\n" + + "\x04http\x18\x01 \x01(\v2\x1d.substrate.ateapi.v1.HttpRuleR\x04http\x124\n" + + "\x05https\x18\x02 \x01(\v2\x1e.substrate.ateapi.v1.HttpsRuleR\x05https\x12P\n" + + "\x0ftls_passthrough\x18\x03 \x01(\v2'.substrate.ateapi.v1.TlsPassthroughRuleR\x0etlsPassthrough\"\x9a\x01\n" + "\bHttpRule\x12\x1c\n" + - "\thostnames\x18\x01 \x03(\tR\thostnames\x12#\n" + - "\x05ports\x18\x02 \x01(\v2\r.ateapi.PortsR\x05ports\x121\n" + - "\aeffects\x18\x03 \x01(\v2\x17.ateapi.HttpRuleEffectsR\aeffects\"\x81\x01\n" + + "\thostnames\x18\x01 \x03(\tR\thostnames\x120\n" + + "\x05ports\x18\x02 \x01(\v2\x1a.substrate.ateapi.v1.PortsR\x05ports\x12>\n" + + "\aeffects\x18\x03 \x01(\v2$.substrate.ateapi.v1.HttpRuleEffectsR\aeffects\"\x9b\x01\n" + "\tHttpsRule\x12\x1c\n" + - "\thostnames\x18\x01 \x03(\tR\thostnames\x12#\n" + - "\x05ports\x18\x02 \x01(\v2\r.ateapi.PortsR\x05ports\x121\n" + - "\aeffects\x18\x03 \x01(\v2\x17.ateapi.HttpRuleEffectsR\aeffects\"W\n" + + "\thostnames\x18\x01 \x03(\tR\thostnames\x120\n" + + "\x05ports\x18\x02 \x01(\v2\x1a.substrate.ateapi.v1.PortsR\x05ports\x12>\n" + + "\aeffects\x18\x03 \x01(\v2$.substrate.ateapi.v1.HttpRuleEffectsR\aeffects\"d\n" + "\x12TlsPassthroughRule\x12\x1c\n" + - "\thostnames\x18\x01 \x03(\tR\thostnames\x12#\n" + - "\x05ports\x18\x02 \x01(\v2\r.ateapi.PortsR\x05ports\"E\n" + - "\x05Ports\x12\"\n" + - "\x03all\x18\x01 \x01(\v2\x10.ateapi.AllPortsR\x03all\x12\x18\n" + + "\thostnames\x18\x01 \x03(\tR\thostnames\x120\n" + + "\x05ports\x18\x02 \x01(\v2\x1a.substrate.ateapi.v1.PortsR\x05ports\"R\n" + + "\x05Ports\x12/\n" + + "\x03all\x18\x01 \x01(\v2\x1d.substrate.ateapi.v1.AllPortsR\x03all\x12\x18\n" + "\anumbers\x18\x02 \x03(\x05R\anumbers\"\n" + "\n" + - "\bAllPorts\"T\n" + - "\x0fHttpRuleEffects\x12A\n" + - "\x0freplace_headers\x18\x01 \x03(\v2\x18.ateapi.CredentialHeaderR\x0ereplaceHeaders\"\x9e\x01\n" + + "\bAllPorts\"a\n" + + "\x0fHttpRuleEffects\x12N\n" + + "\x0freplace_headers\x18\x01 \x03(\v2%.substrate.ateapi.v1.CredentialHeaderR\x0ereplaceHeaders\"\xab\x01\n" + "\x10CredentialHeader\x12\x16\n" + "\x06header\x18\x01 \x01(\tR\x06header\x12\x16\n" + "\x06prefix\x18\x02 \x01(\tR\x06prefix\x12%\n" + - "\x0ecredential_uri\x18\x03 \x01(\tR\rcredentialUri\x123\n" + - "\tactor_jwt\x18\x04 \x01(\v2\x16.ateapi.ActorJwtSourceR\bactorJwt\"]\n" + + "\x0ecredential_uri\x18\x03 \x01(\tR\rcredentialUri\x12@\n" + + "\tactor_jwt\x18\x04 \x01(\v2#.substrate.ateapi.v1.ActorJwtSourceR\bactorJwt\"]\n" + "\x0eActorJwtSource\x12\x1c\n" + "\taudiences\x18\x01 \x03(\tR\taudiences\x12-\n" + - "\x12expiration_seconds\x18\x02 \x01(\x03R\x11expirationSeconds\"\xfb\x02\n" + - "\vActorStatus\x12(\n" + - "\x05state\x18\x01 \x01(\x0e2\x12.ateapi.ActorStateR\x05state\x12E\n" + - "\x11worker_assignment\x18\x02 \x01(\v2\x18.ateapi.WorkerAssignmentR\x10workerAssignment\x12B\n" + - "\x10external_volumes\x18\x03 \x01(\v2\x17.ateapi.ExternalVolumesR\x0fexternalVolumes\x12(\n" + - "\x05crash\x18\x04 \x01(\v2\x12.ateapi.ActorCrashR\x05crash\x12#\n" + - "\rassigned_node\x18\x05 \x01(\tR\fassignedNode\x12.\n" + - "\tsnapshots\x18\x06 \x03(\v2\x10.ateapi.SnapshotR\tsnapshots\x128\n" + + "\x12expiration_seconds\x18\x02 \x01(\x03R\x11expirationSeconds\"\xbc\x03\n" + + "\vActorStatus\x125\n" + + "\x05state\x18\x01 \x01(\x0e2\x1f.substrate.ateapi.v1.ActorStateR\x05state\x12R\n" + + "\x11worker_assignment\x18\x02 \x01(\v2%.substrate.ateapi.v1.WorkerAssignmentR\x10workerAssignment\x12O\n" + + "\x10external_volumes\x18\x03 \x01(\v2$.substrate.ateapi.v1.ExternalVolumesR\x0fexternalVolumes\x125\n" + + "\x05crash\x18\x04 \x01(\v2\x1f.substrate.ateapi.v1.ActorCrashR\x05crash\x12#\n" + + "\rassigned_node\x18\x05 \x01(\tR\fassignedNode\x12;\n" + + "\tsnapshots\x18\x06 \x03(\v2\x1d.substrate.ateapi.v1.SnapshotR\tsnapshots\x128\n" + "\x18last_assigned_generation\x18\a \x01(\x05R\x16lastAssignedGeneration\"a\n" + "\n" + "ActorCrash\x12\x18\n" + "\amessage\x18\x01 \x01(\tR\amessage\x129\n" + "\n" + - "crash_time\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\tcrashTime\"\xa4\x03\n" + - "\x10WorkerAssignment\x12)\n" + - "\x06worker\x18\x06 \x01(\v2\x11.ateapi.ObjectRefR\x06worker\x12)\n" + + "crash_time\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\tcrashTime\"\xbe\x03\n" + + "\x10WorkerAssignment\x126\n" + + "\x06worker\x18\x06 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x06worker\x12)\n" + "\x10worker_namespace\x18\x01 \x01(\tR\x0fworkerNamespace\x12\x1f\n" + "\vworker_pool\x18\x02 \x01(\tR\n" + "workerPool\x12\x1d\n" + @@ -10141,101 +10141,101 @@ const file_ateapi_proto_rawDesc = "" + "\x0eworker_pod_uid\x18\x04 \x01(\tR\fworkerPodUid\x12$\n" + "\x0eworker_pod_ips\x18\x05 \x03(\tR\fworkerPodIps\x12\x1b\n" + "\tnode_name\x18\a \x01(\tR\bnodeName\x12!\n" + - "\fworker_epoch\x18\b \x01(\x03R\vworkerEpoch\x12D\n" + - "\x0fsandbox_runtime\x18\t \x01(\v2\x1b.ateapi.ActorSandboxRuntimeR\x0esandboxRuntime\x12(\n" + + "\fworker_epoch\x18\b \x01(\x03R\vworkerEpoch\x12Q\n" + + "\x0fsandbox_runtime\x18\t \x01(\v2(.substrate.ateapi.v1.ActorSandboxRuntimeR\x0esandboxRuntime\x12(\n" + "\x10worker_spiffe_id\x18\n" + - " \x01(\tR\x0eworkerSpiffeId\"g\n" + - "\tTagStatus\x12,\n" + - "\bsnapshot\x18\x01 \x01(\v2\x10.ateapi.SnapshotR\bsnapshot\x12,\n" + - "\x12actor_template_uid\x18\x02 \x01(\tR\x10actorTemplateUid\"\xd2\x01\n" + - "\x03Tag\x124\n" + - "\bmetadata\x18\x01 \x01(\v2\x18.ateapi.ResourceMetadataR\bmetadata\x12)\n" + - "\x06status\x18\x02 \x01(\v2\x11.ateapi.TagStatusR\x06status\x12&\n" + - "\x05scope\x18\x03 \x01(\x0e2\x10.ateapi.TagScopeR\x05scope\x124\n" + - "\fsource_actor\x18\x04 \x01(\v2\x11.ateapi.ObjectRefR\vsourceActor:\f\x82\xb5\x18\b\x18\x01\"\x04Tags\"S\n" + - "\bAtespace\x124\n" + - "\bmetadata\x18\x01 \x01(\v2\x18.ateapi.ResourceMetadataR\bmetadata:\x11\x82\xb5\x18\r\x18\x02\"\tAtespaces\";\n" + + " \x01(\tR\x0eworkerSpiffeId\"t\n" + + "\tTagStatus\x129\n" + + "\bsnapshot\x18\x01 \x01(\v2\x1d.substrate.ateapi.v1.SnapshotR\bsnapshot\x12,\n" + + "\x12actor_template_uid\x18\x02 \x01(\tR\x10actorTemplateUid\"\x86\x02\n" + + "\x03Tag\x12A\n" + + "\bmetadata\x18\x01 \x01(\v2%.substrate.ateapi.v1.ResourceMetadataR\bmetadata\x126\n" + + "\x06status\x18\x02 \x01(\v2\x1e.substrate.ateapi.v1.TagStatusR\x06status\x123\n" + + "\x05scope\x18\x03 \x01(\x0e2\x1d.substrate.ateapi.v1.TagScopeR\x05scope\x12A\n" + + "\fsource_actor\x18\x04 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\vsourceActor:\f\x82\xb5\x18\b\x18\x01\"\x04Tags\"`\n" + + "\bAtespace\x12A\n" + + "\bmetadata\x18\x01 \x01(\v2%.substrate.ateapi.v1.ResourceMetadataR\bmetadata:\x11\x82\xb5\x18\r\x18\x02\"\tAtespaces\";\n" + "\tObjectRef\x12\x1a\n" + "\batespace\x18\x01 \x01(\tR\batespace\x12\x12\n" + - "\x04name\x18\x02 \x01(\tR\x04name\"\xf7\x03\n" + - "\rActorTemplate\x124\n" + - "\bmetadata\x18\x01 \x01(\v2\x18.ateapi.ResourceMetadataR\bmetadata\x129\n" + - "\x0fworker_selector\x18\x02 \x01(\v2\x10.ateapi.SelectorR\x0eworkerSelector\x121\n" + + "\x04name\x18\x02 \x01(\tR\x04name\"\xdf\x04\n" + + "\rActorTemplate\x12A\n" + + "\bmetadata\x18\x01 \x01(\v2%.substrate.ateapi.v1.ResourceMetadataR\bmetadata\x12F\n" + + "\x0fworker_selector\x18\x02 \x01(\v2\x1d.substrate.ateapi.v1.SelectorR\x0eworkerSelector\x12>\n" + "\n" + - "containers\x18\x03 \x03(\v2\x11.ateapi.ContainerR\n" + - "containers\x12(\n" + - "\avolumes\x18\x04 \x03(\v2\x0e.ateapi.VolumeR\avolumes\x12?\n" + - "\x0fsnapshot_config\x18\x05 \x01(\v2\x16.ateapi.SnapshotConfigR\x0esnapshotConfig\x12:\n" + - "\tresources\x18\x06 \x01(\v2\x1c.ateapi.ResourceRequirementsR\tresources\x12N\n" + - "\x14golden_egress_policy\x18\t \x01(\v2\x1c.ateapi.EgressPolicyTemplateR\x12goldenEgressPolicy\x123\n" + - "\x06status\x18\a \x01(\v2\x1b.ateapi.ActorTemplateStatusR\x06status:\x16\x82\xb5\x18\x12\x18\x01\"\x0eActorTemplates\"A\n" + - "\x14ResourceRequirements\x12)\n" + - "\x06limits\x18\x01 \x01(\v2\x11.ateapi.ResourcesR\x06limits\"U\n" + + "containers\x18\x03 \x03(\v2\x1e.substrate.ateapi.v1.ContainerR\n" + + "containers\x125\n" + + "\avolumes\x18\x04 \x03(\v2\x1b.substrate.ateapi.v1.VolumeR\avolumes\x12L\n" + + "\x0fsnapshot_config\x18\x05 \x01(\v2#.substrate.ateapi.v1.SnapshotConfigR\x0esnapshotConfig\x12G\n" + + "\tresources\x18\x06 \x01(\v2).substrate.ateapi.v1.ResourceRequirementsR\tresources\x12[\n" + + "\x14golden_egress_policy\x18\t \x01(\v2).substrate.ateapi.v1.EgressPolicyTemplateR\x12goldenEgressPolicy\x12@\n" + + "\x06status\x18\a \x01(\v2(.substrate.ateapi.v1.ActorTemplateStatusR\x06status:\x16\x82\xb5\x18\x12\x18\x01\"\x0eActorTemplates\"N\n" + + "\x14ResourceRequirements\x126\n" + + "\x06limits\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ResourcesR\x06limits\"U\n" + "\tResources\x12%\n" + "\x0ecpu_millicores\x18\x01 \x01(\x03R\rcpuMillicores\x12!\n" + - "\fmemory_bytes\x18\x02 \x01(\x03R\vmemoryBytes\"\xae\x01\n" + - "\x14GoldenSnapshotStatus\x120\n" + + "\fmemory_bytes\x18\x02 \x01(\x03R\vmemoryBytes\"\xbb\x01\n" + + "\x14GoldenSnapshotStatus\x12=\n" + "\n" + - "golden_tag\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\tgoldenTag\x12?\n" + + "golden_tag\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\tgoldenTag\x12?\n" + "\rsnapshot_time\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\fsnapshotTime\x12#\n" + - "\rerror_message\x18\x03 \x01(\tR\ferrorMessage\"i\n" + - "\x13ActorTemplateStatus\x12R\n" + - "\x16golden_snapshot_status\x18\x01 \x01(\v2\x1c.ateapi.GoldenSnapshotStatusR\x14goldenSnapshotStatus\"\xd8\x01\n" + + "\rerror_message\x18\x03 \x01(\tR\ferrorMessage\"v\n" + + "\x13ActorTemplateStatus\x12_\n" + + "\x16golden_snapshot_status\x18\x01 \x01(\v2).substrate.ateapi.v1.GoldenSnapshotStatusR\x14goldenSnapshotStatus\"\xf2\x01\n" + "\x0eSnapshotConfig\x12)\n" + - "\x10storage_location\x18\x01 \x01(\tR\x0fstorageLocation\x12G\n" + - "\x12preferred_fidelity\x18\x02 \x01(\x0e2\x18.ateapi.SnapshotFidelityR\x11preferredFidelity\x12R\n" + - "\x16golden_snapshot_config\x18\x03 \x01(\v2\x1c.ateapi.GoldenSnapshotConfigR\x14goldenSnapshotConfig\"F\n" + - "\x14GoldenSnapshotConfig\x12.\n" + - "\x04mode\x18\x01 \x01(\x0e2\x1a.ateapi.GoldenSnapshotModeR\x04mode\"\xf7\x02\n" + + "\x10storage_location\x18\x01 \x01(\tR\x0fstorageLocation\x12T\n" + + "\x12preferred_fidelity\x18\x02 \x01(\x0e2%.substrate.ateapi.v1.SnapshotFidelityR\x11preferredFidelity\x12_\n" + + "\x16golden_snapshot_config\x18\x03 \x01(\v2).substrate.ateapi.v1.GoldenSnapshotConfigR\x14goldenSnapshotConfig\"S\n" + + "\x14GoldenSnapshotConfig\x12;\n" + + "\x04mode\x18\x01 \x01(\x0e2'.substrate.ateapi.v1.GoldenSnapshotModeR\x04mode\"\xb8\x03\n" + "\tContainer\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" + "\x05image\x18\x02 \x01(\tR\x05image\x12\x18\n" + "\acommand\x18\x03 \x03(\tR\acommand\x12\x12\n" + - "\x04args\x18\x04 \x03(\tR\x04args\x12 \n" + - "\x03env\x18\x05 \x03(\v2\x0e.ateapi.EnvVarR\x03env\x126\n" + - "\fwakeup_probe\x18\x06 \x01(\v2\x13.ateapi.WakeupProbeR\vwakeupProbe\x128\n" + - "\rvolume_mounts\x18\a \x03(\v2\x13.ateapi.VolumeMountR\fvolumeMounts\x12B\n" + - "\x10security_context\x18\b \x01(\v2\x17.ateapi.SecurityContextR\x0fsecurityContext\x12:\n" + - "\tresources\x18\t \x01(\v2\x1c.ateapi.ResourceRequirementsR\tresources\"K\n" + - "\x0fSecurityContext\x128\n" + - "\fcapabilities\x18\x01 \x01(\v2\x14.ateapi.CapabilitiesR\fcapabilities\"4\n" + + "\x04args\x18\x04 \x03(\tR\x04args\x12-\n" + + "\x03env\x18\x05 \x03(\v2\x1b.substrate.ateapi.v1.EnvVarR\x03env\x12C\n" + + "\fwakeup_probe\x18\x06 \x01(\v2 .substrate.ateapi.v1.WakeupProbeR\vwakeupProbe\x12E\n" + + "\rvolume_mounts\x18\a \x03(\v2 .substrate.ateapi.v1.VolumeMountR\fvolumeMounts\x12O\n" + + "\x10security_context\x18\b \x01(\v2$.substrate.ateapi.v1.SecurityContextR\x0fsecurityContext\x12G\n" + + "\tresources\x18\t \x01(\v2).substrate.ateapi.v1.ResourceRequirementsR\tresources\"X\n" + + "\x0fSecurityContext\x12E\n" + + "\fcapabilities\x18\x01 \x01(\v2!.substrate.ateapi.v1.CapabilitiesR\fcapabilities\"4\n" + "\fCapabilities\x12\x10\n" + "\x03add\x18\x01 \x03(\tR\x03add\x12\x12\n" + "\x04drop\x18\x02 \x03(\tR\x04drop\"7\n" + "\x06EnvVar\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x19\n" + - "\x05value\x18\x02 \x01(\tB\x03\x80\x01\x01R\x05value\"h\n" + - "\vWakeupProbe\x120\n" + - "\bhttp_get\x18\x01 \x01(\v2\x15.ateapi.HttpGetActionR\ahttpGet\x12'\n" + + "\x05value\x18\x02 \x01(\tB\x03\x80\x01\x01R\x05value\"u\n" + + "\vWakeupProbe\x12=\n" + + "\bhttp_get\x18\x01 \x01(\v2\".substrate.ateapi.v1.HttpGetActionR\ahttpGet\x12'\n" + "\x0ftimeout_seconds\x18\x02 \x01(\x05R\x0etimeoutSeconds\"7\n" + "\rHttpGetAction\x12\x12\n" + "\x04path\x18\x01 \x01(\tR\x04path\x12\x12\n" + - "\x04port\x18\x02 \x01(\x05R\x04port\"\x89\x02\n" + + "\x04port\x18\x02 \x01(\x05R\x04port\"\xbd\x02\n" + "\x06Volume\x12\x12\n" + - "\x04name\x18\x01 \x01(\tR\x04name\x12?\n" + - "\vdurable_dir\x18\x02 \x01(\v2\x1e.ateapi.DurableDirVolumeSourceR\n" + - "durableDir\x128\n" + - "\bexternal\x18\x03 \x01(\v2\x1c.ateapi.ExternalVolumeSourceR\bexternal\x12?\n" + - "\vsystem_info\x18\x04 \x01(\v2\x1e.ateapi.SystemInfoVolumeSourceR\n" + - "systemInfo\x12/\n" + - "\x05image\x18\x05 \x01(\v2\x19.ateapi.ImageVolumeSourceR\x05image\"R\n" + - "\x14ExternalVolumeSource\x12:\n" + - "\btemplate\x18\x01 \x01(\v2\x1e.ateapi.ExternalVolumeTemplateR\btemplate\"1\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12L\n" + + "\vdurable_dir\x18\x02 \x01(\v2+.substrate.ateapi.v1.DurableDirVolumeSourceR\n" + + "durableDir\x12E\n" + + "\bexternal\x18\x03 \x01(\v2).substrate.ateapi.v1.ExternalVolumeSourceR\bexternal\x12L\n" + + "\vsystem_info\x18\x04 \x01(\v2+.substrate.ateapi.v1.SystemInfoVolumeSourceR\n" + + "systemInfo\x12<\n" + + "\x05image\x18\x05 \x01(\v2&.substrate.ateapi.v1.ImageVolumeSourceR\x05image\"_\n" + + "\x14ExternalVolumeSource\x12G\n" + + "\btemplate\x18\x01 \x01(\v2+.substrate.ateapi.v1.ExternalVolumeTemplateR\btemplate\"1\n" + "\x11ImageVolumeSource\x12\x1c\n" + "\treference\x18\x01 \x01(\tR\treference\"\x18\n" + "\x16DurableDirVolumeSource\"m\n" + "\x16ExternalVolumeTemplate\x12%\n" + "\x0ecapacity_bytes\x18\x01 \x01(\x03R\rcapacityBytes\x12,\n" + - "\x12storage_class_name\x18\x02 \x01(\tR\x10storageClassName\"Y\n" + - "\x16SystemInfoVolumeSource\x12?\n" + - "\fdata_sources\x18\x01 \x03(\v2\x1c.ateapi.SystemInfoDataSourceR\vdataSources\"\xa0\x01\n" + - "\x14SystemInfoDataSource\x12F\n" + - "\x0eactor_metadata\x18\x01 \x01(\v2\x1f.ateapi.ActorMetadataDataSourceR\ractorMetadata\x12@\n" + - "\ftrust_bundle\x18\x02 \x01(\v2\x1d.ateapi.TrustBundleDataSourceR\vtrustBundle\"J\n" + - "\x17ActorMetadataDataSource\x12/\n" + - "\x05items\x18\x01 \x03(\v2\x19.ateapi.ActorMetadataItemR\x05items\"Y\n" + - "\x11ActorMetadataItem\x120\n" + - "\x05field\x18\x01 \x01(\x0e2\x1a.ateapi.ActorMetadataFieldR\x05field\x12\x12\n" + + "\x12storage_class_name\x18\x02 \x01(\tR\x10storageClassName\"f\n" + + "\x16SystemInfoVolumeSource\x12L\n" + + "\fdata_sources\x18\x01 \x03(\v2).substrate.ateapi.v1.SystemInfoDataSourceR\vdataSources\"\xba\x01\n" + + "\x14SystemInfoDataSource\x12S\n" + + "\x0eactor_metadata\x18\x01 \x01(\v2,.substrate.ateapi.v1.ActorMetadataDataSourceR\ractorMetadata\x12M\n" + + "\ftrust_bundle\x18\x02 \x01(\v2*.substrate.ateapi.v1.TrustBundleDataSourceR\vtrustBundle\"W\n" + + "\x17ActorMetadataDataSource\x12<\n" + + "\x05items\x18\x01 \x03(\v2&.substrate.ateapi.v1.ActorMetadataItemR\x05items\"f\n" + + "\x11ActorMetadataItem\x12=\n" + + "\x05field\x18\x01 \x01(\x0e2'.substrate.ateapi.v1.ActorMetadataFieldR\x05field\x12\x12\n" + "\x04path\x18\x02 \x01(\tR\x04path\"A\n" + "\x15TrustBundleDataSource\x12\x14\n" + "\x05names\x18\x01 \x03(\tR\x05names\x12\x12\n" + @@ -10243,146 +10243,146 @@ const file_ateapi_proto_rawDesc = "" + "\vVolumeMount\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1d\n" + "\n" + - "mount_path\x18\x02 \x01(\tR\tmountPath\"E\n" + - "\x15CreateAtespaceRequest\x12,\n" + - "\batespace\x18\x01 \x01(\v2\x10.ateapi.AtespaceR\batespace\"C\n" + - "\x12GetAtespaceRequest\x12-\n" + - "\batespace\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\batespace\"E\n" + - "\x14ListAtespacesRequest\x12-\n" + - "\aoptions\x18\x01 \x01(\v2\x13.ateapi.ListOptionsR\aoptions\"o\n" + - "\x15ListAtespacesResponse\x12.\n" + - "\tatespaces\x18\x01 \x03(\v2\x10.ateapi.AtespaceR\tatespaces\x12&\n" + - "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"w\n" + - "\x15DeleteAtespaceRequest\x12-\n" + - "\batespace\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\batespace\x12/\n" + - "\aoptions\x18\x02 \x01(\v2\x15.ateapi.DeleteOptionsR\aoptions\"Z\n" + - "\x1aCreateActorTemplateRequest\x12<\n" + - "\x0eactor_template\x18\x01 \x01(\v2\x15.ateapi.ActorTemplateR\ractorTemplate\"S\n" + - "\x17GetActorTemplateRequest\x128\n" + - "\x0eactor_template\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\ractorTemplate\"f\n" + + "mount_path\x18\x02 \x01(\tR\tmountPath\"R\n" + + "\x15CreateAtespaceRequest\x129\n" + + "\batespace\x18\x01 \x01(\v2\x1d.substrate.ateapi.v1.AtespaceR\batespace\"P\n" + + "\x12GetAtespaceRequest\x12:\n" + + "\batespace\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\batespace\"R\n" + + "\x14ListAtespacesRequest\x12:\n" + + "\aoptions\x18\x01 \x01(\v2 .substrate.ateapi.v1.ListOptionsR\aoptions\"|\n" + + "\x15ListAtespacesResponse\x12;\n" + + "\tatespaces\x18\x01 \x03(\v2\x1d.substrate.ateapi.v1.AtespaceR\tatespaces\x12&\n" + + "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"\x91\x01\n" + + "\x15DeleteAtespaceRequest\x12:\n" + + "\batespace\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\batespace\x12<\n" + + "\aoptions\x18\x02 \x01(\v2\".substrate.ateapi.v1.DeleteOptionsR\aoptions\"g\n" + + "\x1aCreateActorTemplateRequest\x12I\n" + + "\x0eactor_template\x18\x01 \x01(\v2\".substrate.ateapi.v1.ActorTemplateR\ractorTemplate\"`\n" + + "\x17GetActorTemplateRequest\x12E\n" + + "\x0eactor_template\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\ractorTemplate\"s\n" + "\x19ListActorTemplatesRequest\x12\x1a\n" + - "\batespace\x18\x01 \x01(\tR\batespace\x12-\n" + - "\aoptions\x18\x02 \x01(\v2\x13.ateapi.ListOptionsR\aoptions\"\x84\x01\n" + - "\x1aListActorTemplatesResponse\x12>\n" + - "\x0factor_templates\x18\x01 \x03(\v2\x15.ateapi.ActorTemplateR\x0eactorTemplates\x12&\n" + - "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"\x87\x01\n" + - "\x1aDeleteActorTemplateRequest\x128\n" + - "\x0eactor_template\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\ractorTemplate\x12/\n" + - "\aoptions\x18\x02 \x01(\v2\x15.ateapi.DeleteOptionsR\aoptions\":\n" + - "\x0fGetActorRequest\x12'\n" + - "\x05actor\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\"9\n" + - "\x12CreateActorRequest\x12#\n" + - "\x05actor\x18\x01 \x01(\v2\r.ateapi.ActorR\x05actor\"9\n" + - "\x12UpdateActorRequest\x12#\n" + - "\x05actor\x18\x01 \x01(\v2\r.ateapi.ActorR\x05actor\"p\n" + - "\x13SuspendActorRequest\x12'\n" + - "\x05actor\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\x120\n" + - "\aoptions\x18\x02 \x01(\v2\x16.ateapi.SuspendOptionsR\aoptions\";\n" + - "\x14SuspendActorResponse\x12#\n" + - "\x05actor\x18\x01 \x01(\v2\r.ateapi.ActorR\x05actor\"<\n" + - "\x0eSuspendOptions\x12*\n" + - "\x04mode\x18\x01 \x01(\x0e2\x16.ateapi.DurabilityModeR\x04mode\"=\n" + - "\x12ResumeActorRequest\x12'\n" + - "\x05actor\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\"T\n" + - "\x13ResumeActorResponse\x12#\n" + - "\x05actor\x18\x01 \x01(\v2\r.ateapi.ActorR\x05actor\x12\x18\n" + - "\aresumed\x18\x02 \x01(\bR\aresumed\"=\n" + - "\x12RevertActorRequest\x12'\n" + - "\x05actor\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\":\n" + - "\x13RevertActorResponse\x12#\n" + - "\x05actor\x18\x01 \x01(\v2\r.ateapi.ActorR\x05actor\"n\n" + - "\x12DeleteActorRequest\x12'\n" + - "\x05actor\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\x12/\n" + - "\aoptions\x18\x02 \x01(\v2\x15.ateapi.DeleteOptionsR\aoptions\"Z\n" + - "\x1bGetActorEgressPolicyRequest\x12'\n" + - "\x05actor\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\x12\x12\n" + - "\x04name\x18\x02 \x01(\tR\x04name\"\x84\x01\n" + - "\x1eCreateActorEgressPolicyRequest\x12'\n" + - "\x05actor\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\x129\n" + - "\regress_policy\x18\x02 \x01(\v2\x14.ateapi.EgressPolicyR\fegressPolicy\"\x84\x01\n" + - "\x1eUpdateActorEgressPolicyRequest\x12'\n" + - "\x05actor\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\x129\n" + - "\regress_policy\x18\x02 \x01(\v2\x14.ateapi.EgressPolicyR\fegressPolicy\"\x8e\x01\n" + - "\x1eDeleteActorEgressPolicyRequest\x12'\n" + - "\x05actor\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\x12\x12\n" + - "\x04name\x18\x02 \x01(\tR\x04name\x12/\n" + - "\aoptions\x18\x03 \x01(\v2\x15.ateapi.DeleteOptionsR\aoptions\"4\n" + - "\rGetTagRequest\x12#\n" + - "\x03tag\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x03tag\"\x8b\x01\n" + - "\x13MintActorJwtRequest\x12'\n" + - "\x05actor\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\x12\x1c\n" + + "\batespace\x18\x01 \x01(\tR\batespace\x12:\n" + + "\aoptions\x18\x02 \x01(\v2 .substrate.ateapi.v1.ListOptionsR\aoptions\"\x91\x01\n" + + "\x1aListActorTemplatesResponse\x12K\n" + + "\x0factor_templates\x18\x01 \x03(\v2\".substrate.ateapi.v1.ActorTemplateR\x0eactorTemplates\x12&\n" + + "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"\xa1\x01\n" + + "\x1aDeleteActorTemplateRequest\x12E\n" + + "\x0eactor_template\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\ractorTemplate\x12<\n" + + "\aoptions\x18\x02 \x01(\v2\".substrate.ateapi.v1.DeleteOptionsR\aoptions\"G\n" + + "\x0fGetActorRequest\x124\n" + + "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\"F\n" + + "\x12CreateActorRequest\x120\n" + + "\x05actor\x18\x01 \x01(\v2\x1a.substrate.ateapi.v1.ActorR\x05actor\"F\n" + + "\x12UpdateActorRequest\x120\n" + + "\x05actor\x18\x01 \x01(\v2\x1a.substrate.ateapi.v1.ActorR\x05actor\"\x8a\x01\n" + + "\x13SuspendActorRequest\x124\n" + + "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12=\n" + + "\aoptions\x18\x02 \x01(\v2#.substrate.ateapi.v1.SuspendOptionsR\aoptions\"H\n" + + "\x14SuspendActorResponse\x120\n" + + "\x05actor\x18\x01 \x01(\v2\x1a.substrate.ateapi.v1.ActorR\x05actor\"I\n" + + "\x0eSuspendOptions\x127\n" + + "\x04mode\x18\x01 \x01(\x0e2#.substrate.ateapi.v1.DurabilityModeR\x04mode\"J\n" + + "\x12ResumeActorRequest\x124\n" + + "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\"a\n" + + "\x13ResumeActorResponse\x120\n" + + "\x05actor\x18\x01 \x01(\v2\x1a.substrate.ateapi.v1.ActorR\x05actor\x12\x18\n" + + "\aresumed\x18\x02 \x01(\bR\aresumed\"J\n" + + "\x12RevertActorRequest\x124\n" + + "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\"G\n" + + "\x13RevertActorResponse\x120\n" + + "\x05actor\x18\x01 \x01(\v2\x1a.substrate.ateapi.v1.ActorR\x05actor\"\x88\x01\n" + + "\x12DeleteActorRequest\x124\n" + + "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12<\n" + + "\aoptions\x18\x02 \x01(\v2\".substrate.ateapi.v1.DeleteOptionsR\aoptions\"g\n" + + "\x1bGetActorEgressPolicyRequest\x124\n" + + "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\"\x9e\x01\n" + + "\x1eCreateActorEgressPolicyRequest\x124\n" + + "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12F\n" + + "\regress_policy\x18\x02 \x01(\v2!.substrate.ateapi.v1.EgressPolicyR\fegressPolicy\"\x9e\x01\n" + + "\x1eUpdateActorEgressPolicyRequest\x124\n" + + "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12F\n" + + "\regress_policy\x18\x02 \x01(\v2!.substrate.ateapi.v1.EgressPolicyR\fegressPolicy\"\xa8\x01\n" + + "\x1eDeleteActorEgressPolicyRequest\x124\n" + + "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12<\n" + + "\aoptions\x18\x03 \x01(\v2\".substrate.ateapi.v1.DeleteOptionsR\aoptions\"A\n" + + "\rGetTagRequest\x120\n" + + "\x03tag\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x03tag\"\x98\x01\n" + + "\x13MintActorJwtRequest\x124\n" + + "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12\x1c\n" + "\taudiences\x18\x02 \x03(\tR\taudiences\x12-\n" + "\x12expiration_seconds\x18\x03 \x01(\x03R\x11expirationSeconds\"u\n" + "\x14MintActorJwtResponse\x12 \n" + "\tactor_jwt\x18\x01 \x01(\tB\x03\x80\x01\x01R\bactorJwt\x12;\n" + "\vexpire_time\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\n" + - "expireTime\"\xa3\x01\n" + - "\x1bMintActorCertificateRequest\x12'\n" + - "\x05actor\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\x12\x1b\n" + + "expireTime\"\xb0\x01\n" + + "\x1bMintActorCertificateRequest\x124\n" + + "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12\x1b\n" + "\tactor_uid\x18\x02 \x01(\tR\bactorUid\x12>\n" + "\x1bcertificate_signing_request\x18\x03 \x01(\fR\x19certificateSigningRequest\"M\n" + "\x1cMintActorCertificateResponse\x12-\n" + - "\x12actor_certificates\x18\x01 \x03(\fR\x11actorCertificates\"\\\n" + + "\x12actor_certificates\x18\x01 \x03(\fR\x11actorCertificates\"i\n" + "\x0fListTagsRequest\x12\x1a\n" + - "\batespace\x18\x01 \x01(\tR\batespace\x12-\n" + - "\aoptions\x18\x02 \x01(\v2\x13.ateapi.ListOptionsR\aoptions\"[\n" + - "\x10ListTagsResponse\x12\x1f\n" + - "\x04tags\x18\x01 \x03(\v2\v.ateapi.TagR\x04tags\x12&\n" + - "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"1\n" + - "\x10CreateTagRequest\x12\x1d\n" + - "\x03tag\x18\x01 \x01(\v2\v.ateapi.TagR\x03tag\"1\n" + - "\x10UpdateTagRequest\x12\x1d\n" + - "\x03tag\x18\x01 \x01(\v2\v.ateapi.TagR\x03tag\"h\n" + - "\x10DeleteTagRequest\x12#\n" + - "\x03tag\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x03tag\x12/\n" + - "\aoptions\x18\x02 \x01(\v2\x15.ateapi.DeleteOptionsR\aoptions\";\n" + + "\batespace\x18\x01 \x01(\tR\batespace\x12:\n" + + "\aoptions\x18\x02 \x01(\v2 .substrate.ateapi.v1.ListOptionsR\aoptions\"h\n" + + "\x10ListTagsResponse\x12,\n" + + "\x04tags\x18\x01 \x03(\v2\x18.substrate.ateapi.v1.TagR\x04tags\x12&\n" + + "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\">\n" + + "\x10CreateTagRequest\x12*\n" + + "\x03tag\x18\x01 \x01(\v2\x18.substrate.ateapi.v1.TagR\x03tag\">\n" + + "\x10UpdateTagRequest\x12*\n" + + "\x03tag\x18\x01 \x01(\v2\x18.substrate.ateapi.v1.TagR\x03tag\"\x82\x01\n" + + "\x10DeleteTagRequest\x120\n" + + "\x03tag\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x03tag\x12<\n" + + "\aoptions\x18\x02 \x01(\v2\".substrate.ateapi.v1.DeleteOptionsR\aoptions\";\n" + "\rDeleteOptions\x12\x18\n" + "\aversion\x18\x01 \x01(\x03R\aversion\x12\x10\n" + "\x03uid\x18\x02 \x01(\tR\x03uid\"I\n" + "\vListOptions\x12\x1b\n" + "\tpage_size\x18\x01 \x01(\x05R\bpageSize\x12\x1d\n" + "\n" + - "page_token\x18\x02 \x01(\tR\tpageToken\"}\n" + - "!ListWorkerActorAssignmentsRequest\x12)\n" + - "\x06worker\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x06worker\x12-\n" + - "\aoptions\x18\x02 \x01(\v2\x13.ateapi.ListOptionsR\aoptions\"\x92\x01\n" + - "\"ListWorkerActorAssignmentsResponse\x12D\n" + - "\x11actor_assignments\x18\x01 \x03(\v2\x17.ateapi.ActorAssignmentR\x10actorAssignments\x12&\n" + - "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"C\n" + - "\x12ListWorkersRequest\x12-\n" + - "\aoptions\x18\x01 \x01(\v2\x13.ateapi.ListOptionsR\aoptions\"g\n" + - "\x13ListWorkersResponse\x12(\n" + - "\aworkers\x18\x01 \x03(\v2\x0e.ateapi.WorkerR\aworkers\x12&\n" + - "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"=\n" + - "\x10GetWorkerRequest\x12)\n" + - "\x06worker\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x06worker\"=\n" + - "\x13CreateWorkerRequest\x12&\n" + - "\x06worker\x18\x01 \x01(\v2\x0e.ateapi.WorkerR\x06worker\"=\n" + - "\x13UpdateWorkerRequest\x12&\n" + - "\x06worker\x18\x01 \x01(\v2\x0e.ateapi.WorkerR\x06worker\"q\n" + - "\x13DeleteWorkerRequest\x12)\n" + - "\x06worker\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x06worker\x12/\n" + - "\aoptions\x18\x02 \x01(\v2\x15.ateapi.DeleteOptionsR\aoptions\"?\n" + - "\x12DrainWorkerRequest\x12)\n" + - "\x06worker\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x06worker\"=\n" + - "\x13DrainWorkerResponse\x12&\n" + - "\x06worker\x18\x01 \x01(\v2\x0e.ateapi.WorkerR\x06worker\"G\n" + - "\x1aMarkWorkerAvailableRequest\x12)\n" + - "\x06worker\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x06worker\"E\n" + - "\x1bMarkWorkerAvailableResponse\x12&\n" + - "\x06worker\x18\x01 \x01(\v2\x0e.ateapi.WorkerR\x06worker\"I\n" + - "\x1cMarkWorkerUnavailableRequest\x12)\n" + - "\x06worker\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x06worker\"G\n" + - "\x1dMarkWorkerUnavailableResponse\x12&\n" + - "\x06worker\x18\x01 \x01(\v2\x0e.ateapi.WorkerR\x06worker\"^\n" + + "page_token\x18\x02 \x01(\tR\tpageToken\"\x97\x01\n" + + "!ListWorkerActorAssignmentsRequest\x126\n" + + "\x06worker\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x06worker\x12:\n" + + "\aoptions\x18\x02 \x01(\v2 .substrate.ateapi.v1.ListOptionsR\aoptions\"\x9f\x01\n" + + "\"ListWorkerActorAssignmentsResponse\x12Q\n" + + "\x11actor_assignments\x18\x01 \x03(\v2$.substrate.ateapi.v1.ActorAssignmentR\x10actorAssignments\x12&\n" + + "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"P\n" + + "\x12ListWorkersRequest\x12:\n" + + "\aoptions\x18\x01 \x01(\v2 .substrate.ateapi.v1.ListOptionsR\aoptions\"t\n" + + "\x13ListWorkersResponse\x125\n" + + "\aworkers\x18\x01 \x03(\v2\x1b.substrate.ateapi.v1.WorkerR\aworkers\x12&\n" + + "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"J\n" + + "\x10GetWorkerRequest\x126\n" + + "\x06worker\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x06worker\"J\n" + + "\x13CreateWorkerRequest\x123\n" + + "\x06worker\x18\x01 \x01(\v2\x1b.substrate.ateapi.v1.WorkerR\x06worker\"J\n" + + "\x13UpdateWorkerRequest\x123\n" + + "\x06worker\x18\x01 \x01(\v2\x1b.substrate.ateapi.v1.WorkerR\x06worker\"\x8b\x01\n" + + "\x13DeleteWorkerRequest\x126\n" + + "\x06worker\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x06worker\x12<\n" + + "\aoptions\x18\x02 \x01(\v2\".substrate.ateapi.v1.DeleteOptionsR\aoptions\"L\n" + + "\x12DrainWorkerRequest\x126\n" + + "\x06worker\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x06worker\"J\n" + + "\x13DrainWorkerResponse\x123\n" + + "\x06worker\x18\x01 \x01(\v2\x1b.substrate.ateapi.v1.WorkerR\x06worker\"T\n" + + "\x1aMarkWorkerAvailableRequest\x126\n" + + "\x06worker\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x06worker\"R\n" + + "\x1bMarkWorkerAvailableResponse\x123\n" + + "\x06worker\x18\x01 \x01(\v2\x1b.substrate.ateapi.v1.WorkerR\x06worker\"V\n" + + "\x1cMarkWorkerUnavailableRequest\x126\n" + + "\x06worker\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x06worker\"T\n" + + "\x1dMarkWorkerUnavailableResponse\x123\n" + + "\x06worker\x18\x01 \x01(\v2\x1b.substrate.ateapi.v1.WorkerR\x06worker\"k\n" + "\x11ListActorsRequest\x12\x1a\n" + - "\batespace\x18\x01 \x01(\tR\batespace\x12-\n" + - "\aoptions\x18\x02 \x01(\v2\x13.ateapi.ListOptionsR\aoptions\"c\n" + - "\x12ListActorsResponse\x12%\n" + - "\x06actors\x18\x01 \x03(\v2\r.ateapi.ActorR\x06actors\x12&\n" + - "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"\xc4\x03\n" + - "\x06Worker\x124\n" + - "\bmetadata\x18\x01 \x01(\v2\x18.ateapi.ResourceMetadataR\bmetadata\x12)\n" + + "\batespace\x18\x01 \x01(\tR\batespace\x12:\n" + + "\aoptions\x18\x02 \x01(\v2 .substrate.ateapi.v1.ListOptionsR\aoptions\"p\n" + + "\x12ListActorsResponse\x122\n" + + "\x06actors\x18\x01 \x03(\v2\x1a.substrate.ateapi.v1.ActorR\x06actors\x12&\n" + + "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"\xeb\x03\n" + + "\x06Worker\x12A\n" + + "\bmetadata\x18\x01 \x01(\v2%.substrate.ateapi.v1.ResourceMetadataR\bmetadata\x12)\n" + "\x10worker_namespace\x18\x02 \x01(\tR\x0fworkerNamespace\x12\x1f\n" + "\vworker_pool\x18\x03 \x01(\tR\n" + "workerPool\x12\x1d\n" + @@ -10390,34 +10390,34 @@ const file_ateapi_proto_rawDesc = "" + "worker_pod\x18\x04 \x01(\tR\tworkerPod\x12$\n" + "\x0eworker_pod_uid\x18\x05 \x01(\tR\fworkerPodUid\x12\x1b\n" + "\tnode_name\x18\x06 \x01(\tR\bnodeName\x12(\n" + - "\x10worker_spiffe_id\x18\a \x01(\tR\x0eworkerSpiffeId\x122\n" + - "\x06labels\x18\b \x03(\v2\x1a.ateapi.Worker.LabelsEntryR\x06labels\x12,\n" + - "\x06status\x18\t \x01(\v2\x14.ateapi.WorkerStatusR\x06status\x1a9\n" + + "\x10worker_spiffe_id\x18\a \x01(\tR\x0eworkerSpiffeId\x12?\n" + + "\x06labels\x18\b \x03(\v2'.substrate.ateapi.v1.Worker.LabelsEntryR\x06labels\x129\n" + + "\x06status\x18\t \x01(\v2!.substrate.ateapi.v1.WorkerStatusR\x06status\x1a9\n" + "\vLabelsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01:\x0f\x82\xb5\x18\v\x18\x02\"\aWorkers\"\xf1\x02\n" + - "\fWorkerStatus\x12)\n" + - "\x05state\x18\x01 \x01(\x0e2\x13.ateapi.WorkerStateR\x05state\x123\n" + - "\bcapacity\x18\x02 \x01(\v2\x17.ateapi.WorkerResourcesR\bcapacity\x125\n" + - "\tallocated\x18\x03 \x01(\v2\x17.ateapi.WorkerResourcesR\tallocated\x12%\n" + - "\x0eobserved_epoch\x18\x04 \x01(\x03R\robservedEpoch\x12C\n" + - "\x0fsandbox_classes\x18\x05 \x03(\v2\x1a.ateapi.WorkerSandboxClassR\x0esandboxClasses\x12\x10\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01:\x0f\x82\xb5\x18\v\x18\x02\"\aWorkers\"\xa5\x03\n" + + "\fWorkerStatus\x126\n" + + "\x05state\x18\x01 \x01(\x0e2 .substrate.ateapi.v1.WorkerStateR\x05state\x12@\n" + + "\bcapacity\x18\x02 \x01(\v2$.substrate.ateapi.v1.WorkerResourcesR\bcapacity\x12B\n" + + "\tallocated\x18\x03 \x01(\v2$.substrate.ateapi.v1.WorkerResourcesR\tallocated\x12%\n" + + "\x0eobserved_epoch\x18\x04 \x01(\x03R\robservedEpoch\x12P\n" + + "\x0fsandbox_classes\x18\x05 \x03(\v2'.substrate.ateapi.v1.WorkerSandboxClassR\x0esandboxClasses\x12\x10\n" + "\x03ips\x18\x06 \x03(\tR\x03ips\x12!\n" + "\fissued_epoch\x18\a \x01(\x03R\vissuedEpoch\x12)\n" + - "\x10registered_epoch\x18\b \x01(\x03R\x0fregisteredEpoch\"\xcf\x01\n" + + "\x10registered_epoch\x18\b \x01(\x03R\x0fregisteredEpoch\"\xe9\x01\n" + "\x12WorkerSandboxClass\x12#\n" + - "\rsandbox_class\x18\x01 \x01(\tR\fsandboxClass\x12E\n" + - "\x0fdefault_runtime\x18\x02 \x01(\v2\x1c.ateapi.WorkerSandboxRuntimeR\x0edefaultRuntime\x12M\n" + - "\x13restorable_runtimes\x18\x03 \x03(\v2\x1c.ateapi.WorkerSandboxRuntimeR\x12restorableRuntimes\"P\n" + - "\x14WorkerSandboxRuntime\x128\n" + - "\aversion\x18\x01 \x01(\v2\x1e.ateapi.VersionedSandboxCompatR\aversion\"t\n" + + "\rsandbox_class\x18\x01 \x01(\tR\fsandboxClass\x12R\n" + + "\x0fdefault_runtime\x18\x02 \x01(\v2).substrate.ateapi.v1.WorkerSandboxRuntimeR\x0edefaultRuntime\x12Z\n" + + "\x13restorable_runtimes\x18\x03 \x03(\v2).substrate.ateapi.v1.WorkerSandboxRuntimeR\x12restorableRuntimes\"]\n" + + "\x14WorkerSandboxRuntime\x12E\n" + + "\aversion\x18\x01 \x01(\v2+.substrate.ateapi.v1.VersionedSandboxCompatR\aversion\"\x81\x01\n" + "\x13ActorSandboxRuntime\x12#\n" + - "\rsandbox_class\x18\x01 \x01(\tR\fsandboxClass\x128\n" + - "\aversion\x18\x02 \x01(\v2\x1e.ateapi.VersionedSandboxCompatR\aversion\"w\n" + + "\rsandbox_class\x18\x01 \x01(\tR\fsandboxClass\x12E\n" + + "\aversion\x18\x02 \x01(\v2+.substrate.ateapi.v1.VersionedSandboxCompatR\aversion\"\x84\x01\n" + "\x16VersionedSandboxCompat\x12%\n" + - "\x0eschema_version\x18\x01 \x01(\tR\rschemaVersion\x126\n" + + "\x0eschema_version\x18\x01 \x01(\tR\rschemaVersion\x12C\n" + "\n" + - "attributes\x18\x02 \x03(\v2\x16.ateapi.AttributeEntryR\n" + + "attributes\x18\x02 \x03(\v2#.substrate.ateapi.v1.AttributeEntryR\n" + "attributes\"8\n" + "\x0eAttributeEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + @@ -10425,108 +10425,108 @@ const file_ateapi_proto_rawDesc = "" + "\x0fWorkerResources\x12%\n" + "\x0ecpu_millicores\x18\x01 \x01(\x03R\rcpuMillicores\x12!\n" + "\fmemory_bytes\x18\x02 \x01(\x03R\vmemoryBytes\x12\x16\n" + - "\x06actors\x18\x03 \x01(\x05R\x06actors\"\xde\x01\n" + - "\x0fActorAssignment\x124\n" + - "\bmetadata\x18\x01 \x01(\v2\x18.ateapi.ResourceMetadataR\bmetadata\x12'\n" + - "\x05actor\x18\x02 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\x12\x1b\n" + - "\tactor_uid\x18\x03 \x01(\tR\bactorUid\x12/\n" + - "\tresources\x18\x04 \x01(\v2\x11.ateapi.ResourcesR\tresources:\x1e\x82\xb5\x18\x1a\n" + - "\x06Worker\"\x10ActorAssignments\"F\n" + - "\x19AcquireWorkerEpochRequest\x12)\n" + - "\x06worker\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x06worker\"2\n" + + "\x06actors\x18\x03 \x01(\x05R\x06actors\"\x85\x02\n" + + "\x0fActorAssignment\x12A\n" + + "\bmetadata\x18\x01 \x01(\v2%.substrate.ateapi.v1.ResourceMetadataR\bmetadata\x124\n" + + "\x05actor\x18\x02 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12\x1b\n" + + "\tactor_uid\x18\x03 \x01(\tR\bactorUid\x12<\n" + + "\tresources\x18\x04 \x01(\v2\x1e.substrate.ateapi.v1.ResourcesR\tresources:\x1e\x82\xb5\x18\x1a\n" + + "\x06Worker\"\x10ActorAssignments\"S\n" + + "\x19AcquireWorkerEpochRequest\x126\n" + + "\x06worker\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x06worker\"2\n" + "\x1aAcquireWorkerEpochResponse\x12\x14\n" + - "\x05epoch\x18\x01 \x01(\x03R\x05epoch\"\x9f\x01\n" + - "\x15RegisterWorkerRequest\x12)\n" + - "\x06worker\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x06worker\x12\x14\n" + + "\x05epoch\x18\x01 \x01(\x03R\x05epoch\"\xb9\x01\n" + + "\x15RegisterWorkerRequest\x126\n" + + "\x06worker\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x06worker\x12\x14\n" + "\x05epoch\x18\x03 \x01(\x03R\x05epoch\x12\x10\n" + - "\x03ips\x18\x04 \x03(\tR\x03ips\x123\n" + - "\bcapacity\x18\x02 \x01(\v2\x17.ateapi.WorkerResourcesR\bcapacity\"@\n" + - "\x16RegisterWorkerResponse\x12&\n" + - "\x06worker\x18\x01 \x01(\v2\x0e.ateapi.WorkerR\x06worker\"\xa7\x01\n" + - "\x1fSetWorkerSandboxRuntimesRequest\x12)\n" + - "\x06worker\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x06worker\x12\x14\n" + - "\x05epoch\x18\x02 \x01(\x03R\x05epoch\x12C\n" + - "\x0fsandbox_classes\x18\x03 \x03(\v2\x1a.ateapi.WorkerSandboxClassR\x0esandboxClasses\"J\n" + - " SetWorkerSandboxRuntimesResponse\x12&\n" + - "\x06worker\x18\x01 \x01(\v2\x0e.ateapi.WorkerR\x06worker\"\xd4\x01\n" + - "!MintWorkerActorCertificateRequest\x12'\n" + - "\x05actor\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\x12\x1b\n" + + "\x03ips\x18\x04 \x03(\tR\x03ips\x12@\n" + + "\bcapacity\x18\x02 \x01(\v2$.substrate.ateapi.v1.WorkerResourcesR\bcapacity\"M\n" + + "\x16RegisterWorkerResponse\x123\n" + + "\x06worker\x18\x01 \x01(\v2\x1b.substrate.ateapi.v1.WorkerR\x06worker\"\xc1\x01\n" + + "\x1fSetWorkerSandboxRuntimesRequest\x126\n" + + "\x06worker\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x06worker\x12\x14\n" + + "\x05epoch\x18\x02 \x01(\x03R\x05epoch\x12P\n" + + "\x0fsandbox_classes\x18\x03 \x03(\v2'.substrate.ateapi.v1.WorkerSandboxClassR\x0esandboxClasses\"W\n" + + " SetWorkerSandboxRuntimesResponse\x123\n" + + "\x06worker\x18\x01 \x01(\v2\x1b.substrate.ateapi.v1.WorkerR\x06worker\"\xee\x01\n" + + "!MintWorkerActorCertificateRequest\x124\n" + + "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12\x1b\n" + "\tactor_uid\x18\x02 \x01(\tR\bactorUid\x12>\n" + - "\x1bcertificate_signing_request\x18\x03 \x01(\fR\x19certificateSigningRequest\x12)\n" + - "\x06worker\x18\x04 \x01(\v2\x11.ateapi.ObjectRefR\x06worker\"S\n" + + "\x1bcertificate_signing_request\x18\x03 \x01(\fR\x19certificateSigningRequest\x126\n" + + "\x06worker\x18\x04 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x06worker\"S\n" + "\"MintWorkerActorCertificateResponse\x12-\n" + - "\x12actor_certificates\x18\x01 \x03(\fR\x11actorCertificates\"\x7f\n" + - "\x19MintWorkerActorJwtRequest\x12'\n" + - "\x05actor\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\x12\x1b\n" + + "\x12actor_certificates\x18\x01 \x03(\fR\x11actorCertificates\"\x8c\x01\n" + + "\x19MintWorkerActorJwtRequest\x124\n" + + "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12\x1b\n" + "\tactor_uid\x18\x02 \x01(\tR\bactorUid\x12\x1c\n" + "\taudiences\x18\x03 \x03(\tR\taudiences\"{\n" + "\x1aMintWorkerActorJwtResponse\x12 \n" + "\tactor_jwt\x18\x01 \x01(\tB\x03\x80\x01\x01R\bactorJwt\x12;\n" + "\vexpire_time\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\n" + - "expireTime\"\x8d\x01\n" + - "\x1aRequestActorSuspendRequest\x12)\n" + - "\x06worker\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x06worker\x12'\n" + - "\x05actor\x18\x02 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\x12\x1b\n" + - "\tactor_uid\x18\x03 \x01(\tR\bactorUid\"B\n" + - "\x1bRequestActorSuspendResponse\x12#\n" + - "\x05actor\x18\x01 \x01(\v2\r.ateapi.ActorR\x05actor\"\xa6\x01\n" + - "\x19ReportActorCrashedRequest\x12)\n" + - "\x06worker\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x06worker\x12'\n" + - "\x05actor\x18\x02 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\x12\x1b\n" + + "expireTime\"\xa7\x01\n" + + "\x1aRequestActorSuspendRequest\x126\n" + + "\x06worker\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x06worker\x124\n" + + "\x05actor\x18\x02 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12\x1b\n" + + "\tactor_uid\x18\x03 \x01(\tR\bactorUid\"O\n" + + "\x1bRequestActorSuspendResponse\x120\n" + + "\x05actor\x18\x01 \x01(\v2\x1a.substrate.ateapi.v1.ActorR\x05actor\"\xc0\x01\n" + + "\x19ReportActorCrashedRequest\x126\n" + + "\x06worker\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x06worker\x124\n" + + "\x05actor\x18\x02 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12\x1b\n" + "\tactor_uid\x18\x03 \x01(\tR\bactorUid\x12\x18\n" + - "\amessage\x18\x04 \x01(\tR\amessage\"A\n" + - "\x1aReportActorCrashedResponse\x12#\n" + - "\x05actor\x18\x01 \x01(\v2\r.ateapi.ActorR\x05actor\"\x99\x01\n" + - "\x1fReportActorSnapshotStateRequest\x12'\n" + - "\x05actor\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x05actor\x12\x1b\n" + - "\tactor_uid\x18\x02 \x01(\tR\bactorUid\x120\n" + - "\x05state\x18\x03 \x01(\v2\x1a.ateapi.ActorSnapshotStateR\x05state\"\"\n" + - " ReportActorSnapshotStateResponse\"\x88\x02\n" + - "\x12ActorSnapshotState\x129\n" + - "\flatest_local\x18\x01 \x01(\v2\x16.ateapi.SnapshotReportR\vlatestLocal\x124\n" + - "\tuploading\x18\x02 \x01(\v2\x16.ateapi.SnapshotReportR\tuploading\x12=\n" + - "\x0elatest_durable\x18\x03 \x01(\v2\x16.ateapi.SnapshotReportR\rlatestDurable\x12B\n" + - "\x0fupload_due_time\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\ruploadDueTime\"\xc2\x02\n" + + "\amessage\x18\x04 \x01(\tR\amessage\"N\n" + + "\x1aReportActorCrashedResponse\x120\n" + + "\x05actor\x18\x01 \x01(\v2\x1a.substrate.ateapi.v1.ActorR\x05actor\"\xb3\x01\n" + + "\x1fReportActorSnapshotStateRequest\x124\n" + + "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12\x1b\n" + + "\tactor_uid\x18\x02 \x01(\tR\bactorUid\x12=\n" + + "\x05state\x18\x03 \x01(\v2'.substrate.ateapi.v1.ActorSnapshotStateR\x05state\"\"\n" + + " ReportActorSnapshotStateResponse\"\xaf\x02\n" + + "\x12ActorSnapshotState\x12F\n" + + "\flatest_local\x18\x01 \x01(\v2#.substrate.ateapi.v1.SnapshotReportR\vlatestLocal\x12A\n" + + "\tuploading\x18\x02 \x01(\v2#.substrate.ateapi.v1.SnapshotReportR\tuploading\x12J\n" + + "\x0elatest_durable\x18\x03 \x01(\v2#.substrate.ateapi.v1.SnapshotReportR\rlatestDurable\x12B\n" + + "\x0fupload_due_time\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\ruploadDueTime\"\xdc\x02\n" + "\x0eSnapshotReport\x12\x12\n" + "\x04uuid\x18\x01 \x01(\tR\x04uuid\x12\x1e\n" + "\n" + "generation\x18\x02 \x01(\x05R\n" + - "generation\x124\n" + - "\bfidelity\x18\x03 \x01(\x0e2\x18.ateapi.SnapshotFidelityR\bfidelity\x12.\n" + - "\x06object\x18\x04 \x01(\v2\x16.ateapi.ObjectSnapshotR\x06object\x12F\n" + + "generation\x12A\n" + + "\bfidelity\x18\x03 \x01(\x0e2%.substrate.ateapi.v1.SnapshotFidelityR\bfidelity\x12;\n" + + "\x06object\x18\x04 \x01(\v2#.substrate.ateapi.v1.ObjectSnapshotR\x06object\x12F\n" + "\x11local_commit_time\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\x0flocalCommitTime\x12N\n" + - "\x15durable_complete_time\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\x13durableCompleteTime\"\x9b\x01\n" + - "\fAccessPolicy\x124\n" + - "\bmetadata\x18\x01 \x01(\v2\x18.ateapi.ResourceMetadataR\bmetadata\x12+\n" + - "\bbindings\x18\x02 \x03(\v2\x0f.ateapi.BindingR\bbindings:(\x82\xb5\x18$\n" + + "\x15durable_complete_time\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\x13durableCompleteTime\"\xb5\x01\n" + + "\fAccessPolicy\x12A\n" + + "\bmetadata\x18\x01 \x01(\v2%.substrate.ateapi.v1.ResourceMetadataR\bmetadata\x128\n" + + "\bbindings\x18\x02 \x03(\v2\x1c.substrate.ateapi.v1.BindingR\bbindings:(\x82\xb5\x18$\n" + "\x06Global\n" + "\bAtespace\x10\x01\"\x0eAccessPolicies\"7\n" + "\aBinding\x12\x12\n" + "\x04role\x18\x01 \x01(\tR\x04role\x12\x18\n" + "\amembers\x18\x02 \x03(\tR\amembers\"2\n" + "\x1cGetGlobalAccessPolicyRequest\x12\x12\n" + - "\x04name\x18\x01 \x01(\tR\x04name\"\\\n" + - "\x1fCreateGlobalAccessPolicyRequest\x129\n" + - "\raccess_policy\x18\x01 \x01(\v2\x14.ateapi.AccessPolicyR\faccessPolicy\"\\\n" + - "\x1fUpdateGlobalAccessPolicyRequest\x129\n" + - "\raccess_policy\x18\x01 \x01(\v2\x14.ateapi.AccessPolicyR\faccessPolicy\"c\n" + - "\x1eGetAtespaceAccessPolicyRequest\x12-\n" + - "\batespace\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\batespace\x12\x12\n" + - "\x04name\x18\x02 \x01(\tR\x04name\"\x8d\x01\n" + - "!CreateAtespaceAccessPolicyRequest\x12-\n" + - "\batespace\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\batespace\x129\n" + - "\raccess_policy\x18\x02 \x01(\v2\x14.ateapi.AccessPolicyR\faccessPolicy\"\x8d\x01\n" + - "!UpdateAtespaceAccessPolicyRequest\x12-\n" + - "\batespace\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\batespace\x129\n" + - "\raccess_policy\x18\x02 \x01(\v2\x14.ateapi.AccessPolicyR\faccessPolicy\"\x97\x01\n" + - "!DeleteAtespaceAccessPolicyRequest\x12-\n" + - "\batespace\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\batespace\x12\x12\n" + - "\x04name\x18\x02 \x01(\tR\x04name\x12/\n" + - "\aoptions\x18\x03 \x01(\v2\x15.ateapi.DeleteOptionsR\aoptions\"\x89\x01\n" + + "\x04name\x18\x01 \x01(\tR\x04name\"i\n" + + "\x1fCreateGlobalAccessPolicyRequest\x12F\n" + + "\raccess_policy\x18\x01 \x01(\v2!.substrate.ateapi.v1.AccessPolicyR\faccessPolicy\"i\n" + + "\x1fUpdateGlobalAccessPolicyRequest\x12F\n" + + "\raccess_policy\x18\x01 \x01(\v2!.substrate.ateapi.v1.AccessPolicyR\faccessPolicy\"p\n" + + "\x1eGetAtespaceAccessPolicyRequest\x12:\n" + + "\batespace\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\batespace\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\"\xa7\x01\n" + + "!CreateAtespaceAccessPolicyRequest\x12:\n" + + "\batespace\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\batespace\x12F\n" + + "\raccess_policy\x18\x02 \x01(\v2!.substrate.ateapi.v1.AccessPolicyR\faccessPolicy\"\xa7\x01\n" + + "!UpdateAtespaceAccessPolicyRequest\x12:\n" + + "\batespace\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\batespace\x12F\n" + + "\raccess_policy\x18\x02 \x01(\v2!.substrate.ateapi.v1.AccessPolicyR\faccessPolicy\"\xb1\x01\n" + + "!DeleteAtespaceAccessPolicyRequest\x12:\n" + + "\batespace\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\batespace\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12<\n" + + "\aoptions\x18\x03 \x01(\v2\".substrate.ateapi.v1.DeleteOptionsR\aoptions\"\x96\x01\n" + "\x12ResourceAnnotation\x12\x18\n" + "\aparents\x18\x01 \x03(\tR\aparents\x12\x1c\n" + - "\tsingleton\x18\x02 \x01(\bR\tsingleton\x12#\n" + - "\x05scope\x18\x03 \x01(\x0e2\r.ateapi.ScopeR\x05scope\x12\x16\n" + + "\tsingleton\x18\x02 \x01(\bR\tsingleton\x120\n" + + "\x05scope\x18\x03 \x01(\x0e2\x1a.substrate.ateapi.v1.ScopeR\x05scope\x12\x16\n" + "\x06plural\x18\x04 \x01(\tR\x06plural\".\n" + "\x10MethodAnnotation\x12\x1a\n" + "\bresource\x18\x01 \x01(\tR\bresource*a\n" + @@ -10578,582 +10578,582 @@ const file_ateapi_proto_rawDesc = "" + "\x05Scope\x12\x15\n" + "\x11SCOPE_UNSPECIFIED\x10\x00\x12\x12\n" + "\x0eSCOPE_ATESPACE\x10\x01\x12\x10\n" + - "\fSCOPE_GLOBAL\x10\x022\xe9\x1e\n" + - "\aControl\x12?\n" + - "\bGetActor\x12\x17.ateapi.GetActorRequest\x1a\r.ateapi.Actor\"\v\x82\xb5\x18\a\n" + - "\x05Actor\x12E\n" + - "\vCreateActor\x12\x1a.ateapi.CreateActorRequest\x1a\r.ateapi.Actor\"\v\x82\xb5\x18\a\n" + - "\x05Actor\x12E\n" + - "\vUpdateActor\x12\x1a.ateapi.UpdateActorRequest\x1a\r.ateapi.Actor\"\v\x82\xb5\x18\a\n" + - "\x05Actor\x12V\n" + - "\fSuspendActor\x12\x1b.ateapi.SuspendActorRequest\x1a\x1c.ateapi.SuspendActorResponse\"\v\x82\xb5\x18\a\n" + - "\x05Actor\x12S\n" + - "\vResumeActor\x12\x1a.ateapi.ResumeActorRequest\x1a\x1b.ateapi.ResumeActorResponse\"\v\x82\xb5\x18\a\n" + - "\x05Actor\x12S\n" + - "\vRevertActor\x12\x1a.ateapi.RevertActorRequest\x1a\x1b.ateapi.RevertActorResponse\"\v\x82\xb5\x18\a\n" + - "\x05Actor\x12E\n" + - "\vDeleteActor\x12\x1a.ateapi.DeleteActorRequest\x1a\r.ateapi.Actor\"\v\x82\xb5\x18\a\n" + - "\x05Actor\x12e\n" + - "\x14GetActorEgressPolicy\x12#.ateapi.GetActorEgressPolicyRequest\x1a\x14.ateapi.EgressPolicy\"\x12\x82\xb5\x18\x0e\n" + - "\fEgressPolicy\x12k\n" + - "\x17CreateActorEgressPolicy\x12&.ateapi.CreateActorEgressPolicyRequest\x1a\x14.ateapi.EgressPolicy\"\x12\x82\xb5\x18\x0e\n" + - "\fEgressPolicy\x12k\n" + - "\x17UpdateActorEgressPolicy\x12&.ateapi.UpdateActorEgressPolicyRequest\x1a\x14.ateapi.EgressPolicy\"\x12\x82\xb5\x18\x0e\n" + - "\fEgressPolicy\x12k\n" + - "\x17DeleteActorEgressPolicy\x12&.ateapi.DeleteActorEgressPolicyRequest\x1a\x14.ateapi.EgressPolicy\"\x12\x82\xb5\x18\x0e\n" + - "\fEgressPolicy\x12V\n" + - "\fMintActorJwt\x12\x1b.ateapi.MintActorJwtRequest\x1a\x1c.ateapi.MintActorJwtResponse\"\v\x82\xb5\x18\a\n" + - "\x05Actor\x12n\n" + - "\x14MintActorCertificate\x12#.ateapi.MintActorCertificateRequest\x1a$.ateapi.MintActorCertificateResponse\"\v\x82\xb5\x18\a\n" + - "\x05Actor\x12=\n" + - "\tCreateTag\x12\x18.ateapi.CreateTagRequest\x1a\v.ateapi.Tag\"\t\x82\xb5\x18\x05\n" + - "\x03Tag\x127\n" + - "\x06GetTag\x12\x15.ateapi.GetTagRequest\x1a\v.ateapi.Tag\"\t\x82\xb5\x18\x05\n" + - "\x03Tag\x12H\n" + - "\bListTags\x12\x17.ateapi.ListTagsRequest\x1a\x18.ateapi.ListTagsResponse\"\t\x82\xb5\x18\x05\n" + - "\x03Tag\x12=\n" + - "\tUpdateTag\x12\x18.ateapi.UpdateTagRequest\x1a\v.ateapi.Tag\"\t\x82\xb5\x18\x05\n" + - "\x03Tag\x12=\n" + - "\tDeleteTag\x12\x18.ateapi.DeleteTagRequest\x1a\v.ateapi.Tag\"\t\x82\xb5\x18\x05\n" + - "\x03Tag\x12T\n" + - "\vListWorkers\x12\x1a.ateapi.ListWorkersRequest\x1a\x1b.ateapi.ListWorkersResponse\"\f\x82\xb5\x18\b\n" + - "\x06Worker\x12C\n" + - "\tGetWorker\x12\x18.ateapi.GetWorkerRequest\x1a\x0e.ateapi.Worker\"\f\x82\xb5\x18\b\n" + - "\x06Worker\x12I\n" + - "\fCreateWorker\x12\x1b.ateapi.CreateWorkerRequest\x1a\x0e.ateapi.Worker\"\f\x82\xb5\x18\b\n" + - "\x06Worker\x12I\n" + - "\fUpdateWorker\x12\x1b.ateapi.UpdateWorkerRequest\x1a\x0e.ateapi.Worker\"\f\x82\xb5\x18\b\n" + - "\x06Worker\x12I\n" + - "\fDeleteWorker\x12\x1b.ateapi.DeleteWorkerRequest\x1a\x0e.ateapi.Worker\"\f\x82\xb5\x18\b\n" + - "\x06Worker\x12T\n" + - "\vDrainWorker\x12\x1a.ateapi.DrainWorkerRequest\x1a\x1b.ateapi.DrainWorkerResponse\"\f\x82\xb5\x18\b\n" + - "\x06Worker\x12l\n" + - "\x13MarkWorkerAvailable\x12\".ateapi.MarkWorkerAvailableRequest\x1a#.ateapi.MarkWorkerAvailableResponse\"\f\x82\xb5\x18\b\n" + - "\x06Worker\x12r\n" + - "\x15MarkWorkerUnavailable\x12$.ateapi.MarkWorkerUnavailableRequest\x1a%.ateapi.MarkWorkerUnavailableResponse\"\f\x82\xb5\x18\b\n" + - "\x06Worker\x12\x8a\x01\n" + - "\x1aListWorkerActorAssignments\x12).ateapi.ListWorkerActorAssignmentsRequest\x1a*.ateapi.ListWorkerActorAssignmentsResponse\"\x15\x82\xb5\x18\x11\n" + - "\x0fActorAssignment\x12P\n" + + "\fSCOPE_GLOBAL\x10\x022\xd5'\n" + + "\aControl\x12Y\n" + + "\bGetActor\x12$.substrate.ateapi.v1.GetActorRequest\x1a\x1a.substrate.ateapi.v1.Actor\"\v\x82\xb5\x18\a\n" + + "\x05Actor\x12_\n" + + "\vCreateActor\x12'.substrate.ateapi.v1.CreateActorRequest\x1a\x1a.substrate.ateapi.v1.Actor\"\v\x82\xb5\x18\a\n" + + "\x05Actor\x12_\n" + + "\vUpdateActor\x12'.substrate.ateapi.v1.UpdateActorRequest\x1a\x1a.substrate.ateapi.v1.Actor\"\v\x82\xb5\x18\a\n" + + "\x05Actor\x12p\n" + + "\fSuspendActor\x12(.substrate.ateapi.v1.SuspendActorRequest\x1a).substrate.ateapi.v1.SuspendActorResponse\"\v\x82\xb5\x18\a\n" + + "\x05Actor\x12m\n" + + "\vResumeActor\x12'.substrate.ateapi.v1.ResumeActorRequest\x1a(.substrate.ateapi.v1.ResumeActorResponse\"\v\x82\xb5\x18\a\n" + + "\x05Actor\x12m\n" + + "\vRevertActor\x12'.substrate.ateapi.v1.RevertActorRequest\x1a(.substrate.ateapi.v1.RevertActorResponse\"\v\x82\xb5\x18\a\n" + + "\x05Actor\x12_\n" + + "\vDeleteActor\x12'.substrate.ateapi.v1.DeleteActorRequest\x1a\x1a.substrate.ateapi.v1.Actor\"\v\x82\xb5\x18\a\n" + + "\x05Actor\x12\x7f\n" + + "\x14GetActorEgressPolicy\x120.substrate.ateapi.v1.GetActorEgressPolicyRequest\x1a!.substrate.ateapi.v1.EgressPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fEgressPolicy\x12\x85\x01\n" + + "\x17CreateActorEgressPolicy\x123.substrate.ateapi.v1.CreateActorEgressPolicyRequest\x1a!.substrate.ateapi.v1.EgressPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fEgressPolicy\x12\x85\x01\n" + + "\x17UpdateActorEgressPolicy\x123.substrate.ateapi.v1.UpdateActorEgressPolicyRequest\x1a!.substrate.ateapi.v1.EgressPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fEgressPolicy\x12\x85\x01\n" + + "\x17DeleteActorEgressPolicy\x123.substrate.ateapi.v1.DeleteActorEgressPolicyRequest\x1a!.substrate.ateapi.v1.EgressPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fEgressPolicy\x12p\n" + + "\fMintActorJwt\x12(.substrate.ateapi.v1.MintActorJwtRequest\x1a).substrate.ateapi.v1.MintActorJwtResponse\"\v\x82\xb5\x18\a\n" + + "\x05Actor\x12\x88\x01\n" + + "\x14MintActorCertificate\x120.substrate.ateapi.v1.MintActorCertificateRequest\x1a1.substrate.ateapi.v1.MintActorCertificateResponse\"\v\x82\xb5\x18\a\n" + + "\x05Actor\x12W\n" + + "\tCreateTag\x12%.substrate.ateapi.v1.CreateTagRequest\x1a\x18.substrate.ateapi.v1.Tag\"\t\x82\xb5\x18\x05\n" + + "\x03Tag\x12Q\n" + + "\x06GetTag\x12\".substrate.ateapi.v1.GetTagRequest\x1a\x18.substrate.ateapi.v1.Tag\"\t\x82\xb5\x18\x05\n" + + "\x03Tag\x12b\n" + + "\bListTags\x12$.substrate.ateapi.v1.ListTagsRequest\x1a%.substrate.ateapi.v1.ListTagsResponse\"\t\x82\xb5\x18\x05\n" + + "\x03Tag\x12W\n" + + "\tUpdateTag\x12%.substrate.ateapi.v1.UpdateTagRequest\x1a\x18.substrate.ateapi.v1.Tag\"\t\x82\xb5\x18\x05\n" + + "\x03Tag\x12W\n" + + "\tDeleteTag\x12%.substrate.ateapi.v1.DeleteTagRequest\x1a\x18.substrate.ateapi.v1.Tag\"\t\x82\xb5\x18\x05\n" + + "\x03Tag\x12n\n" + + "\vListWorkers\x12'.substrate.ateapi.v1.ListWorkersRequest\x1a(.substrate.ateapi.v1.ListWorkersResponse\"\f\x82\xb5\x18\b\n" + + "\x06Worker\x12]\n" + + "\tGetWorker\x12%.substrate.ateapi.v1.GetWorkerRequest\x1a\x1b.substrate.ateapi.v1.Worker\"\f\x82\xb5\x18\b\n" + + "\x06Worker\x12c\n" + + "\fCreateWorker\x12(.substrate.ateapi.v1.CreateWorkerRequest\x1a\x1b.substrate.ateapi.v1.Worker\"\f\x82\xb5\x18\b\n" + + "\x06Worker\x12c\n" + + "\fUpdateWorker\x12(.substrate.ateapi.v1.UpdateWorkerRequest\x1a\x1b.substrate.ateapi.v1.Worker\"\f\x82\xb5\x18\b\n" + + "\x06Worker\x12c\n" + + "\fDeleteWorker\x12(.substrate.ateapi.v1.DeleteWorkerRequest\x1a\x1b.substrate.ateapi.v1.Worker\"\f\x82\xb5\x18\b\n" + + "\x06Worker\x12n\n" + + "\vDrainWorker\x12'.substrate.ateapi.v1.DrainWorkerRequest\x1a(.substrate.ateapi.v1.DrainWorkerResponse\"\f\x82\xb5\x18\b\n" + + "\x06Worker\x12\x86\x01\n" + + "\x13MarkWorkerAvailable\x12/.substrate.ateapi.v1.MarkWorkerAvailableRequest\x1a0.substrate.ateapi.v1.MarkWorkerAvailableResponse\"\f\x82\xb5\x18\b\n" + + "\x06Worker\x12\x8c\x01\n" + + "\x15MarkWorkerUnavailable\x121.substrate.ateapi.v1.MarkWorkerUnavailableRequest\x1a2.substrate.ateapi.v1.MarkWorkerUnavailableResponse\"\f\x82\xb5\x18\b\n" + + "\x06Worker\x12\xa4\x01\n" + + "\x1aListWorkerActorAssignments\x126.substrate.ateapi.v1.ListWorkerActorAssignmentsRequest\x1a7.substrate.ateapi.v1.ListWorkerActorAssignmentsResponse\"\x15\x82\xb5\x18\x11\n" + + "\x0fActorAssignment\x12j\n" + "\n" + - "ListActors\x12\x19.ateapi.ListActorsRequest\x1a\x1a.ateapi.ListActorsResponse\"\v\x82\xb5\x18\a\n" + - "\x05Actor\x12Q\n" + - "\x0eCreateAtespace\x12\x1d.ateapi.CreateAtespaceRequest\x1a\x10.ateapi.Atespace\"\x0e\x82\xb5\x18\n" + + "ListActors\x12&.substrate.ateapi.v1.ListActorsRequest\x1a'.substrate.ateapi.v1.ListActorsResponse\"\v\x82\xb5\x18\a\n" + + "\x05Actor\x12k\n" + + "\x0eCreateAtespace\x12*.substrate.ateapi.v1.CreateAtespaceRequest\x1a\x1d.substrate.ateapi.v1.Atespace\"\x0e\x82\xb5\x18\n" + "\n" + - "\bAtespace\x12K\n" + - "\vGetAtespace\x12\x1a.ateapi.GetAtespaceRequest\x1a\x10.ateapi.Atespace\"\x0e\x82\xb5\x18\n" + + "\bAtespace\x12e\n" + + "\vGetAtespace\x12'.substrate.ateapi.v1.GetAtespaceRequest\x1a\x1d.substrate.ateapi.v1.Atespace\"\x0e\x82\xb5\x18\n" + "\n" + - "\bAtespace\x12\\\n" + - "\rListAtespaces\x12\x1c.ateapi.ListAtespacesRequest\x1a\x1d.ateapi.ListAtespacesResponse\"\x0e\x82\xb5\x18\n" + + "\bAtespace\x12v\n" + + "\rListAtespaces\x12).substrate.ateapi.v1.ListAtespacesRequest\x1a*.substrate.ateapi.v1.ListAtespacesResponse\"\x0e\x82\xb5\x18\n" + "\n" + - "\bAtespace\x12Q\n" + - "\x0eDeleteAtespace\x12\x1d.ateapi.DeleteAtespaceRequest\x1a\x10.ateapi.Atespace\"\x0e\x82\xb5\x18\n" + + "\bAtespace\x12k\n" + + "\x0eDeleteAtespace\x12*.substrate.ateapi.v1.DeleteAtespaceRequest\x1a\x1d.substrate.ateapi.v1.Atespace\"\x0e\x82\xb5\x18\n" + "\n" + - "\bAtespace\x12e\n" + - "\x13CreateActorTemplate\x12\".ateapi.CreateActorTemplateRequest\x1a\x15.ateapi.ActorTemplate\"\x13\x82\xb5\x18\x0f\n" + - "\rActorTemplate\x12_\n" + - "\x10GetActorTemplate\x12\x1f.ateapi.GetActorTemplateRequest\x1a\x15.ateapi.ActorTemplate\"\x13\x82\xb5\x18\x0f\n" + - "\rActorTemplate\x12p\n" + - "\x12ListActorTemplates\x12!.ateapi.ListActorTemplatesRequest\x1a\".ateapi.ListActorTemplatesResponse\"\x13\x82\xb5\x18\x0f\n" + - "\rActorTemplate\x12e\n" + - "\x13DeleteActorTemplate\x12\".ateapi.DeleteActorTemplateRequest\x1a\x15.ateapi.ActorTemplate\"\x13\x82\xb5\x18\x0f\n" + - "\rActorTemplate\x12g\n" + - "\x15GetGlobalAccessPolicy\x12$.ateapi.GetGlobalAccessPolicyRequest\x1a\x14.ateapi.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + - "\fAccessPolicy\x12m\n" + - "\x18CreateGlobalAccessPolicy\x12'.ateapi.CreateGlobalAccessPolicyRequest\x1a\x14.ateapi.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + - "\fAccessPolicy\x12m\n" + - "\x18UpdateGlobalAccessPolicy\x12'.ateapi.UpdateGlobalAccessPolicyRequest\x1a\x14.ateapi.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + - "\fAccessPolicy\x12k\n" + - "\x17GetAtespaceAccessPolicy\x12&.ateapi.GetAtespaceAccessPolicyRequest\x1a\x14.ateapi.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + - "\fAccessPolicy\x12q\n" + - "\x1aCreateAtespaceAccessPolicy\x12).ateapi.CreateAtespaceAccessPolicyRequest\x1a\x14.ateapi.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + - "\fAccessPolicy\x12q\n" + - "\x1aUpdateAtespaceAccessPolicy\x12).ateapi.UpdateAtespaceAccessPolicyRequest\x1a\x14.ateapi.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + - "\fAccessPolicy\x12q\n" + - "\x1aDeleteAtespaceAccessPolicy\x12).ateapi.DeleteAtespaceAccessPolicyRequest\x1a\x14.ateapi.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + - "\fAccessPolicy2\xaa\x06\n" + - "\rWorkerService\x12[\n" + - "\x12AcquireWorkerEpoch\x12!.ateapi.AcquireWorkerEpochRequest\x1a\".ateapi.AcquireWorkerEpochResponse\x12O\n" + - "\x0eRegisterWorker\x12\x1d.ateapi.RegisterWorkerRequest\x1a\x1e.ateapi.RegisterWorkerResponse\x12m\n" + - "\x18SetWorkerSandboxRuntimes\x12'.ateapi.SetWorkerSandboxRuntimesRequest\x1a(.ateapi.SetWorkerSandboxRuntimesResponse\x12s\n" + - "\x1aMintWorkerActorCertificate\x12).ateapi.MintWorkerActorCertificateRequest\x1a*.ateapi.MintWorkerActorCertificateResponse\x12[\n" + - "\x12MintWorkerActorJwt\x12!.ateapi.MintWorkerActorJwtRequest\x1a\".ateapi.MintWorkerActorJwtResponse\x12^\n" + - "\x13RequestActorSuspend\x12\".ateapi.RequestActorSuspendRequest\x1a#.ateapi.RequestActorSuspendResponse\x12m\n" + - "\x18ReportActorSnapshotState\x12'.ateapi.ReportActorSnapshotStateRequest\x1a(.ateapi.ReportActorSnapshotStateResponse\x12[\n" + - "\x12ReportActorCrashed\x12!.ateapi.ReportActorCrashedRequest\x1a\".ateapi.ReportActorCrashedResponse:Y\n" + - "\bresource\x12\x1f.google.protobuf.MessageOptions\x18І\x03 \x01(\v2\x1a.ateapi.ResourceAnnotationR\bresource:R\n" + - "\x06method\x12\x1e.google.protobuf.MethodOptions\x18І\x03 \x01(\v2\x18.ateapi.MethodAnnotationR\x06methodB)Z'go.ate.dev/substrate/pkg/proto/ateapipbb\x06proto3" + "\bAtespace\x12\x7f\n" + + "\x13CreateActorTemplate\x12/.substrate.ateapi.v1.CreateActorTemplateRequest\x1a\".substrate.ateapi.v1.ActorTemplate\"\x13\x82\xb5\x18\x0f\n" + + "\rActorTemplate\x12y\n" + + "\x10GetActorTemplate\x12,.substrate.ateapi.v1.GetActorTemplateRequest\x1a\".substrate.ateapi.v1.ActorTemplate\"\x13\x82\xb5\x18\x0f\n" + + "\rActorTemplate\x12\x8a\x01\n" + + "\x12ListActorTemplates\x12..substrate.ateapi.v1.ListActorTemplatesRequest\x1a/.substrate.ateapi.v1.ListActorTemplatesResponse\"\x13\x82\xb5\x18\x0f\n" + + "\rActorTemplate\x12\x7f\n" + + "\x13DeleteActorTemplate\x12/.substrate.ateapi.v1.DeleteActorTemplateRequest\x1a\".substrate.ateapi.v1.ActorTemplate\"\x13\x82\xb5\x18\x0f\n" + + "\rActorTemplate\x12\x81\x01\n" + + "\x15GetGlobalAccessPolicy\x121.substrate.ateapi.v1.GetGlobalAccessPolicyRequest\x1a!.substrate.ateapi.v1.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fAccessPolicy\x12\x87\x01\n" + + "\x18CreateGlobalAccessPolicy\x124.substrate.ateapi.v1.CreateGlobalAccessPolicyRequest\x1a!.substrate.ateapi.v1.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fAccessPolicy\x12\x87\x01\n" + + "\x18UpdateGlobalAccessPolicy\x124.substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest\x1a!.substrate.ateapi.v1.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fAccessPolicy\x12\x85\x01\n" + + "\x17GetAtespaceAccessPolicy\x123.substrate.ateapi.v1.GetAtespaceAccessPolicyRequest\x1a!.substrate.ateapi.v1.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fAccessPolicy\x12\x8b\x01\n" + + "\x1aCreateAtespaceAccessPolicy\x126.substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest\x1a!.substrate.ateapi.v1.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fAccessPolicy\x12\x8b\x01\n" + + "\x1aUpdateAtespaceAccessPolicy\x126.substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest\x1a!.substrate.ateapi.v1.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fAccessPolicy\x12\x8b\x01\n" + + "\x1aDeleteAtespaceAccessPolicy\x126.substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest\x1a!.substrate.ateapi.v1.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fAccessPolicy2\xfd\a\n" + + "\rWorkerService\x12u\n" + + "\x12AcquireWorkerEpoch\x12..substrate.ateapi.v1.AcquireWorkerEpochRequest\x1a/.substrate.ateapi.v1.AcquireWorkerEpochResponse\x12i\n" + + "\x0eRegisterWorker\x12*.substrate.ateapi.v1.RegisterWorkerRequest\x1a+.substrate.ateapi.v1.RegisterWorkerResponse\x12\x87\x01\n" + + "\x18SetWorkerSandboxRuntimes\x124.substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest\x1a5.substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse\x12\x8d\x01\n" + + "\x1aMintWorkerActorCertificate\x126.substrate.ateapi.v1.MintWorkerActorCertificateRequest\x1a7.substrate.ateapi.v1.MintWorkerActorCertificateResponse\x12u\n" + + "\x12MintWorkerActorJwt\x12..substrate.ateapi.v1.MintWorkerActorJwtRequest\x1a/.substrate.ateapi.v1.MintWorkerActorJwtResponse\x12x\n" + + "\x13RequestActorSuspend\x12/.substrate.ateapi.v1.RequestActorSuspendRequest\x1a0.substrate.ateapi.v1.RequestActorSuspendResponse\x12\x87\x01\n" + + "\x18ReportActorSnapshotState\x124.substrate.ateapi.v1.ReportActorSnapshotStateRequest\x1a5.substrate.ateapi.v1.ReportActorSnapshotStateResponse\x12u\n" + + "\x12ReportActorCrashed\x12..substrate.ateapi.v1.ReportActorCrashedRequest\x1a/.substrate.ateapi.v1.ReportActorCrashedResponse:f\n" + + "\bresource\x12\x1f.google.protobuf.MessageOptions\x18І\x03 \x01(\v2'.substrate.ateapi.v1.ResourceAnnotationR\bresource:_\n" + + "\x06method\x12\x1e.google.protobuf.MethodOptions\x18І\x03 \x01(\v2%.substrate.ateapi.v1.MethodAnnotationR\x06methodB+Z)go.ate.dev/substrate/api/ateapi/v1;ateapib\x06proto3" var ( - file_ateapi_proto_rawDescOnce sync.Once - file_ateapi_proto_rawDescData []byte + file_api_ateapi_v1_ateapi_proto_rawDescOnce sync.Once + file_api_ateapi_v1_ateapi_proto_rawDescData []byte ) -func file_ateapi_proto_rawDescGZIP() []byte { - file_ateapi_proto_rawDescOnce.Do(func() { - file_ateapi_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ateapi_proto_rawDesc), len(file_ateapi_proto_rawDesc))) +func file_api_ateapi_v1_ateapi_proto_rawDescGZIP() []byte { + file_api_ateapi_v1_ateapi_proto_rawDescOnce.Do(func() { + file_api_ateapi_v1_ateapi_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_api_ateapi_v1_ateapi_proto_rawDesc), len(file_api_ateapi_v1_ateapi_proto_rawDesc))) }) - return file_ateapi_proto_rawDescData -} - -var file_ateapi_proto_enumTypes = make([]protoimpl.EnumInfo, 10) -var file_ateapi_proto_msgTypes = make([]protoimpl.MessageInfo, 144) -var file_ateapi_proto_goTypes = []any{ - (SnapshotOwner)(0), // 0: ateapi.SnapshotOwner - (SnapshotStorageStatus)(0), // 1: ateapi.SnapshotStorageStatus - (SnapshotFidelity)(0), // 2: ateapi.SnapshotFidelity - (TagScope)(0), // 3: ateapi.TagScope - (ActorState)(0), // 4: ateapi.ActorState - (GoldenSnapshotMode)(0), // 5: ateapi.GoldenSnapshotMode - (ActorMetadataField)(0), // 6: ateapi.ActorMetadataField - (DurabilityMode)(0), // 7: ateapi.DurabilityMode - (WorkerState)(0), // 8: ateapi.WorkerState - (Scope)(0), // 9: ateapi.Scope - (*ObjectSnapshot)(nil), // 10: ateapi.ObjectSnapshot - (*SnapshotStorage)(nil), // 11: ateapi.SnapshotStorage - (*Snapshot)(nil), // 12: ateapi.Snapshot - (*Selector)(nil), // 13: ateapi.Selector - (*ResourceMetadata)(nil), // 14: ateapi.ResourceMetadata - (*ExternalVolumes)(nil), // 15: ateapi.ExternalVolumes - (*ExternalVolumeStatus)(nil), // 16: ateapi.ExternalVolumeStatus - (*Actor)(nil), // 17: ateapi.Actor - (*EgressPolicy)(nil), // 18: ateapi.EgressPolicy - (*EgressPolicyTemplate)(nil), // 19: ateapi.EgressPolicyTemplate - (*EgressRule)(nil), // 20: ateapi.EgressRule - (*HttpRule)(nil), // 21: ateapi.HttpRule - (*HttpsRule)(nil), // 22: ateapi.HttpsRule - (*TlsPassthroughRule)(nil), // 23: ateapi.TlsPassthroughRule - (*Ports)(nil), // 24: ateapi.Ports - (*AllPorts)(nil), // 25: ateapi.AllPorts - (*HttpRuleEffects)(nil), // 26: ateapi.HttpRuleEffects - (*CredentialHeader)(nil), // 27: ateapi.CredentialHeader - (*ActorJwtSource)(nil), // 28: ateapi.ActorJwtSource - (*ActorStatus)(nil), // 29: ateapi.ActorStatus - (*ActorCrash)(nil), // 30: ateapi.ActorCrash - (*WorkerAssignment)(nil), // 31: ateapi.WorkerAssignment - (*TagStatus)(nil), // 32: ateapi.TagStatus - (*Tag)(nil), // 33: ateapi.Tag - (*Atespace)(nil), // 34: ateapi.Atespace - (*ObjectRef)(nil), // 35: ateapi.ObjectRef - (*ActorTemplate)(nil), // 36: ateapi.ActorTemplate - (*ResourceRequirements)(nil), // 37: ateapi.ResourceRequirements - (*Resources)(nil), // 38: ateapi.Resources - (*GoldenSnapshotStatus)(nil), // 39: ateapi.GoldenSnapshotStatus - (*ActorTemplateStatus)(nil), // 40: ateapi.ActorTemplateStatus - (*SnapshotConfig)(nil), // 41: ateapi.SnapshotConfig - (*GoldenSnapshotConfig)(nil), // 42: ateapi.GoldenSnapshotConfig - (*Container)(nil), // 43: ateapi.Container - (*SecurityContext)(nil), // 44: ateapi.SecurityContext - (*Capabilities)(nil), // 45: ateapi.Capabilities - (*EnvVar)(nil), // 46: ateapi.EnvVar - (*WakeupProbe)(nil), // 47: ateapi.WakeupProbe - (*HttpGetAction)(nil), // 48: ateapi.HttpGetAction - (*Volume)(nil), // 49: ateapi.Volume - (*ExternalVolumeSource)(nil), // 50: ateapi.ExternalVolumeSource - (*ImageVolumeSource)(nil), // 51: ateapi.ImageVolumeSource - (*DurableDirVolumeSource)(nil), // 52: ateapi.DurableDirVolumeSource - (*ExternalVolumeTemplate)(nil), // 53: ateapi.ExternalVolumeTemplate - (*SystemInfoVolumeSource)(nil), // 54: ateapi.SystemInfoVolumeSource - (*SystemInfoDataSource)(nil), // 55: ateapi.SystemInfoDataSource - (*ActorMetadataDataSource)(nil), // 56: ateapi.ActorMetadataDataSource - (*ActorMetadataItem)(nil), // 57: ateapi.ActorMetadataItem - (*TrustBundleDataSource)(nil), // 58: ateapi.TrustBundleDataSource - (*VolumeMount)(nil), // 59: ateapi.VolumeMount - (*CreateAtespaceRequest)(nil), // 60: ateapi.CreateAtespaceRequest - (*GetAtespaceRequest)(nil), // 61: ateapi.GetAtespaceRequest - (*ListAtespacesRequest)(nil), // 62: ateapi.ListAtespacesRequest - (*ListAtespacesResponse)(nil), // 63: ateapi.ListAtespacesResponse - (*DeleteAtespaceRequest)(nil), // 64: ateapi.DeleteAtespaceRequest - (*CreateActorTemplateRequest)(nil), // 65: ateapi.CreateActorTemplateRequest - (*GetActorTemplateRequest)(nil), // 66: ateapi.GetActorTemplateRequest - (*ListActorTemplatesRequest)(nil), // 67: ateapi.ListActorTemplatesRequest - (*ListActorTemplatesResponse)(nil), // 68: ateapi.ListActorTemplatesResponse - (*DeleteActorTemplateRequest)(nil), // 69: ateapi.DeleteActorTemplateRequest - (*GetActorRequest)(nil), // 70: ateapi.GetActorRequest - (*CreateActorRequest)(nil), // 71: ateapi.CreateActorRequest - (*UpdateActorRequest)(nil), // 72: ateapi.UpdateActorRequest - (*SuspendActorRequest)(nil), // 73: ateapi.SuspendActorRequest - (*SuspendActorResponse)(nil), // 74: ateapi.SuspendActorResponse - (*SuspendOptions)(nil), // 75: ateapi.SuspendOptions - (*ResumeActorRequest)(nil), // 76: ateapi.ResumeActorRequest - (*ResumeActorResponse)(nil), // 77: ateapi.ResumeActorResponse - (*RevertActorRequest)(nil), // 78: ateapi.RevertActorRequest - (*RevertActorResponse)(nil), // 79: ateapi.RevertActorResponse - (*DeleteActorRequest)(nil), // 80: ateapi.DeleteActorRequest - (*GetActorEgressPolicyRequest)(nil), // 81: ateapi.GetActorEgressPolicyRequest - (*CreateActorEgressPolicyRequest)(nil), // 82: ateapi.CreateActorEgressPolicyRequest - (*UpdateActorEgressPolicyRequest)(nil), // 83: ateapi.UpdateActorEgressPolicyRequest - (*DeleteActorEgressPolicyRequest)(nil), // 84: ateapi.DeleteActorEgressPolicyRequest - (*GetTagRequest)(nil), // 85: ateapi.GetTagRequest - (*MintActorJwtRequest)(nil), // 86: ateapi.MintActorJwtRequest - (*MintActorJwtResponse)(nil), // 87: ateapi.MintActorJwtResponse - (*MintActorCertificateRequest)(nil), // 88: ateapi.MintActorCertificateRequest - (*MintActorCertificateResponse)(nil), // 89: ateapi.MintActorCertificateResponse - (*ListTagsRequest)(nil), // 90: ateapi.ListTagsRequest - (*ListTagsResponse)(nil), // 91: ateapi.ListTagsResponse - (*CreateTagRequest)(nil), // 92: ateapi.CreateTagRequest - (*UpdateTagRequest)(nil), // 93: ateapi.UpdateTagRequest - (*DeleteTagRequest)(nil), // 94: ateapi.DeleteTagRequest - (*DeleteOptions)(nil), // 95: ateapi.DeleteOptions - (*ListOptions)(nil), // 96: ateapi.ListOptions - (*ListWorkerActorAssignmentsRequest)(nil), // 97: ateapi.ListWorkerActorAssignmentsRequest - (*ListWorkerActorAssignmentsResponse)(nil), // 98: ateapi.ListWorkerActorAssignmentsResponse - (*ListWorkersRequest)(nil), // 99: ateapi.ListWorkersRequest - (*ListWorkersResponse)(nil), // 100: ateapi.ListWorkersResponse - (*GetWorkerRequest)(nil), // 101: ateapi.GetWorkerRequest - (*CreateWorkerRequest)(nil), // 102: ateapi.CreateWorkerRequest - (*UpdateWorkerRequest)(nil), // 103: ateapi.UpdateWorkerRequest - (*DeleteWorkerRequest)(nil), // 104: ateapi.DeleteWorkerRequest - (*DrainWorkerRequest)(nil), // 105: ateapi.DrainWorkerRequest - (*DrainWorkerResponse)(nil), // 106: ateapi.DrainWorkerResponse - (*MarkWorkerAvailableRequest)(nil), // 107: ateapi.MarkWorkerAvailableRequest - (*MarkWorkerAvailableResponse)(nil), // 108: ateapi.MarkWorkerAvailableResponse - (*MarkWorkerUnavailableRequest)(nil), // 109: ateapi.MarkWorkerUnavailableRequest - (*MarkWorkerUnavailableResponse)(nil), // 110: ateapi.MarkWorkerUnavailableResponse - (*ListActorsRequest)(nil), // 111: ateapi.ListActorsRequest - (*ListActorsResponse)(nil), // 112: ateapi.ListActorsResponse - (*Worker)(nil), // 113: ateapi.Worker - (*WorkerStatus)(nil), // 114: ateapi.WorkerStatus - (*WorkerSandboxClass)(nil), // 115: ateapi.WorkerSandboxClass - (*WorkerSandboxRuntime)(nil), // 116: ateapi.WorkerSandboxRuntime - (*ActorSandboxRuntime)(nil), // 117: ateapi.ActorSandboxRuntime - (*VersionedSandboxCompat)(nil), // 118: ateapi.VersionedSandboxCompat - (*AttributeEntry)(nil), // 119: ateapi.AttributeEntry - (*WorkerResources)(nil), // 120: ateapi.WorkerResources - (*ActorAssignment)(nil), // 121: ateapi.ActorAssignment - (*AcquireWorkerEpochRequest)(nil), // 122: ateapi.AcquireWorkerEpochRequest - (*AcquireWorkerEpochResponse)(nil), // 123: ateapi.AcquireWorkerEpochResponse - (*RegisterWorkerRequest)(nil), // 124: ateapi.RegisterWorkerRequest - (*RegisterWorkerResponse)(nil), // 125: ateapi.RegisterWorkerResponse - (*SetWorkerSandboxRuntimesRequest)(nil), // 126: ateapi.SetWorkerSandboxRuntimesRequest - (*SetWorkerSandboxRuntimesResponse)(nil), // 127: ateapi.SetWorkerSandboxRuntimesResponse - (*MintWorkerActorCertificateRequest)(nil), // 128: ateapi.MintWorkerActorCertificateRequest - (*MintWorkerActorCertificateResponse)(nil), // 129: ateapi.MintWorkerActorCertificateResponse - (*MintWorkerActorJwtRequest)(nil), // 130: ateapi.MintWorkerActorJwtRequest - (*MintWorkerActorJwtResponse)(nil), // 131: ateapi.MintWorkerActorJwtResponse - (*RequestActorSuspendRequest)(nil), // 132: ateapi.RequestActorSuspendRequest - (*RequestActorSuspendResponse)(nil), // 133: ateapi.RequestActorSuspendResponse - (*ReportActorCrashedRequest)(nil), // 134: ateapi.ReportActorCrashedRequest - (*ReportActorCrashedResponse)(nil), // 135: ateapi.ReportActorCrashedResponse - (*ReportActorSnapshotStateRequest)(nil), // 136: ateapi.ReportActorSnapshotStateRequest - (*ReportActorSnapshotStateResponse)(nil), // 137: ateapi.ReportActorSnapshotStateResponse - (*ActorSnapshotState)(nil), // 138: ateapi.ActorSnapshotState - (*SnapshotReport)(nil), // 139: ateapi.SnapshotReport - (*AccessPolicy)(nil), // 140: ateapi.AccessPolicy - (*Binding)(nil), // 141: ateapi.Binding - (*GetGlobalAccessPolicyRequest)(nil), // 142: ateapi.GetGlobalAccessPolicyRequest - (*CreateGlobalAccessPolicyRequest)(nil), // 143: ateapi.CreateGlobalAccessPolicyRequest - (*UpdateGlobalAccessPolicyRequest)(nil), // 144: ateapi.UpdateGlobalAccessPolicyRequest - (*GetAtespaceAccessPolicyRequest)(nil), // 145: ateapi.GetAtespaceAccessPolicyRequest - (*CreateAtespaceAccessPolicyRequest)(nil), // 146: ateapi.CreateAtespaceAccessPolicyRequest - (*UpdateAtespaceAccessPolicyRequest)(nil), // 147: ateapi.UpdateAtespaceAccessPolicyRequest - (*DeleteAtespaceAccessPolicyRequest)(nil), // 148: ateapi.DeleteAtespaceAccessPolicyRequest - (*ResourceAnnotation)(nil), // 149: ateapi.ResourceAnnotation - (*MethodAnnotation)(nil), // 150: ateapi.MethodAnnotation - nil, // 151: ateapi.Selector.MatchLabelsEntry - nil, // 152: ateapi.ExternalVolumeStatus.VolumeContextEntry - nil, // 153: ateapi.Worker.LabelsEntry + return file_api_ateapi_v1_ateapi_proto_rawDescData +} + +var file_api_ateapi_v1_ateapi_proto_enumTypes = make([]protoimpl.EnumInfo, 10) +var file_api_ateapi_v1_ateapi_proto_msgTypes = make([]protoimpl.MessageInfo, 144) +var file_api_ateapi_v1_ateapi_proto_goTypes = []any{ + (SnapshotOwner)(0), // 0: substrate.ateapi.v1.SnapshotOwner + (SnapshotStorageStatus)(0), // 1: substrate.ateapi.v1.SnapshotStorageStatus + (SnapshotFidelity)(0), // 2: substrate.ateapi.v1.SnapshotFidelity + (TagScope)(0), // 3: substrate.ateapi.v1.TagScope + (ActorState)(0), // 4: substrate.ateapi.v1.ActorState + (GoldenSnapshotMode)(0), // 5: substrate.ateapi.v1.GoldenSnapshotMode + (ActorMetadataField)(0), // 6: substrate.ateapi.v1.ActorMetadataField + (DurabilityMode)(0), // 7: substrate.ateapi.v1.DurabilityMode + (WorkerState)(0), // 8: substrate.ateapi.v1.WorkerState + (Scope)(0), // 9: substrate.ateapi.v1.Scope + (*ObjectSnapshot)(nil), // 10: substrate.ateapi.v1.ObjectSnapshot + (*SnapshotStorage)(nil), // 11: substrate.ateapi.v1.SnapshotStorage + (*Snapshot)(nil), // 12: substrate.ateapi.v1.Snapshot + (*Selector)(nil), // 13: substrate.ateapi.v1.Selector + (*ResourceMetadata)(nil), // 14: substrate.ateapi.v1.ResourceMetadata + (*ExternalVolumes)(nil), // 15: substrate.ateapi.v1.ExternalVolumes + (*ExternalVolumeStatus)(nil), // 16: substrate.ateapi.v1.ExternalVolumeStatus + (*Actor)(nil), // 17: substrate.ateapi.v1.Actor + (*EgressPolicy)(nil), // 18: substrate.ateapi.v1.EgressPolicy + (*EgressPolicyTemplate)(nil), // 19: substrate.ateapi.v1.EgressPolicyTemplate + (*EgressRule)(nil), // 20: substrate.ateapi.v1.EgressRule + (*HttpRule)(nil), // 21: substrate.ateapi.v1.HttpRule + (*HttpsRule)(nil), // 22: substrate.ateapi.v1.HttpsRule + (*TlsPassthroughRule)(nil), // 23: substrate.ateapi.v1.TlsPassthroughRule + (*Ports)(nil), // 24: substrate.ateapi.v1.Ports + (*AllPorts)(nil), // 25: substrate.ateapi.v1.AllPorts + (*HttpRuleEffects)(nil), // 26: substrate.ateapi.v1.HttpRuleEffects + (*CredentialHeader)(nil), // 27: substrate.ateapi.v1.CredentialHeader + (*ActorJwtSource)(nil), // 28: substrate.ateapi.v1.ActorJwtSource + (*ActorStatus)(nil), // 29: substrate.ateapi.v1.ActorStatus + (*ActorCrash)(nil), // 30: substrate.ateapi.v1.ActorCrash + (*WorkerAssignment)(nil), // 31: substrate.ateapi.v1.WorkerAssignment + (*TagStatus)(nil), // 32: substrate.ateapi.v1.TagStatus + (*Tag)(nil), // 33: substrate.ateapi.v1.Tag + (*Atespace)(nil), // 34: substrate.ateapi.v1.Atespace + (*ObjectRef)(nil), // 35: substrate.ateapi.v1.ObjectRef + (*ActorTemplate)(nil), // 36: substrate.ateapi.v1.ActorTemplate + (*ResourceRequirements)(nil), // 37: substrate.ateapi.v1.ResourceRequirements + (*Resources)(nil), // 38: substrate.ateapi.v1.Resources + (*GoldenSnapshotStatus)(nil), // 39: substrate.ateapi.v1.GoldenSnapshotStatus + (*ActorTemplateStatus)(nil), // 40: substrate.ateapi.v1.ActorTemplateStatus + (*SnapshotConfig)(nil), // 41: substrate.ateapi.v1.SnapshotConfig + (*GoldenSnapshotConfig)(nil), // 42: substrate.ateapi.v1.GoldenSnapshotConfig + (*Container)(nil), // 43: substrate.ateapi.v1.Container + (*SecurityContext)(nil), // 44: substrate.ateapi.v1.SecurityContext + (*Capabilities)(nil), // 45: substrate.ateapi.v1.Capabilities + (*EnvVar)(nil), // 46: substrate.ateapi.v1.EnvVar + (*WakeupProbe)(nil), // 47: substrate.ateapi.v1.WakeupProbe + (*HttpGetAction)(nil), // 48: substrate.ateapi.v1.HttpGetAction + (*Volume)(nil), // 49: substrate.ateapi.v1.Volume + (*ExternalVolumeSource)(nil), // 50: substrate.ateapi.v1.ExternalVolumeSource + (*ImageVolumeSource)(nil), // 51: substrate.ateapi.v1.ImageVolumeSource + (*DurableDirVolumeSource)(nil), // 52: substrate.ateapi.v1.DurableDirVolumeSource + (*ExternalVolumeTemplate)(nil), // 53: substrate.ateapi.v1.ExternalVolumeTemplate + (*SystemInfoVolumeSource)(nil), // 54: substrate.ateapi.v1.SystemInfoVolumeSource + (*SystemInfoDataSource)(nil), // 55: substrate.ateapi.v1.SystemInfoDataSource + (*ActorMetadataDataSource)(nil), // 56: substrate.ateapi.v1.ActorMetadataDataSource + (*ActorMetadataItem)(nil), // 57: substrate.ateapi.v1.ActorMetadataItem + (*TrustBundleDataSource)(nil), // 58: substrate.ateapi.v1.TrustBundleDataSource + (*VolumeMount)(nil), // 59: substrate.ateapi.v1.VolumeMount + (*CreateAtespaceRequest)(nil), // 60: substrate.ateapi.v1.CreateAtespaceRequest + (*GetAtespaceRequest)(nil), // 61: substrate.ateapi.v1.GetAtespaceRequest + (*ListAtespacesRequest)(nil), // 62: substrate.ateapi.v1.ListAtespacesRequest + (*ListAtespacesResponse)(nil), // 63: substrate.ateapi.v1.ListAtespacesResponse + (*DeleteAtespaceRequest)(nil), // 64: substrate.ateapi.v1.DeleteAtespaceRequest + (*CreateActorTemplateRequest)(nil), // 65: substrate.ateapi.v1.CreateActorTemplateRequest + (*GetActorTemplateRequest)(nil), // 66: substrate.ateapi.v1.GetActorTemplateRequest + (*ListActorTemplatesRequest)(nil), // 67: substrate.ateapi.v1.ListActorTemplatesRequest + (*ListActorTemplatesResponse)(nil), // 68: substrate.ateapi.v1.ListActorTemplatesResponse + (*DeleteActorTemplateRequest)(nil), // 69: substrate.ateapi.v1.DeleteActorTemplateRequest + (*GetActorRequest)(nil), // 70: substrate.ateapi.v1.GetActorRequest + (*CreateActorRequest)(nil), // 71: substrate.ateapi.v1.CreateActorRequest + (*UpdateActorRequest)(nil), // 72: substrate.ateapi.v1.UpdateActorRequest + (*SuspendActorRequest)(nil), // 73: substrate.ateapi.v1.SuspendActorRequest + (*SuspendActorResponse)(nil), // 74: substrate.ateapi.v1.SuspendActorResponse + (*SuspendOptions)(nil), // 75: substrate.ateapi.v1.SuspendOptions + (*ResumeActorRequest)(nil), // 76: substrate.ateapi.v1.ResumeActorRequest + (*ResumeActorResponse)(nil), // 77: substrate.ateapi.v1.ResumeActorResponse + (*RevertActorRequest)(nil), // 78: substrate.ateapi.v1.RevertActorRequest + (*RevertActorResponse)(nil), // 79: substrate.ateapi.v1.RevertActorResponse + (*DeleteActorRequest)(nil), // 80: substrate.ateapi.v1.DeleteActorRequest + (*GetActorEgressPolicyRequest)(nil), // 81: substrate.ateapi.v1.GetActorEgressPolicyRequest + (*CreateActorEgressPolicyRequest)(nil), // 82: substrate.ateapi.v1.CreateActorEgressPolicyRequest + (*UpdateActorEgressPolicyRequest)(nil), // 83: substrate.ateapi.v1.UpdateActorEgressPolicyRequest + (*DeleteActorEgressPolicyRequest)(nil), // 84: substrate.ateapi.v1.DeleteActorEgressPolicyRequest + (*GetTagRequest)(nil), // 85: substrate.ateapi.v1.GetTagRequest + (*MintActorJwtRequest)(nil), // 86: substrate.ateapi.v1.MintActorJwtRequest + (*MintActorJwtResponse)(nil), // 87: substrate.ateapi.v1.MintActorJwtResponse + (*MintActorCertificateRequest)(nil), // 88: substrate.ateapi.v1.MintActorCertificateRequest + (*MintActorCertificateResponse)(nil), // 89: substrate.ateapi.v1.MintActorCertificateResponse + (*ListTagsRequest)(nil), // 90: substrate.ateapi.v1.ListTagsRequest + (*ListTagsResponse)(nil), // 91: substrate.ateapi.v1.ListTagsResponse + (*CreateTagRequest)(nil), // 92: substrate.ateapi.v1.CreateTagRequest + (*UpdateTagRequest)(nil), // 93: substrate.ateapi.v1.UpdateTagRequest + (*DeleteTagRequest)(nil), // 94: substrate.ateapi.v1.DeleteTagRequest + (*DeleteOptions)(nil), // 95: substrate.ateapi.v1.DeleteOptions + (*ListOptions)(nil), // 96: substrate.ateapi.v1.ListOptions + (*ListWorkerActorAssignmentsRequest)(nil), // 97: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest + (*ListWorkerActorAssignmentsResponse)(nil), // 98: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse + (*ListWorkersRequest)(nil), // 99: substrate.ateapi.v1.ListWorkersRequest + (*ListWorkersResponse)(nil), // 100: substrate.ateapi.v1.ListWorkersResponse + (*GetWorkerRequest)(nil), // 101: substrate.ateapi.v1.GetWorkerRequest + (*CreateWorkerRequest)(nil), // 102: substrate.ateapi.v1.CreateWorkerRequest + (*UpdateWorkerRequest)(nil), // 103: substrate.ateapi.v1.UpdateWorkerRequest + (*DeleteWorkerRequest)(nil), // 104: substrate.ateapi.v1.DeleteWorkerRequest + (*DrainWorkerRequest)(nil), // 105: substrate.ateapi.v1.DrainWorkerRequest + (*DrainWorkerResponse)(nil), // 106: substrate.ateapi.v1.DrainWorkerResponse + (*MarkWorkerAvailableRequest)(nil), // 107: substrate.ateapi.v1.MarkWorkerAvailableRequest + (*MarkWorkerAvailableResponse)(nil), // 108: substrate.ateapi.v1.MarkWorkerAvailableResponse + (*MarkWorkerUnavailableRequest)(nil), // 109: substrate.ateapi.v1.MarkWorkerUnavailableRequest + (*MarkWorkerUnavailableResponse)(nil), // 110: substrate.ateapi.v1.MarkWorkerUnavailableResponse + (*ListActorsRequest)(nil), // 111: substrate.ateapi.v1.ListActorsRequest + (*ListActorsResponse)(nil), // 112: substrate.ateapi.v1.ListActorsResponse + (*Worker)(nil), // 113: substrate.ateapi.v1.Worker + (*WorkerStatus)(nil), // 114: substrate.ateapi.v1.WorkerStatus + (*WorkerSandboxClass)(nil), // 115: substrate.ateapi.v1.WorkerSandboxClass + (*WorkerSandboxRuntime)(nil), // 116: substrate.ateapi.v1.WorkerSandboxRuntime + (*ActorSandboxRuntime)(nil), // 117: substrate.ateapi.v1.ActorSandboxRuntime + (*VersionedSandboxCompat)(nil), // 118: substrate.ateapi.v1.VersionedSandboxCompat + (*AttributeEntry)(nil), // 119: substrate.ateapi.v1.AttributeEntry + (*WorkerResources)(nil), // 120: substrate.ateapi.v1.WorkerResources + (*ActorAssignment)(nil), // 121: substrate.ateapi.v1.ActorAssignment + (*AcquireWorkerEpochRequest)(nil), // 122: substrate.ateapi.v1.AcquireWorkerEpochRequest + (*AcquireWorkerEpochResponse)(nil), // 123: substrate.ateapi.v1.AcquireWorkerEpochResponse + (*RegisterWorkerRequest)(nil), // 124: substrate.ateapi.v1.RegisterWorkerRequest + (*RegisterWorkerResponse)(nil), // 125: substrate.ateapi.v1.RegisterWorkerResponse + (*SetWorkerSandboxRuntimesRequest)(nil), // 126: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest + (*SetWorkerSandboxRuntimesResponse)(nil), // 127: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse + (*MintWorkerActorCertificateRequest)(nil), // 128: substrate.ateapi.v1.MintWorkerActorCertificateRequest + (*MintWorkerActorCertificateResponse)(nil), // 129: substrate.ateapi.v1.MintWorkerActorCertificateResponse + (*MintWorkerActorJwtRequest)(nil), // 130: substrate.ateapi.v1.MintWorkerActorJwtRequest + (*MintWorkerActorJwtResponse)(nil), // 131: substrate.ateapi.v1.MintWorkerActorJwtResponse + (*RequestActorSuspendRequest)(nil), // 132: substrate.ateapi.v1.RequestActorSuspendRequest + (*RequestActorSuspendResponse)(nil), // 133: substrate.ateapi.v1.RequestActorSuspendResponse + (*ReportActorCrashedRequest)(nil), // 134: substrate.ateapi.v1.ReportActorCrashedRequest + (*ReportActorCrashedResponse)(nil), // 135: substrate.ateapi.v1.ReportActorCrashedResponse + (*ReportActorSnapshotStateRequest)(nil), // 136: substrate.ateapi.v1.ReportActorSnapshotStateRequest + (*ReportActorSnapshotStateResponse)(nil), // 137: substrate.ateapi.v1.ReportActorSnapshotStateResponse + (*ActorSnapshotState)(nil), // 138: substrate.ateapi.v1.ActorSnapshotState + (*SnapshotReport)(nil), // 139: substrate.ateapi.v1.SnapshotReport + (*AccessPolicy)(nil), // 140: substrate.ateapi.v1.AccessPolicy + (*Binding)(nil), // 141: substrate.ateapi.v1.Binding + (*GetGlobalAccessPolicyRequest)(nil), // 142: substrate.ateapi.v1.GetGlobalAccessPolicyRequest + (*CreateGlobalAccessPolicyRequest)(nil), // 143: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest + (*UpdateGlobalAccessPolicyRequest)(nil), // 144: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest + (*GetAtespaceAccessPolicyRequest)(nil), // 145: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest + (*CreateAtespaceAccessPolicyRequest)(nil), // 146: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest + (*UpdateAtespaceAccessPolicyRequest)(nil), // 147: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest + (*DeleteAtespaceAccessPolicyRequest)(nil), // 148: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest + (*ResourceAnnotation)(nil), // 149: substrate.ateapi.v1.ResourceAnnotation + (*MethodAnnotation)(nil), // 150: substrate.ateapi.v1.MethodAnnotation + nil, // 151: substrate.ateapi.v1.Selector.MatchLabelsEntry + nil, // 152: substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry + nil, // 153: substrate.ateapi.v1.Worker.LabelsEntry (*timestamppb.Timestamp)(nil), // 154: google.protobuf.Timestamp (*descriptorpb.MessageOptions)(nil), // 155: google.protobuf.MessageOptions (*descriptorpb.MethodOptions)(nil), // 156: google.protobuf.MethodOptions } -var file_ateapi_proto_depIdxs = []int32{ - 1, // 0: ateapi.SnapshotStorage.status:type_name -> ateapi.SnapshotStorageStatus - 10, // 1: ateapi.SnapshotStorage.object:type_name -> ateapi.ObjectSnapshot - 0, // 2: ateapi.Snapshot.owner:type_name -> ateapi.SnapshotOwner - 2, // 3: ateapi.Snapshot.fidelity:type_name -> ateapi.SnapshotFidelity - 11, // 4: ateapi.Snapshot.durable_snapshot:type_name -> ateapi.SnapshotStorage - 117, // 5: ateapi.Snapshot.sandbox_runtime:type_name -> ateapi.ActorSandboxRuntime - 151, // 6: ateapi.Selector.match_labels:type_name -> ateapi.Selector.MatchLabelsEntry - 154, // 7: ateapi.ResourceMetadata.create_time:type_name -> google.protobuf.Timestamp - 154, // 8: ateapi.ResourceMetadata.update_time:type_name -> google.protobuf.Timestamp - 154, // 9: ateapi.ResourceMetadata.delete_time:type_name -> google.protobuf.Timestamp - 16, // 10: ateapi.ExternalVolumes.volumes:type_name -> ateapi.ExternalVolumeStatus - 152, // 11: ateapi.ExternalVolumeStatus.volume_context:type_name -> ateapi.ExternalVolumeStatus.VolumeContextEntry - 14, // 12: ateapi.Actor.metadata:type_name -> ateapi.ResourceMetadata - 35, // 13: ateapi.Actor.actor_template:type_name -> ateapi.ObjectRef - 13, // 14: ateapi.Actor.worker_selector:type_name -> ateapi.Selector - 35, // 15: ateapi.Actor.source_tag:type_name -> ateapi.ObjectRef - 29, // 16: ateapi.Actor.status:type_name -> ateapi.ActorStatus - 14, // 17: ateapi.EgressPolicy.metadata:type_name -> ateapi.ResourceMetadata - 20, // 18: ateapi.EgressPolicy.rules:type_name -> ateapi.EgressRule - 20, // 19: ateapi.EgressPolicyTemplate.rules:type_name -> ateapi.EgressRule - 21, // 20: ateapi.EgressRule.http:type_name -> ateapi.HttpRule - 22, // 21: ateapi.EgressRule.https:type_name -> ateapi.HttpsRule - 23, // 22: ateapi.EgressRule.tls_passthrough:type_name -> ateapi.TlsPassthroughRule - 24, // 23: ateapi.HttpRule.ports:type_name -> ateapi.Ports - 26, // 24: ateapi.HttpRule.effects:type_name -> ateapi.HttpRuleEffects - 24, // 25: ateapi.HttpsRule.ports:type_name -> ateapi.Ports - 26, // 26: ateapi.HttpsRule.effects:type_name -> ateapi.HttpRuleEffects - 24, // 27: ateapi.TlsPassthroughRule.ports:type_name -> ateapi.Ports - 25, // 28: ateapi.Ports.all:type_name -> ateapi.AllPorts - 27, // 29: ateapi.HttpRuleEffects.replace_headers:type_name -> ateapi.CredentialHeader - 28, // 30: ateapi.CredentialHeader.actor_jwt:type_name -> ateapi.ActorJwtSource - 4, // 31: ateapi.ActorStatus.state:type_name -> ateapi.ActorState - 31, // 32: ateapi.ActorStatus.worker_assignment:type_name -> ateapi.WorkerAssignment - 15, // 33: ateapi.ActorStatus.external_volumes:type_name -> ateapi.ExternalVolumes - 30, // 34: ateapi.ActorStatus.crash:type_name -> ateapi.ActorCrash - 12, // 35: ateapi.ActorStatus.snapshots:type_name -> ateapi.Snapshot - 154, // 36: ateapi.ActorCrash.crash_time:type_name -> google.protobuf.Timestamp - 35, // 37: ateapi.WorkerAssignment.worker:type_name -> ateapi.ObjectRef - 117, // 38: ateapi.WorkerAssignment.sandbox_runtime:type_name -> ateapi.ActorSandboxRuntime - 12, // 39: ateapi.TagStatus.snapshot:type_name -> ateapi.Snapshot - 14, // 40: ateapi.Tag.metadata:type_name -> ateapi.ResourceMetadata - 32, // 41: ateapi.Tag.status:type_name -> ateapi.TagStatus - 3, // 42: ateapi.Tag.scope:type_name -> ateapi.TagScope - 35, // 43: ateapi.Tag.source_actor:type_name -> ateapi.ObjectRef - 14, // 44: ateapi.Atespace.metadata:type_name -> ateapi.ResourceMetadata - 14, // 45: ateapi.ActorTemplate.metadata:type_name -> ateapi.ResourceMetadata - 13, // 46: ateapi.ActorTemplate.worker_selector:type_name -> ateapi.Selector - 43, // 47: ateapi.ActorTemplate.containers:type_name -> ateapi.Container - 49, // 48: ateapi.ActorTemplate.volumes:type_name -> ateapi.Volume - 41, // 49: ateapi.ActorTemplate.snapshot_config:type_name -> ateapi.SnapshotConfig - 37, // 50: ateapi.ActorTemplate.resources:type_name -> ateapi.ResourceRequirements - 19, // 51: ateapi.ActorTemplate.golden_egress_policy:type_name -> ateapi.EgressPolicyTemplate - 40, // 52: ateapi.ActorTemplate.status:type_name -> ateapi.ActorTemplateStatus - 38, // 53: ateapi.ResourceRequirements.limits:type_name -> ateapi.Resources - 35, // 54: ateapi.GoldenSnapshotStatus.golden_tag:type_name -> ateapi.ObjectRef - 154, // 55: ateapi.GoldenSnapshotStatus.snapshot_time:type_name -> google.protobuf.Timestamp - 39, // 56: ateapi.ActorTemplateStatus.golden_snapshot_status:type_name -> ateapi.GoldenSnapshotStatus - 2, // 57: ateapi.SnapshotConfig.preferred_fidelity:type_name -> ateapi.SnapshotFidelity - 42, // 58: ateapi.SnapshotConfig.golden_snapshot_config:type_name -> ateapi.GoldenSnapshotConfig - 5, // 59: ateapi.GoldenSnapshotConfig.mode:type_name -> ateapi.GoldenSnapshotMode - 46, // 60: ateapi.Container.env:type_name -> ateapi.EnvVar - 47, // 61: ateapi.Container.wakeup_probe:type_name -> ateapi.WakeupProbe - 59, // 62: ateapi.Container.volume_mounts:type_name -> ateapi.VolumeMount - 44, // 63: ateapi.Container.security_context:type_name -> ateapi.SecurityContext - 37, // 64: ateapi.Container.resources:type_name -> ateapi.ResourceRequirements - 45, // 65: ateapi.SecurityContext.capabilities:type_name -> ateapi.Capabilities - 48, // 66: ateapi.WakeupProbe.http_get:type_name -> ateapi.HttpGetAction - 52, // 67: ateapi.Volume.durable_dir:type_name -> ateapi.DurableDirVolumeSource - 50, // 68: ateapi.Volume.external:type_name -> ateapi.ExternalVolumeSource - 54, // 69: ateapi.Volume.system_info:type_name -> ateapi.SystemInfoVolumeSource - 51, // 70: ateapi.Volume.image:type_name -> ateapi.ImageVolumeSource - 53, // 71: ateapi.ExternalVolumeSource.template:type_name -> ateapi.ExternalVolumeTemplate - 55, // 72: ateapi.SystemInfoVolumeSource.data_sources:type_name -> ateapi.SystemInfoDataSource - 56, // 73: ateapi.SystemInfoDataSource.actor_metadata:type_name -> ateapi.ActorMetadataDataSource - 58, // 74: ateapi.SystemInfoDataSource.trust_bundle:type_name -> ateapi.TrustBundleDataSource - 57, // 75: ateapi.ActorMetadataDataSource.items:type_name -> ateapi.ActorMetadataItem - 6, // 76: ateapi.ActorMetadataItem.field:type_name -> ateapi.ActorMetadataField - 34, // 77: ateapi.CreateAtespaceRequest.atespace:type_name -> ateapi.Atespace - 35, // 78: ateapi.GetAtespaceRequest.atespace:type_name -> ateapi.ObjectRef - 96, // 79: ateapi.ListAtespacesRequest.options:type_name -> ateapi.ListOptions - 34, // 80: ateapi.ListAtespacesResponse.atespaces:type_name -> ateapi.Atespace - 35, // 81: ateapi.DeleteAtespaceRequest.atespace:type_name -> ateapi.ObjectRef - 95, // 82: ateapi.DeleteAtespaceRequest.options:type_name -> ateapi.DeleteOptions - 36, // 83: ateapi.CreateActorTemplateRequest.actor_template:type_name -> ateapi.ActorTemplate - 35, // 84: ateapi.GetActorTemplateRequest.actor_template:type_name -> ateapi.ObjectRef - 96, // 85: ateapi.ListActorTemplatesRequest.options:type_name -> ateapi.ListOptions - 36, // 86: ateapi.ListActorTemplatesResponse.actor_templates:type_name -> ateapi.ActorTemplate - 35, // 87: ateapi.DeleteActorTemplateRequest.actor_template:type_name -> ateapi.ObjectRef - 95, // 88: ateapi.DeleteActorTemplateRequest.options:type_name -> ateapi.DeleteOptions - 35, // 89: ateapi.GetActorRequest.actor:type_name -> ateapi.ObjectRef - 17, // 90: ateapi.CreateActorRequest.actor:type_name -> ateapi.Actor - 17, // 91: ateapi.UpdateActorRequest.actor:type_name -> ateapi.Actor - 35, // 92: ateapi.SuspendActorRequest.actor:type_name -> ateapi.ObjectRef - 75, // 93: ateapi.SuspendActorRequest.options:type_name -> ateapi.SuspendOptions - 17, // 94: ateapi.SuspendActorResponse.actor:type_name -> ateapi.Actor - 7, // 95: ateapi.SuspendOptions.mode:type_name -> ateapi.DurabilityMode - 35, // 96: ateapi.ResumeActorRequest.actor:type_name -> ateapi.ObjectRef - 17, // 97: ateapi.ResumeActorResponse.actor:type_name -> ateapi.Actor - 35, // 98: ateapi.RevertActorRequest.actor:type_name -> ateapi.ObjectRef - 17, // 99: ateapi.RevertActorResponse.actor:type_name -> ateapi.Actor - 35, // 100: ateapi.DeleteActorRequest.actor:type_name -> ateapi.ObjectRef - 95, // 101: ateapi.DeleteActorRequest.options:type_name -> ateapi.DeleteOptions - 35, // 102: ateapi.GetActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef - 35, // 103: ateapi.CreateActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef - 18, // 104: ateapi.CreateActorEgressPolicyRequest.egress_policy:type_name -> ateapi.EgressPolicy - 35, // 105: ateapi.UpdateActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef - 18, // 106: ateapi.UpdateActorEgressPolicyRequest.egress_policy:type_name -> ateapi.EgressPolicy - 35, // 107: ateapi.DeleteActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef - 95, // 108: ateapi.DeleteActorEgressPolicyRequest.options:type_name -> ateapi.DeleteOptions - 35, // 109: ateapi.GetTagRequest.tag:type_name -> ateapi.ObjectRef - 35, // 110: ateapi.MintActorJwtRequest.actor:type_name -> ateapi.ObjectRef - 154, // 111: ateapi.MintActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp - 35, // 112: ateapi.MintActorCertificateRequest.actor:type_name -> ateapi.ObjectRef - 96, // 113: ateapi.ListTagsRequest.options:type_name -> ateapi.ListOptions - 33, // 114: ateapi.ListTagsResponse.tags:type_name -> ateapi.Tag - 33, // 115: ateapi.CreateTagRequest.tag:type_name -> ateapi.Tag - 33, // 116: ateapi.UpdateTagRequest.tag:type_name -> ateapi.Tag - 35, // 117: ateapi.DeleteTagRequest.tag:type_name -> ateapi.ObjectRef - 95, // 118: ateapi.DeleteTagRequest.options:type_name -> ateapi.DeleteOptions - 35, // 119: ateapi.ListWorkerActorAssignmentsRequest.worker:type_name -> ateapi.ObjectRef - 96, // 120: ateapi.ListWorkerActorAssignmentsRequest.options:type_name -> ateapi.ListOptions - 121, // 121: ateapi.ListWorkerActorAssignmentsResponse.actor_assignments:type_name -> ateapi.ActorAssignment - 96, // 122: ateapi.ListWorkersRequest.options:type_name -> ateapi.ListOptions - 113, // 123: ateapi.ListWorkersResponse.workers:type_name -> ateapi.Worker - 35, // 124: ateapi.GetWorkerRequest.worker:type_name -> ateapi.ObjectRef - 113, // 125: ateapi.CreateWorkerRequest.worker:type_name -> ateapi.Worker - 113, // 126: ateapi.UpdateWorkerRequest.worker:type_name -> ateapi.Worker - 35, // 127: ateapi.DeleteWorkerRequest.worker:type_name -> ateapi.ObjectRef - 95, // 128: ateapi.DeleteWorkerRequest.options:type_name -> ateapi.DeleteOptions - 35, // 129: ateapi.DrainWorkerRequest.worker:type_name -> ateapi.ObjectRef - 113, // 130: ateapi.DrainWorkerResponse.worker:type_name -> ateapi.Worker - 35, // 131: ateapi.MarkWorkerAvailableRequest.worker:type_name -> ateapi.ObjectRef - 113, // 132: ateapi.MarkWorkerAvailableResponse.worker:type_name -> ateapi.Worker - 35, // 133: ateapi.MarkWorkerUnavailableRequest.worker:type_name -> ateapi.ObjectRef - 113, // 134: ateapi.MarkWorkerUnavailableResponse.worker:type_name -> ateapi.Worker - 96, // 135: ateapi.ListActorsRequest.options:type_name -> ateapi.ListOptions - 17, // 136: ateapi.ListActorsResponse.actors:type_name -> ateapi.Actor - 14, // 137: ateapi.Worker.metadata:type_name -> ateapi.ResourceMetadata - 153, // 138: ateapi.Worker.labels:type_name -> ateapi.Worker.LabelsEntry - 114, // 139: ateapi.Worker.status:type_name -> ateapi.WorkerStatus - 8, // 140: ateapi.WorkerStatus.state:type_name -> ateapi.WorkerState - 120, // 141: ateapi.WorkerStatus.capacity:type_name -> ateapi.WorkerResources - 120, // 142: ateapi.WorkerStatus.allocated:type_name -> ateapi.WorkerResources - 115, // 143: ateapi.WorkerStatus.sandbox_classes:type_name -> ateapi.WorkerSandboxClass - 116, // 144: ateapi.WorkerSandboxClass.default_runtime:type_name -> ateapi.WorkerSandboxRuntime - 116, // 145: ateapi.WorkerSandboxClass.restorable_runtimes:type_name -> ateapi.WorkerSandboxRuntime - 118, // 146: ateapi.WorkerSandboxRuntime.version:type_name -> ateapi.VersionedSandboxCompat - 118, // 147: ateapi.ActorSandboxRuntime.version:type_name -> ateapi.VersionedSandboxCompat - 119, // 148: ateapi.VersionedSandboxCompat.attributes:type_name -> ateapi.AttributeEntry - 14, // 149: ateapi.ActorAssignment.metadata:type_name -> ateapi.ResourceMetadata - 35, // 150: ateapi.ActorAssignment.actor:type_name -> ateapi.ObjectRef - 38, // 151: ateapi.ActorAssignment.resources:type_name -> ateapi.Resources - 35, // 152: ateapi.AcquireWorkerEpochRequest.worker:type_name -> ateapi.ObjectRef - 35, // 153: ateapi.RegisterWorkerRequest.worker:type_name -> ateapi.ObjectRef - 120, // 154: ateapi.RegisterWorkerRequest.capacity:type_name -> ateapi.WorkerResources - 113, // 155: ateapi.RegisterWorkerResponse.worker:type_name -> ateapi.Worker - 35, // 156: ateapi.SetWorkerSandboxRuntimesRequest.worker:type_name -> ateapi.ObjectRef - 115, // 157: ateapi.SetWorkerSandboxRuntimesRequest.sandbox_classes:type_name -> ateapi.WorkerSandboxClass - 113, // 158: ateapi.SetWorkerSandboxRuntimesResponse.worker:type_name -> ateapi.Worker - 35, // 159: ateapi.MintWorkerActorCertificateRequest.actor:type_name -> ateapi.ObjectRef - 35, // 160: ateapi.MintWorkerActorCertificateRequest.worker:type_name -> ateapi.ObjectRef - 35, // 161: ateapi.MintWorkerActorJwtRequest.actor:type_name -> ateapi.ObjectRef - 154, // 162: ateapi.MintWorkerActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp - 35, // 163: ateapi.RequestActorSuspendRequest.worker:type_name -> ateapi.ObjectRef - 35, // 164: ateapi.RequestActorSuspendRequest.actor:type_name -> ateapi.ObjectRef - 17, // 165: ateapi.RequestActorSuspendResponse.actor:type_name -> ateapi.Actor - 35, // 166: ateapi.ReportActorCrashedRequest.worker:type_name -> ateapi.ObjectRef - 35, // 167: ateapi.ReportActorCrashedRequest.actor:type_name -> ateapi.ObjectRef - 17, // 168: ateapi.ReportActorCrashedResponse.actor:type_name -> ateapi.Actor - 35, // 169: ateapi.ReportActorSnapshotStateRequest.actor:type_name -> ateapi.ObjectRef - 138, // 170: ateapi.ReportActorSnapshotStateRequest.state:type_name -> ateapi.ActorSnapshotState - 139, // 171: ateapi.ActorSnapshotState.latest_local:type_name -> ateapi.SnapshotReport - 139, // 172: ateapi.ActorSnapshotState.uploading:type_name -> ateapi.SnapshotReport - 139, // 173: ateapi.ActorSnapshotState.latest_durable:type_name -> ateapi.SnapshotReport - 154, // 174: ateapi.ActorSnapshotState.upload_due_time:type_name -> google.protobuf.Timestamp - 2, // 175: ateapi.SnapshotReport.fidelity:type_name -> ateapi.SnapshotFidelity - 10, // 176: ateapi.SnapshotReport.object:type_name -> ateapi.ObjectSnapshot - 154, // 177: ateapi.SnapshotReport.local_commit_time:type_name -> google.protobuf.Timestamp - 154, // 178: ateapi.SnapshotReport.durable_complete_time:type_name -> google.protobuf.Timestamp - 14, // 179: ateapi.AccessPolicy.metadata:type_name -> ateapi.ResourceMetadata - 141, // 180: ateapi.AccessPolicy.bindings:type_name -> ateapi.Binding - 140, // 181: ateapi.CreateGlobalAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy - 140, // 182: ateapi.UpdateGlobalAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy - 35, // 183: ateapi.GetAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef - 35, // 184: ateapi.CreateAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef - 140, // 185: ateapi.CreateAtespaceAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy - 35, // 186: ateapi.UpdateAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef - 140, // 187: ateapi.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy - 35, // 188: ateapi.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef - 95, // 189: ateapi.DeleteAtespaceAccessPolicyRequest.options:type_name -> ateapi.DeleteOptions - 9, // 190: ateapi.ResourceAnnotation.scope:type_name -> ateapi.Scope - 155, // 191: ateapi.resource:extendee -> google.protobuf.MessageOptions - 156, // 192: ateapi.method:extendee -> google.protobuf.MethodOptions - 149, // 193: ateapi.resource:type_name -> ateapi.ResourceAnnotation - 150, // 194: ateapi.method:type_name -> ateapi.MethodAnnotation - 70, // 195: ateapi.Control.GetActor:input_type -> ateapi.GetActorRequest - 71, // 196: ateapi.Control.CreateActor:input_type -> ateapi.CreateActorRequest - 72, // 197: ateapi.Control.UpdateActor:input_type -> ateapi.UpdateActorRequest - 73, // 198: ateapi.Control.SuspendActor:input_type -> ateapi.SuspendActorRequest - 76, // 199: ateapi.Control.ResumeActor:input_type -> ateapi.ResumeActorRequest - 78, // 200: ateapi.Control.RevertActor:input_type -> ateapi.RevertActorRequest - 80, // 201: ateapi.Control.DeleteActor:input_type -> ateapi.DeleteActorRequest - 81, // 202: ateapi.Control.GetActorEgressPolicy:input_type -> ateapi.GetActorEgressPolicyRequest - 82, // 203: ateapi.Control.CreateActorEgressPolicy:input_type -> ateapi.CreateActorEgressPolicyRequest - 83, // 204: ateapi.Control.UpdateActorEgressPolicy:input_type -> ateapi.UpdateActorEgressPolicyRequest - 84, // 205: ateapi.Control.DeleteActorEgressPolicy:input_type -> ateapi.DeleteActorEgressPolicyRequest - 86, // 206: ateapi.Control.MintActorJwt:input_type -> ateapi.MintActorJwtRequest - 88, // 207: ateapi.Control.MintActorCertificate:input_type -> ateapi.MintActorCertificateRequest - 92, // 208: ateapi.Control.CreateTag:input_type -> ateapi.CreateTagRequest - 85, // 209: ateapi.Control.GetTag:input_type -> ateapi.GetTagRequest - 90, // 210: ateapi.Control.ListTags:input_type -> ateapi.ListTagsRequest - 93, // 211: ateapi.Control.UpdateTag:input_type -> ateapi.UpdateTagRequest - 94, // 212: ateapi.Control.DeleteTag:input_type -> ateapi.DeleteTagRequest - 99, // 213: ateapi.Control.ListWorkers:input_type -> ateapi.ListWorkersRequest - 101, // 214: ateapi.Control.GetWorker:input_type -> ateapi.GetWorkerRequest - 102, // 215: ateapi.Control.CreateWorker:input_type -> ateapi.CreateWorkerRequest - 103, // 216: ateapi.Control.UpdateWorker:input_type -> ateapi.UpdateWorkerRequest - 104, // 217: ateapi.Control.DeleteWorker:input_type -> ateapi.DeleteWorkerRequest - 105, // 218: ateapi.Control.DrainWorker:input_type -> ateapi.DrainWorkerRequest - 107, // 219: ateapi.Control.MarkWorkerAvailable:input_type -> ateapi.MarkWorkerAvailableRequest - 109, // 220: ateapi.Control.MarkWorkerUnavailable:input_type -> ateapi.MarkWorkerUnavailableRequest - 97, // 221: ateapi.Control.ListWorkerActorAssignments:input_type -> ateapi.ListWorkerActorAssignmentsRequest - 111, // 222: ateapi.Control.ListActors:input_type -> ateapi.ListActorsRequest - 60, // 223: ateapi.Control.CreateAtespace:input_type -> ateapi.CreateAtespaceRequest - 61, // 224: ateapi.Control.GetAtespace:input_type -> ateapi.GetAtespaceRequest - 62, // 225: ateapi.Control.ListAtespaces:input_type -> ateapi.ListAtespacesRequest - 64, // 226: ateapi.Control.DeleteAtespace:input_type -> ateapi.DeleteAtespaceRequest - 65, // 227: ateapi.Control.CreateActorTemplate:input_type -> ateapi.CreateActorTemplateRequest - 66, // 228: ateapi.Control.GetActorTemplate:input_type -> ateapi.GetActorTemplateRequest - 67, // 229: ateapi.Control.ListActorTemplates:input_type -> ateapi.ListActorTemplatesRequest - 69, // 230: ateapi.Control.DeleteActorTemplate:input_type -> ateapi.DeleteActorTemplateRequest - 142, // 231: ateapi.Control.GetGlobalAccessPolicy:input_type -> ateapi.GetGlobalAccessPolicyRequest - 143, // 232: ateapi.Control.CreateGlobalAccessPolicy:input_type -> ateapi.CreateGlobalAccessPolicyRequest - 144, // 233: ateapi.Control.UpdateGlobalAccessPolicy:input_type -> ateapi.UpdateGlobalAccessPolicyRequest - 145, // 234: ateapi.Control.GetAtespaceAccessPolicy:input_type -> ateapi.GetAtespaceAccessPolicyRequest - 146, // 235: ateapi.Control.CreateAtespaceAccessPolicy:input_type -> ateapi.CreateAtespaceAccessPolicyRequest - 147, // 236: ateapi.Control.UpdateAtespaceAccessPolicy:input_type -> ateapi.UpdateAtespaceAccessPolicyRequest - 148, // 237: ateapi.Control.DeleteAtespaceAccessPolicy:input_type -> ateapi.DeleteAtespaceAccessPolicyRequest - 122, // 238: ateapi.WorkerService.AcquireWorkerEpoch:input_type -> ateapi.AcquireWorkerEpochRequest - 124, // 239: ateapi.WorkerService.RegisterWorker:input_type -> ateapi.RegisterWorkerRequest - 126, // 240: ateapi.WorkerService.SetWorkerSandboxRuntimes:input_type -> ateapi.SetWorkerSandboxRuntimesRequest - 128, // 241: ateapi.WorkerService.MintWorkerActorCertificate:input_type -> ateapi.MintWorkerActorCertificateRequest - 130, // 242: ateapi.WorkerService.MintWorkerActorJwt:input_type -> ateapi.MintWorkerActorJwtRequest - 132, // 243: ateapi.WorkerService.RequestActorSuspend:input_type -> ateapi.RequestActorSuspendRequest - 136, // 244: ateapi.WorkerService.ReportActorSnapshotState:input_type -> ateapi.ReportActorSnapshotStateRequest - 134, // 245: ateapi.WorkerService.ReportActorCrashed:input_type -> ateapi.ReportActorCrashedRequest - 17, // 246: ateapi.Control.GetActor:output_type -> ateapi.Actor - 17, // 247: ateapi.Control.CreateActor:output_type -> ateapi.Actor - 17, // 248: ateapi.Control.UpdateActor:output_type -> ateapi.Actor - 74, // 249: ateapi.Control.SuspendActor:output_type -> ateapi.SuspendActorResponse - 77, // 250: ateapi.Control.ResumeActor:output_type -> ateapi.ResumeActorResponse - 79, // 251: ateapi.Control.RevertActor:output_type -> ateapi.RevertActorResponse - 17, // 252: ateapi.Control.DeleteActor:output_type -> ateapi.Actor - 18, // 253: ateapi.Control.GetActorEgressPolicy:output_type -> ateapi.EgressPolicy - 18, // 254: ateapi.Control.CreateActorEgressPolicy:output_type -> ateapi.EgressPolicy - 18, // 255: ateapi.Control.UpdateActorEgressPolicy:output_type -> ateapi.EgressPolicy - 18, // 256: ateapi.Control.DeleteActorEgressPolicy:output_type -> ateapi.EgressPolicy - 87, // 257: ateapi.Control.MintActorJwt:output_type -> ateapi.MintActorJwtResponse - 89, // 258: ateapi.Control.MintActorCertificate:output_type -> ateapi.MintActorCertificateResponse - 33, // 259: ateapi.Control.CreateTag:output_type -> ateapi.Tag - 33, // 260: ateapi.Control.GetTag:output_type -> ateapi.Tag - 91, // 261: ateapi.Control.ListTags:output_type -> ateapi.ListTagsResponse - 33, // 262: ateapi.Control.UpdateTag:output_type -> ateapi.Tag - 33, // 263: ateapi.Control.DeleteTag:output_type -> ateapi.Tag - 100, // 264: ateapi.Control.ListWorkers:output_type -> ateapi.ListWorkersResponse - 113, // 265: ateapi.Control.GetWorker:output_type -> ateapi.Worker - 113, // 266: ateapi.Control.CreateWorker:output_type -> ateapi.Worker - 113, // 267: ateapi.Control.UpdateWorker:output_type -> ateapi.Worker - 113, // 268: ateapi.Control.DeleteWorker:output_type -> ateapi.Worker - 106, // 269: ateapi.Control.DrainWorker:output_type -> ateapi.DrainWorkerResponse - 108, // 270: ateapi.Control.MarkWorkerAvailable:output_type -> ateapi.MarkWorkerAvailableResponse - 110, // 271: ateapi.Control.MarkWorkerUnavailable:output_type -> ateapi.MarkWorkerUnavailableResponse - 98, // 272: ateapi.Control.ListWorkerActorAssignments:output_type -> ateapi.ListWorkerActorAssignmentsResponse - 112, // 273: ateapi.Control.ListActors:output_type -> ateapi.ListActorsResponse - 34, // 274: ateapi.Control.CreateAtespace:output_type -> ateapi.Atespace - 34, // 275: ateapi.Control.GetAtespace:output_type -> ateapi.Atespace - 63, // 276: ateapi.Control.ListAtespaces:output_type -> ateapi.ListAtespacesResponse - 34, // 277: ateapi.Control.DeleteAtespace:output_type -> ateapi.Atespace - 36, // 278: ateapi.Control.CreateActorTemplate:output_type -> ateapi.ActorTemplate - 36, // 279: ateapi.Control.GetActorTemplate:output_type -> ateapi.ActorTemplate - 68, // 280: ateapi.Control.ListActorTemplates:output_type -> ateapi.ListActorTemplatesResponse - 36, // 281: ateapi.Control.DeleteActorTemplate:output_type -> ateapi.ActorTemplate - 140, // 282: ateapi.Control.GetGlobalAccessPolicy:output_type -> ateapi.AccessPolicy - 140, // 283: ateapi.Control.CreateGlobalAccessPolicy:output_type -> ateapi.AccessPolicy - 140, // 284: ateapi.Control.UpdateGlobalAccessPolicy:output_type -> ateapi.AccessPolicy - 140, // 285: ateapi.Control.GetAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy - 140, // 286: ateapi.Control.CreateAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy - 140, // 287: ateapi.Control.UpdateAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy - 140, // 288: ateapi.Control.DeleteAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy - 123, // 289: ateapi.WorkerService.AcquireWorkerEpoch:output_type -> ateapi.AcquireWorkerEpochResponse - 125, // 290: ateapi.WorkerService.RegisterWorker:output_type -> ateapi.RegisterWorkerResponse - 127, // 291: ateapi.WorkerService.SetWorkerSandboxRuntimes:output_type -> ateapi.SetWorkerSandboxRuntimesResponse - 129, // 292: ateapi.WorkerService.MintWorkerActorCertificate:output_type -> ateapi.MintWorkerActorCertificateResponse - 131, // 293: ateapi.WorkerService.MintWorkerActorJwt:output_type -> ateapi.MintWorkerActorJwtResponse - 133, // 294: ateapi.WorkerService.RequestActorSuspend:output_type -> ateapi.RequestActorSuspendResponse - 137, // 295: ateapi.WorkerService.ReportActorSnapshotState:output_type -> ateapi.ReportActorSnapshotStateResponse - 135, // 296: ateapi.WorkerService.ReportActorCrashed:output_type -> ateapi.ReportActorCrashedResponse +var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ + 1, // 0: substrate.ateapi.v1.SnapshotStorage.status:type_name -> substrate.ateapi.v1.SnapshotStorageStatus + 10, // 1: substrate.ateapi.v1.SnapshotStorage.object:type_name -> substrate.ateapi.v1.ObjectSnapshot + 0, // 2: substrate.ateapi.v1.Snapshot.owner:type_name -> substrate.ateapi.v1.SnapshotOwner + 2, // 3: substrate.ateapi.v1.Snapshot.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity + 11, // 4: substrate.ateapi.v1.Snapshot.durable_snapshot:type_name -> substrate.ateapi.v1.SnapshotStorage + 117, // 5: substrate.ateapi.v1.Snapshot.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime + 151, // 6: substrate.ateapi.v1.Selector.match_labels:type_name -> substrate.ateapi.v1.Selector.MatchLabelsEntry + 154, // 7: substrate.ateapi.v1.ResourceMetadata.create_time:type_name -> google.protobuf.Timestamp + 154, // 8: substrate.ateapi.v1.ResourceMetadata.update_time:type_name -> google.protobuf.Timestamp + 154, // 9: substrate.ateapi.v1.ResourceMetadata.delete_time:type_name -> google.protobuf.Timestamp + 16, // 10: substrate.ateapi.v1.ExternalVolumes.volumes:type_name -> substrate.ateapi.v1.ExternalVolumeStatus + 152, // 11: substrate.ateapi.v1.ExternalVolumeStatus.volume_context:type_name -> substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry + 14, // 12: substrate.ateapi.v1.Actor.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 35, // 13: substrate.ateapi.v1.Actor.actor_template:type_name -> substrate.ateapi.v1.ObjectRef + 13, // 14: substrate.ateapi.v1.Actor.worker_selector:type_name -> substrate.ateapi.v1.Selector + 35, // 15: substrate.ateapi.v1.Actor.source_tag:type_name -> substrate.ateapi.v1.ObjectRef + 29, // 16: substrate.ateapi.v1.Actor.status:type_name -> substrate.ateapi.v1.ActorStatus + 14, // 17: substrate.ateapi.v1.EgressPolicy.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 20, // 18: substrate.ateapi.v1.EgressPolicy.rules:type_name -> substrate.ateapi.v1.EgressRule + 20, // 19: substrate.ateapi.v1.EgressPolicyTemplate.rules:type_name -> substrate.ateapi.v1.EgressRule + 21, // 20: substrate.ateapi.v1.EgressRule.http:type_name -> substrate.ateapi.v1.HttpRule + 22, // 21: substrate.ateapi.v1.EgressRule.https:type_name -> substrate.ateapi.v1.HttpsRule + 23, // 22: substrate.ateapi.v1.EgressRule.tls_passthrough:type_name -> substrate.ateapi.v1.TlsPassthroughRule + 24, // 23: substrate.ateapi.v1.HttpRule.ports:type_name -> substrate.ateapi.v1.Ports + 26, // 24: substrate.ateapi.v1.HttpRule.effects:type_name -> substrate.ateapi.v1.HttpRuleEffects + 24, // 25: substrate.ateapi.v1.HttpsRule.ports:type_name -> substrate.ateapi.v1.Ports + 26, // 26: substrate.ateapi.v1.HttpsRule.effects:type_name -> substrate.ateapi.v1.HttpRuleEffects + 24, // 27: substrate.ateapi.v1.TlsPassthroughRule.ports:type_name -> substrate.ateapi.v1.Ports + 25, // 28: substrate.ateapi.v1.Ports.all:type_name -> substrate.ateapi.v1.AllPorts + 27, // 29: substrate.ateapi.v1.HttpRuleEffects.replace_headers:type_name -> substrate.ateapi.v1.CredentialHeader + 28, // 30: substrate.ateapi.v1.CredentialHeader.actor_jwt:type_name -> substrate.ateapi.v1.ActorJwtSource + 4, // 31: substrate.ateapi.v1.ActorStatus.state:type_name -> substrate.ateapi.v1.ActorState + 31, // 32: substrate.ateapi.v1.ActorStatus.worker_assignment:type_name -> substrate.ateapi.v1.WorkerAssignment + 15, // 33: substrate.ateapi.v1.ActorStatus.external_volumes:type_name -> substrate.ateapi.v1.ExternalVolumes + 30, // 34: substrate.ateapi.v1.ActorStatus.crash:type_name -> substrate.ateapi.v1.ActorCrash + 12, // 35: substrate.ateapi.v1.ActorStatus.snapshots:type_name -> substrate.ateapi.v1.Snapshot + 154, // 36: substrate.ateapi.v1.ActorCrash.crash_time:type_name -> google.protobuf.Timestamp + 35, // 37: substrate.ateapi.v1.WorkerAssignment.worker:type_name -> substrate.ateapi.v1.ObjectRef + 117, // 38: substrate.ateapi.v1.WorkerAssignment.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime + 12, // 39: substrate.ateapi.v1.TagStatus.snapshot:type_name -> substrate.ateapi.v1.Snapshot + 14, // 40: substrate.ateapi.v1.Tag.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 32, // 41: substrate.ateapi.v1.Tag.status:type_name -> substrate.ateapi.v1.TagStatus + 3, // 42: substrate.ateapi.v1.Tag.scope:type_name -> substrate.ateapi.v1.TagScope + 35, // 43: substrate.ateapi.v1.Tag.source_actor:type_name -> substrate.ateapi.v1.ObjectRef + 14, // 44: substrate.ateapi.v1.Atespace.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 14, // 45: substrate.ateapi.v1.ActorTemplate.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 13, // 46: substrate.ateapi.v1.ActorTemplate.worker_selector:type_name -> substrate.ateapi.v1.Selector + 43, // 47: substrate.ateapi.v1.ActorTemplate.containers:type_name -> substrate.ateapi.v1.Container + 49, // 48: substrate.ateapi.v1.ActorTemplate.volumes:type_name -> substrate.ateapi.v1.Volume + 41, // 49: substrate.ateapi.v1.ActorTemplate.snapshot_config:type_name -> substrate.ateapi.v1.SnapshotConfig + 37, // 50: substrate.ateapi.v1.ActorTemplate.resources:type_name -> substrate.ateapi.v1.ResourceRequirements + 19, // 51: substrate.ateapi.v1.ActorTemplate.golden_egress_policy:type_name -> substrate.ateapi.v1.EgressPolicyTemplate + 40, // 52: substrate.ateapi.v1.ActorTemplate.status:type_name -> substrate.ateapi.v1.ActorTemplateStatus + 38, // 53: substrate.ateapi.v1.ResourceRequirements.limits:type_name -> substrate.ateapi.v1.Resources + 35, // 54: substrate.ateapi.v1.GoldenSnapshotStatus.golden_tag:type_name -> substrate.ateapi.v1.ObjectRef + 154, // 55: substrate.ateapi.v1.GoldenSnapshotStatus.snapshot_time:type_name -> google.protobuf.Timestamp + 39, // 56: substrate.ateapi.v1.ActorTemplateStatus.golden_snapshot_status:type_name -> substrate.ateapi.v1.GoldenSnapshotStatus + 2, // 57: substrate.ateapi.v1.SnapshotConfig.preferred_fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity + 42, // 58: substrate.ateapi.v1.SnapshotConfig.golden_snapshot_config:type_name -> substrate.ateapi.v1.GoldenSnapshotConfig + 5, // 59: substrate.ateapi.v1.GoldenSnapshotConfig.mode:type_name -> substrate.ateapi.v1.GoldenSnapshotMode + 46, // 60: substrate.ateapi.v1.Container.env:type_name -> substrate.ateapi.v1.EnvVar + 47, // 61: substrate.ateapi.v1.Container.wakeup_probe:type_name -> substrate.ateapi.v1.WakeupProbe + 59, // 62: substrate.ateapi.v1.Container.volume_mounts:type_name -> substrate.ateapi.v1.VolumeMount + 44, // 63: substrate.ateapi.v1.Container.security_context:type_name -> substrate.ateapi.v1.SecurityContext + 37, // 64: substrate.ateapi.v1.Container.resources:type_name -> substrate.ateapi.v1.ResourceRequirements + 45, // 65: substrate.ateapi.v1.SecurityContext.capabilities:type_name -> substrate.ateapi.v1.Capabilities + 48, // 66: substrate.ateapi.v1.WakeupProbe.http_get:type_name -> substrate.ateapi.v1.HttpGetAction + 52, // 67: substrate.ateapi.v1.Volume.durable_dir:type_name -> substrate.ateapi.v1.DurableDirVolumeSource + 50, // 68: substrate.ateapi.v1.Volume.external:type_name -> substrate.ateapi.v1.ExternalVolumeSource + 54, // 69: substrate.ateapi.v1.Volume.system_info:type_name -> substrate.ateapi.v1.SystemInfoVolumeSource + 51, // 70: substrate.ateapi.v1.Volume.image:type_name -> substrate.ateapi.v1.ImageVolumeSource + 53, // 71: substrate.ateapi.v1.ExternalVolumeSource.template:type_name -> substrate.ateapi.v1.ExternalVolumeTemplate + 55, // 72: substrate.ateapi.v1.SystemInfoVolumeSource.data_sources:type_name -> substrate.ateapi.v1.SystemInfoDataSource + 56, // 73: substrate.ateapi.v1.SystemInfoDataSource.actor_metadata:type_name -> substrate.ateapi.v1.ActorMetadataDataSource + 58, // 74: substrate.ateapi.v1.SystemInfoDataSource.trust_bundle:type_name -> substrate.ateapi.v1.TrustBundleDataSource + 57, // 75: substrate.ateapi.v1.ActorMetadataDataSource.items:type_name -> substrate.ateapi.v1.ActorMetadataItem + 6, // 76: substrate.ateapi.v1.ActorMetadataItem.field:type_name -> substrate.ateapi.v1.ActorMetadataField + 34, // 77: substrate.ateapi.v1.CreateAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.Atespace + 35, // 78: substrate.ateapi.v1.GetAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 96, // 79: substrate.ateapi.v1.ListAtespacesRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 34, // 80: substrate.ateapi.v1.ListAtespacesResponse.atespaces:type_name -> substrate.ateapi.v1.Atespace + 35, // 81: substrate.ateapi.v1.DeleteAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 95, // 82: substrate.ateapi.v1.DeleteAtespaceRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 36, // 83: substrate.ateapi.v1.CreateActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ActorTemplate + 35, // 84: substrate.ateapi.v1.GetActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef + 96, // 85: substrate.ateapi.v1.ListActorTemplatesRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 36, // 86: substrate.ateapi.v1.ListActorTemplatesResponse.actor_templates:type_name -> substrate.ateapi.v1.ActorTemplate + 35, // 87: substrate.ateapi.v1.DeleteActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef + 95, // 88: substrate.ateapi.v1.DeleteActorTemplateRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 89: substrate.ateapi.v1.GetActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 90: substrate.ateapi.v1.CreateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor + 17, // 91: substrate.ateapi.v1.UpdateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 92: substrate.ateapi.v1.SuspendActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 75, // 93: substrate.ateapi.v1.SuspendActorRequest.options:type_name -> substrate.ateapi.v1.SuspendOptions + 17, // 94: substrate.ateapi.v1.SuspendActorResponse.actor:type_name -> substrate.ateapi.v1.Actor + 7, // 95: substrate.ateapi.v1.SuspendOptions.mode:type_name -> substrate.ateapi.v1.DurabilityMode + 35, // 96: substrate.ateapi.v1.ResumeActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 97: substrate.ateapi.v1.ResumeActorResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 98: substrate.ateapi.v1.RevertActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 99: substrate.ateapi.v1.RevertActorResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 100: substrate.ateapi.v1.DeleteActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 95, // 101: substrate.ateapi.v1.DeleteActorRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 102: substrate.ateapi.v1.GetActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 103: substrate.ateapi.v1.CreateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 18, // 104: substrate.ateapi.v1.CreateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy + 35, // 105: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 18, // 106: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy + 35, // 107: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 95, // 108: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 109: substrate.ateapi.v1.GetTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 110: substrate.ateapi.v1.MintActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 154, // 111: substrate.ateapi.v1.MintActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp + 35, // 112: substrate.ateapi.v1.MintActorCertificateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 96, // 113: substrate.ateapi.v1.ListTagsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 33, // 114: substrate.ateapi.v1.ListTagsResponse.tags:type_name -> substrate.ateapi.v1.Tag + 33, // 115: substrate.ateapi.v1.CreateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag + 33, // 116: substrate.ateapi.v1.UpdateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag + 35, // 117: substrate.ateapi.v1.DeleteTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef + 95, // 118: substrate.ateapi.v1.DeleteTagRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 119: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 96, // 120: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 121, // 121: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse.actor_assignments:type_name -> substrate.ateapi.v1.ActorAssignment + 96, // 122: substrate.ateapi.v1.ListWorkersRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 113, // 123: substrate.ateapi.v1.ListWorkersResponse.workers:type_name -> substrate.ateapi.v1.Worker + 35, // 124: substrate.ateapi.v1.GetWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 113, // 125: substrate.ateapi.v1.CreateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker + 113, // 126: substrate.ateapi.v1.UpdateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 127: substrate.ateapi.v1.DeleteWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 95, // 128: substrate.ateapi.v1.DeleteWorkerRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 129: substrate.ateapi.v1.DrainWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 113, // 130: substrate.ateapi.v1.DrainWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 131: substrate.ateapi.v1.MarkWorkerAvailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 113, // 132: substrate.ateapi.v1.MarkWorkerAvailableResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 133: substrate.ateapi.v1.MarkWorkerUnavailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 113, // 134: substrate.ateapi.v1.MarkWorkerUnavailableResponse.worker:type_name -> substrate.ateapi.v1.Worker + 96, // 135: substrate.ateapi.v1.ListActorsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 17, // 136: substrate.ateapi.v1.ListActorsResponse.actors:type_name -> substrate.ateapi.v1.Actor + 14, // 137: substrate.ateapi.v1.Worker.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 153, // 138: substrate.ateapi.v1.Worker.labels:type_name -> substrate.ateapi.v1.Worker.LabelsEntry + 114, // 139: substrate.ateapi.v1.Worker.status:type_name -> substrate.ateapi.v1.WorkerStatus + 8, // 140: substrate.ateapi.v1.WorkerStatus.state:type_name -> substrate.ateapi.v1.WorkerState + 120, // 141: substrate.ateapi.v1.WorkerStatus.capacity:type_name -> substrate.ateapi.v1.WorkerResources + 120, // 142: substrate.ateapi.v1.WorkerStatus.allocated:type_name -> substrate.ateapi.v1.WorkerResources + 115, // 143: substrate.ateapi.v1.WorkerStatus.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass + 116, // 144: substrate.ateapi.v1.WorkerSandboxClass.default_runtime:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime + 116, // 145: substrate.ateapi.v1.WorkerSandboxClass.restorable_runtimes:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime + 118, // 146: substrate.ateapi.v1.WorkerSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat + 118, // 147: substrate.ateapi.v1.ActorSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat + 119, // 148: substrate.ateapi.v1.VersionedSandboxCompat.attributes:type_name -> substrate.ateapi.v1.AttributeEntry + 14, // 149: substrate.ateapi.v1.ActorAssignment.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 35, // 150: substrate.ateapi.v1.ActorAssignment.actor:type_name -> substrate.ateapi.v1.ObjectRef + 38, // 151: substrate.ateapi.v1.ActorAssignment.resources:type_name -> substrate.ateapi.v1.Resources + 35, // 152: substrate.ateapi.v1.AcquireWorkerEpochRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 153: substrate.ateapi.v1.RegisterWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 120, // 154: substrate.ateapi.v1.RegisterWorkerRequest.capacity:type_name -> substrate.ateapi.v1.WorkerResources + 113, // 155: substrate.ateapi.v1.RegisterWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 156: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 115, // 157: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass + 113, // 158: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 159: substrate.ateapi.v1.MintWorkerActorCertificateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 160: substrate.ateapi.v1.MintWorkerActorCertificateRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 161: substrate.ateapi.v1.MintWorkerActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 154, // 162: substrate.ateapi.v1.MintWorkerActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp + 35, // 163: substrate.ateapi.v1.RequestActorSuspendRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 164: substrate.ateapi.v1.RequestActorSuspendRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 165: substrate.ateapi.v1.RequestActorSuspendResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 166: substrate.ateapi.v1.ReportActorCrashedRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 167: substrate.ateapi.v1.ReportActorCrashedRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 168: substrate.ateapi.v1.ReportActorCrashedResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 169: substrate.ateapi.v1.ReportActorSnapshotStateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 138, // 170: substrate.ateapi.v1.ReportActorSnapshotStateRequest.state:type_name -> substrate.ateapi.v1.ActorSnapshotState + 139, // 171: substrate.ateapi.v1.ActorSnapshotState.latest_local:type_name -> substrate.ateapi.v1.SnapshotReport + 139, // 172: substrate.ateapi.v1.ActorSnapshotState.uploading:type_name -> substrate.ateapi.v1.SnapshotReport + 139, // 173: substrate.ateapi.v1.ActorSnapshotState.latest_durable:type_name -> substrate.ateapi.v1.SnapshotReport + 154, // 174: substrate.ateapi.v1.ActorSnapshotState.upload_due_time:type_name -> google.protobuf.Timestamp + 2, // 175: substrate.ateapi.v1.SnapshotReport.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity + 10, // 176: substrate.ateapi.v1.SnapshotReport.object:type_name -> substrate.ateapi.v1.ObjectSnapshot + 154, // 177: substrate.ateapi.v1.SnapshotReport.local_commit_time:type_name -> google.protobuf.Timestamp + 154, // 178: substrate.ateapi.v1.SnapshotReport.durable_complete_time:type_name -> google.protobuf.Timestamp + 14, // 179: substrate.ateapi.v1.AccessPolicy.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 141, // 180: substrate.ateapi.v1.AccessPolicy.bindings:type_name -> substrate.ateapi.v1.Binding + 140, // 181: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 140, // 182: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 183: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 184: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 140, // 185: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 186: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 140, // 187: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 188: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 95, // 189: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 9, // 190: substrate.ateapi.v1.ResourceAnnotation.scope:type_name -> substrate.ateapi.v1.Scope + 155, // 191: substrate.ateapi.v1.resource:extendee -> google.protobuf.MessageOptions + 156, // 192: substrate.ateapi.v1.method:extendee -> google.protobuf.MethodOptions + 149, // 193: substrate.ateapi.v1.resource:type_name -> substrate.ateapi.v1.ResourceAnnotation + 150, // 194: substrate.ateapi.v1.method:type_name -> substrate.ateapi.v1.MethodAnnotation + 70, // 195: substrate.ateapi.v1.Control.GetActor:input_type -> substrate.ateapi.v1.GetActorRequest + 71, // 196: substrate.ateapi.v1.Control.CreateActor:input_type -> substrate.ateapi.v1.CreateActorRequest + 72, // 197: substrate.ateapi.v1.Control.UpdateActor:input_type -> substrate.ateapi.v1.UpdateActorRequest + 73, // 198: substrate.ateapi.v1.Control.SuspendActor:input_type -> substrate.ateapi.v1.SuspendActorRequest + 76, // 199: substrate.ateapi.v1.Control.ResumeActor:input_type -> substrate.ateapi.v1.ResumeActorRequest + 78, // 200: substrate.ateapi.v1.Control.RevertActor:input_type -> substrate.ateapi.v1.RevertActorRequest + 80, // 201: substrate.ateapi.v1.Control.DeleteActor:input_type -> substrate.ateapi.v1.DeleteActorRequest + 81, // 202: substrate.ateapi.v1.Control.GetActorEgressPolicy:input_type -> substrate.ateapi.v1.GetActorEgressPolicyRequest + 82, // 203: substrate.ateapi.v1.Control.CreateActorEgressPolicy:input_type -> substrate.ateapi.v1.CreateActorEgressPolicyRequest + 83, // 204: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:input_type -> substrate.ateapi.v1.UpdateActorEgressPolicyRequest + 84, // 205: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:input_type -> substrate.ateapi.v1.DeleteActorEgressPolicyRequest + 86, // 206: substrate.ateapi.v1.Control.MintActorJwt:input_type -> substrate.ateapi.v1.MintActorJwtRequest + 88, // 207: substrate.ateapi.v1.Control.MintActorCertificate:input_type -> substrate.ateapi.v1.MintActorCertificateRequest + 92, // 208: substrate.ateapi.v1.Control.CreateTag:input_type -> substrate.ateapi.v1.CreateTagRequest + 85, // 209: substrate.ateapi.v1.Control.GetTag:input_type -> substrate.ateapi.v1.GetTagRequest + 90, // 210: substrate.ateapi.v1.Control.ListTags:input_type -> substrate.ateapi.v1.ListTagsRequest + 93, // 211: substrate.ateapi.v1.Control.UpdateTag:input_type -> substrate.ateapi.v1.UpdateTagRequest + 94, // 212: substrate.ateapi.v1.Control.DeleteTag:input_type -> substrate.ateapi.v1.DeleteTagRequest + 99, // 213: substrate.ateapi.v1.Control.ListWorkers:input_type -> substrate.ateapi.v1.ListWorkersRequest + 101, // 214: substrate.ateapi.v1.Control.GetWorker:input_type -> substrate.ateapi.v1.GetWorkerRequest + 102, // 215: substrate.ateapi.v1.Control.CreateWorker:input_type -> substrate.ateapi.v1.CreateWorkerRequest + 103, // 216: substrate.ateapi.v1.Control.UpdateWorker:input_type -> substrate.ateapi.v1.UpdateWorkerRequest + 104, // 217: substrate.ateapi.v1.Control.DeleteWorker:input_type -> substrate.ateapi.v1.DeleteWorkerRequest + 105, // 218: substrate.ateapi.v1.Control.DrainWorker:input_type -> substrate.ateapi.v1.DrainWorkerRequest + 107, // 219: substrate.ateapi.v1.Control.MarkWorkerAvailable:input_type -> substrate.ateapi.v1.MarkWorkerAvailableRequest + 109, // 220: substrate.ateapi.v1.Control.MarkWorkerUnavailable:input_type -> substrate.ateapi.v1.MarkWorkerUnavailableRequest + 97, // 221: substrate.ateapi.v1.Control.ListWorkerActorAssignments:input_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsRequest + 111, // 222: substrate.ateapi.v1.Control.ListActors:input_type -> substrate.ateapi.v1.ListActorsRequest + 60, // 223: substrate.ateapi.v1.Control.CreateAtespace:input_type -> substrate.ateapi.v1.CreateAtespaceRequest + 61, // 224: substrate.ateapi.v1.Control.GetAtespace:input_type -> substrate.ateapi.v1.GetAtespaceRequest + 62, // 225: substrate.ateapi.v1.Control.ListAtespaces:input_type -> substrate.ateapi.v1.ListAtespacesRequest + 64, // 226: substrate.ateapi.v1.Control.DeleteAtespace:input_type -> substrate.ateapi.v1.DeleteAtespaceRequest + 65, // 227: substrate.ateapi.v1.Control.CreateActorTemplate:input_type -> substrate.ateapi.v1.CreateActorTemplateRequest + 66, // 228: substrate.ateapi.v1.Control.GetActorTemplate:input_type -> substrate.ateapi.v1.GetActorTemplateRequest + 67, // 229: substrate.ateapi.v1.Control.ListActorTemplates:input_type -> substrate.ateapi.v1.ListActorTemplatesRequest + 69, // 230: substrate.ateapi.v1.Control.DeleteActorTemplate:input_type -> substrate.ateapi.v1.DeleteActorTemplateRequest + 142, // 231: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:input_type -> substrate.ateapi.v1.GetGlobalAccessPolicyRequest + 143, // 232: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.CreateGlobalAccessPolicyRequest + 144, // 233: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest + 145, // 234: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.GetAtespaceAccessPolicyRequest + 146, // 235: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest + 147, // 236: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest + 148, // 237: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest + 122, // 238: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:input_type -> substrate.ateapi.v1.AcquireWorkerEpochRequest + 124, // 239: substrate.ateapi.v1.WorkerService.RegisterWorker:input_type -> substrate.ateapi.v1.RegisterWorkerRequest + 126, // 240: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:input_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest + 128, // 241: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:input_type -> substrate.ateapi.v1.MintWorkerActorCertificateRequest + 130, // 242: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:input_type -> substrate.ateapi.v1.MintWorkerActorJwtRequest + 132, // 243: substrate.ateapi.v1.WorkerService.RequestActorSuspend:input_type -> substrate.ateapi.v1.RequestActorSuspendRequest + 136, // 244: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:input_type -> substrate.ateapi.v1.ReportActorSnapshotStateRequest + 134, // 245: substrate.ateapi.v1.WorkerService.ReportActorCrashed:input_type -> substrate.ateapi.v1.ReportActorCrashedRequest + 17, // 246: substrate.ateapi.v1.Control.GetActor:output_type -> substrate.ateapi.v1.Actor + 17, // 247: substrate.ateapi.v1.Control.CreateActor:output_type -> substrate.ateapi.v1.Actor + 17, // 248: substrate.ateapi.v1.Control.UpdateActor:output_type -> substrate.ateapi.v1.Actor + 74, // 249: substrate.ateapi.v1.Control.SuspendActor:output_type -> substrate.ateapi.v1.SuspendActorResponse + 77, // 250: substrate.ateapi.v1.Control.ResumeActor:output_type -> substrate.ateapi.v1.ResumeActorResponse + 79, // 251: substrate.ateapi.v1.Control.RevertActor:output_type -> substrate.ateapi.v1.RevertActorResponse + 17, // 252: substrate.ateapi.v1.Control.DeleteActor:output_type -> substrate.ateapi.v1.Actor + 18, // 253: substrate.ateapi.v1.Control.GetActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 254: substrate.ateapi.v1.Control.CreateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 255: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 256: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 87, // 257: substrate.ateapi.v1.Control.MintActorJwt:output_type -> substrate.ateapi.v1.MintActorJwtResponse + 89, // 258: substrate.ateapi.v1.Control.MintActorCertificate:output_type -> substrate.ateapi.v1.MintActorCertificateResponse + 33, // 259: substrate.ateapi.v1.Control.CreateTag:output_type -> substrate.ateapi.v1.Tag + 33, // 260: substrate.ateapi.v1.Control.GetTag:output_type -> substrate.ateapi.v1.Tag + 91, // 261: substrate.ateapi.v1.Control.ListTags:output_type -> substrate.ateapi.v1.ListTagsResponse + 33, // 262: substrate.ateapi.v1.Control.UpdateTag:output_type -> substrate.ateapi.v1.Tag + 33, // 263: substrate.ateapi.v1.Control.DeleteTag:output_type -> substrate.ateapi.v1.Tag + 100, // 264: substrate.ateapi.v1.Control.ListWorkers:output_type -> substrate.ateapi.v1.ListWorkersResponse + 113, // 265: substrate.ateapi.v1.Control.GetWorker:output_type -> substrate.ateapi.v1.Worker + 113, // 266: substrate.ateapi.v1.Control.CreateWorker:output_type -> substrate.ateapi.v1.Worker + 113, // 267: substrate.ateapi.v1.Control.UpdateWorker:output_type -> substrate.ateapi.v1.Worker + 113, // 268: substrate.ateapi.v1.Control.DeleteWorker:output_type -> substrate.ateapi.v1.Worker + 106, // 269: substrate.ateapi.v1.Control.DrainWorker:output_type -> substrate.ateapi.v1.DrainWorkerResponse + 108, // 270: substrate.ateapi.v1.Control.MarkWorkerAvailable:output_type -> substrate.ateapi.v1.MarkWorkerAvailableResponse + 110, // 271: substrate.ateapi.v1.Control.MarkWorkerUnavailable:output_type -> substrate.ateapi.v1.MarkWorkerUnavailableResponse + 98, // 272: substrate.ateapi.v1.Control.ListWorkerActorAssignments:output_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsResponse + 112, // 273: substrate.ateapi.v1.Control.ListActors:output_type -> substrate.ateapi.v1.ListActorsResponse + 34, // 274: substrate.ateapi.v1.Control.CreateAtespace:output_type -> substrate.ateapi.v1.Atespace + 34, // 275: substrate.ateapi.v1.Control.GetAtespace:output_type -> substrate.ateapi.v1.Atespace + 63, // 276: substrate.ateapi.v1.Control.ListAtespaces:output_type -> substrate.ateapi.v1.ListAtespacesResponse + 34, // 277: substrate.ateapi.v1.Control.DeleteAtespace:output_type -> substrate.ateapi.v1.Atespace + 36, // 278: substrate.ateapi.v1.Control.CreateActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 36, // 279: substrate.ateapi.v1.Control.GetActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 68, // 280: substrate.ateapi.v1.Control.ListActorTemplates:output_type -> substrate.ateapi.v1.ListActorTemplatesResponse + 36, // 281: substrate.ateapi.v1.Control.DeleteActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 140, // 282: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 140, // 283: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 140, // 284: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 140, // 285: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 140, // 286: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 140, // 287: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 140, // 288: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 123, // 289: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:output_type -> substrate.ateapi.v1.AcquireWorkerEpochResponse + 125, // 290: substrate.ateapi.v1.WorkerService.RegisterWorker:output_type -> substrate.ateapi.v1.RegisterWorkerResponse + 127, // 291: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:output_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse + 129, // 292: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:output_type -> substrate.ateapi.v1.MintWorkerActorCertificateResponse + 131, // 293: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:output_type -> substrate.ateapi.v1.MintWorkerActorJwtResponse + 133, // 294: substrate.ateapi.v1.WorkerService.RequestActorSuspend:output_type -> substrate.ateapi.v1.RequestActorSuspendResponse + 137, // 295: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:output_type -> substrate.ateapi.v1.ReportActorSnapshotStateResponse + 135, // 296: substrate.ateapi.v1.WorkerService.ReportActorCrashed:output_type -> substrate.ateapi.v1.ReportActorCrashedResponse 246, // [246:297] is the sub-list for method output_type 195, // [195:246] is the sub-list for method input_type 193, // [193:195] is the sub-list for extension type_name @@ -11161,28 +11161,28 @@ var file_ateapi_proto_depIdxs = []int32{ 0, // [0:191] is the sub-list for field type_name } -func init() { file_ateapi_proto_init() } -func file_ateapi_proto_init() { - if File_ateapi_proto != nil { +func init() { file_api_ateapi_v1_ateapi_proto_init() } +func file_api_ateapi_v1_ateapi_proto_init() { + if File_api_ateapi_v1_ateapi_proto != nil { return } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_ateapi_proto_rawDesc), len(file_ateapi_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_ateapi_v1_ateapi_proto_rawDesc), len(file_api_ateapi_v1_ateapi_proto_rawDesc)), NumEnums: 10, NumMessages: 144, NumExtensions: 2, NumServices: 2, }, - GoTypes: file_ateapi_proto_goTypes, - DependencyIndexes: file_ateapi_proto_depIdxs, - EnumInfos: file_ateapi_proto_enumTypes, - MessageInfos: file_ateapi_proto_msgTypes, - ExtensionInfos: file_ateapi_proto_extTypes, + GoTypes: file_api_ateapi_v1_ateapi_proto_goTypes, + DependencyIndexes: file_api_ateapi_v1_ateapi_proto_depIdxs, + EnumInfos: file_api_ateapi_v1_ateapi_proto_enumTypes, + MessageInfos: file_api_ateapi_v1_ateapi_proto_msgTypes, + ExtensionInfos: file_api_ateapi_v1_ateapi_proto_extTypes, }.Build() - File_ateapi_proto = out.File - file_ateapi_proto_goTypes = nil - file_ateapi_proto_depIdxs = nil + File_api_ateapi_v1_ateapi_proto = out.File + file_api_ateapi_v1_ateapi_proto_goTypes = nil + file_api_ateapi_v1_ateapi_proto_depIdxs = nil } diff --git a/pkg/proto/ateapipb/ateapi.proto b/api/ateapi/v1/ateapi.proto similarity index 99% rename from pkg/proto/ateapipb/ateapi.proto rename to api/ateapi/v1/ateapi.proto index e453a318c9..a5e777a4a6 100644 --- a/pkg/proto/ateapipb/ateapi.proto +++ b/api/ateapi/v1/ateapi.proto @@ -14,12 +14,12 @@ syntax = "proto3"; -package ateapi; +package substrate.ateapi.v1; import "google/protobuf/descriptor.proto"; import "google/protobuf/timestamp.proto"; -option go_package = "go.ate.dev/substrate/pkg/proto/ateapipb"; +option go_package = "go.ate.dev/substrate/api/ateapi/v1;ateapi"; // Control is the primary RPC interface for Agentic Substrate. service Control { diff --git a/pkg/proto/ateapipb/ateapi_grpc.pb.go b/api/ateapi/v1/ateapi_grpc.pb.go similarity index 95% rename from pkg/proto/ateapipb/ateapi_grpc.pb.go rename to api/ateapi/v1/ateapi_grpc.pb.go index f8a5e5be72..4c2cadb5d9 100644 --- a/pkg/proto/ateapipb/ateapi_grpc.pb.go +++ b/api/ateapi/v1/ateapi_grpc.pb.go @@ -16,9 +16,9 @@ // versions: // - protoc-gen-go-grpc v1.6.2 // - protoc v4.25.3 -// source: ateapi.proto +// source: api/ateapi/v1/ateapi.proto -package ateapipb +package ateapi import ( context "context" @@ -33,49 +33,49 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - Control_GetActor_FullMethodName = "/ateapi.Control/GetActor" - Control_CreateActor_FullMethodName = "/ateapi.Control/CreateActor" - Control_UpdateActor_FullMethodName = "/ateapi.Control/UpdateActor" - Control_SuspendActor_FullMethodName = "/ateapi.Control/SuspendActor" - Control_ResumeActor_FullMethodName = "/ateapi.Control/ResumeActor" - Control_RevertActor_FullMethodName = "/ateapi.Control/RevertActor" - Control_DeleteActor_FullMethodName = "/ateapi.Control/DeleteActor" - Control_GetActorEgressPolicy_FullMethodName = "/ateapi.Control/GetActorEgressPolicy" - Control_CreateActorEgressPolicy_FullMethodName = "/ateapi.Control/CreateActorEgressPolicy" - Control_UpdateActorEgressPolicy_FullMethodName = "/ateapi.Control/UpdateActorEgressPolicy" - Control_DeleteActorEgressPolicy_FullMethodName = "/ateapi.Control/DeleteActorEgressPolicy" - Control_MintActorJwt_FullMethodName = "/ateapi.Control/MintActorJwt" - Control_MintActorCertificate_FullMethodName = "/ateapi.Control/MintActorCertificate" - Control_CreateTag_FullMethodName = "/ateapi.Control/CreateTag" - Control_GetTag_FullMethodName = "/ateapi.Control/GetTag" - Control_ListTags_FullMethodName = "/ateapi.Control/ListTags" - Control_UpdateTag_FullMethodName = "/ateapi.Control/UpdateTag" - Control_DeleteTag_FullMethodName = "/ateapi.Control/DeleteTag" - Control_ListWorkers_FullMethodName = "/ateapi.Control/ListWorkers" - Control_GetWorker_FullMethodName = "/ateapi.Control/GetWorker" - Control_CreateWorker_FullMethodName = "/ateapi.Control/CreateWorker" - Control_UpdateWorker_FullMethodName = "/ateapi.Control/UpdateWorker" - Control_DeleteWorker_FullMethodName = "/ateapi.Control/DeleteWorker" - Control_DrainWorker_FullMethodName = "/ateapi.Control/DrainWorker" - Control_MarkWorkerAvailable_FullMethodName = "/ateapi.Control/MarkWorkerAvailable" - Control_MarkWorkerUnavailable_FullMethodName = "/ateapi.Control/MarkWorkerUnavailable" - Control_ListWorkerActorAssignments_FullMethodName = "/ateapi.Control/ListWorkerActorAssignments" - Control_ListActors_FullMethodName = "/ateapi.Control/ListActors" - Control_CreateAtespace_FullMethodName = "/ateapi.Control/CreateAtespace" - Control_GetAtespace_FullMethodName = "/ateapi.Control/GetAtespace" - Control_ListAtespaces_FullMethodName = "/ateapi.Control/ListAtespaces" - Control_DeleteAtespace_FullMethodName = "/ateapi.Control/DeleteAtespace" - Control_CreateActorTemplate_FullMethodName = "/ateapi.Control/CreateActorTemplate" - Control_GetActorTemplate_FullMethodName = "/ateapi.Control/GetActorTemplate" - Control_ListActorTemplates_FullMethodName = "/ateapi.Control/ListActorTemplates" - Control_DeleteActorTemplate_FullMethodName = "/ateapi.Control/DeleteActorTemplate" - Control_GetGlobalAccessPolicy_FullMethodName = "/ateapi.Control/GetGlobalAccessPolicy" - Control_CreateGlobalAccessPolicy_FullMethodName = "/ateapi.Control/CreateGlobalAccessPolicy" - Control_UpdateGlobalAccessPolicy_FullMethodName = "/ateapi.Control/UpdateGlobalAccessPolicy" - Control_GetAtespaceAccessPolicy_FullMethodName = "/ateapi.Control/GetAtespaceAccessPolicy" - Control_CreateAtespaceAccessPolicy_FullMethodName = "/ateapi.Control/CreateAtespaceAccessPolicy" - Control_UpdateAtespaceAccessPolicy_FullMethodName = "/ateapi.Control/UpdateAtespaceAccessPolicy" - Control_DeleteAtespaceAccessPolicy_FullMethodName = "/ateapi.Control/DeleteAtespaceAccessPolicy" + Control_GetActor_FullMethodName = "/substrate.ateapi.v1.Control/GetActor" + Control_CreateActor_FullMethodName = "/substrate.ateapi.v1.Control/CreateActor" + Control_UpdateActor_FullMethodName = "/substrate.ateapi.v1.Control/UpdateActor" + Control_SuspendActor_FullMethodName = "/substrate.ateapi.v1.Control/SuspendActor" + Control_ResumeActor_FullMethodName = "/substrate.ateapi.v1.Control/ResumeActor" + Control_RevertActor_FullMethodName = "/substrate.ateapi.v1.Control/RevertActor" + Control_DeleteActor_FullMethodName = "/substrate.ateapi.v1.Control/DeleteActor" + Control_GetActorEgressPolicy_FullMethodName = "/substrate.ateapi.v1.Control/GetActorEgressPolicy" + Control_CreateActorEgressPolicy_FullMethodName = "/substrate.ateapi.v1.Control/CreateActorEgressPolicy" + Control_UpdateActorEgressPolicy_FullMethodName = "/substrate.ateapi.v1.Control/UpdateActorEgressPolicy" + Control_DeleteActorEgressPolicy_FullMethodName = "/substrate.ateapi.v1.Control/DeleteActorEgressPolicy" + Control_MintActorJwt_FullMethodName = "/substrate.ateapi.v1.Control/MintActorJwt" + Control_MintActorCertificate_FullMethodName = "/substrate.ateapi.v1.Control/MintActorCertificate" + Control_CreateTag_FullMethodName = "/substrate.ateapi.v1.Control/CreateTag" + Control_GetTag_FullMethodName = "/substrate.ateapi.v1.Control/GetTag" + Control_ListTags_FullMethodName = "/substrate.ateapi.v1.Control/ListTags" + Control_UpdateTag_FullMethodName = "/substrate.ateapi.v1.Control/UpdateTag" + Control_DeleteTag_FullMethodName = "/substrate.ateapi.v1.Control/DeleteTag" + Control_ListWorkers_FullMethodName = "/substrate.ateapi.v1.Control/ListWorkers" + Control_GetWorker_FullMethodName = "/substrate.ateapi.v1.Control/GetWorker" + Control_CreateWorker_FullMethodName = "/substrate.ateapi.v1.Control/CreateWorker" + Control_UpdateWorker_FullMethodName = "/substrate.ateapi.v1.Control/UpdateWorker" + Control_DeleteWorker_FullMethodName = "/substrate.ateapi.v1.Control/DeleteWorker" + Control_DrainWorker_FullMethodName = "/substrate.ateapi.v1.Control/DrainWorker" + Control_MarkWorkerAvailable_FullMethodName = "/substrate.ateapi.v1.Control/MarkWorkerAvailable" + Control_MarkWorkerUnavailable_FullMethodName = "/substrate.ateapi.v1.Control/MarkWorkerUnavailable" + Control_ListWorkerActorAssignments_FullMethodName = "/substrate.ateapi.v1.Control/ListWorkerActorAssignments" + Control_ListActors_FullMethodName = "/substrate.ateapi.v1.Control/ListActors" + Control_CreateAtespace_FullMethodName = "/substrate.ateapi.v1.Control/CreateAtespace" + Control_GetAtespace_FullMethodName = "/substrate.ateapi.v1.Control/GetAtespace" + Control_ListAtespaces_FullMethodName = "/substrate.ateapi.v1.Control/ListAtespaces" + Control_DeleteAtespace_FullMethodName = "/substrate.ateapi.v1.Control/DeleteAtespace" + Control_CreateActorTemplate_FullMethodName = "/substrate.ateapi.v1.Control/CreateActorTemplate" + Control_GetActorTemplate_FullMethodName = "/substrate.ateapi.v1.Control/GetActorTemplate" + Control_ListActorTemplates_FullMethodName = "/substrate.ateapi.v1.Control/ListActorTemplates" + Control_DeleteActorTemplate_FullMethodName = "/substrate.ateapi.v1.Control/DeleteActorTemplate" + Control_GetGlobalAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/GetGlobalAccessPolicy" + Control_CreateGlobalAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/CreateGlobalAccessPolicy" + Control_UpdateGlobalAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/UpdateGlobalAccessPolicy" + Control_GetAtespaceAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/GetAtespaceAccessPolicy" + Control_CreateAtespaceAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/CreateAtespaceAccessPolicy" + Control_UpdateAtespaceAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/UpdateAtespaceAccessPolicy" + Control_DeleteAtespaceAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/DeleteAtespaceAccessPolicy" ) // ControlClient is the client API for Control service. @@ -1706,7 +1706,7 @@ func _Control_DeleteAtespaceAccessPolicy_Handler(srv interface{}, ctx context.Co // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var Control_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "ateapi.Control", + ServiceName: "substrate.ateapi.v1.Control", HandlerType: (*ControlServer)(nil), Methods: []grpc.MethodDesc{ { @@ -1883,18 +1883,18 @@ var Control_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "ateapi.proto", + Metadata: "api/ateapi/v1/ateapi.proto", } const ( - WorkerService_AcquireWorkerEpoch_FullMethodName = "/ateapi.WorkerService/AcquireWorkerEpoch" - WorkerService_RegisterWorker_FullMethodName = "/ateapi.WorkerService/RegisterWorker" - WorkerService_SetWorkerSandboxRuntimes_FullMethodName = "/ateapi.WorkerService/SetWorkerSandboxRuntimes" - WorkerService_MintWorkerActorCertificate_FullMethodName = "/ateapi.WorkerService/MintWorkerActorCertificate" - WorkerService_MintWorkerActorJwt_FullMethodName = "/ateapi.WorkerService/MintWorkerActorJwt" - WorkerService_RequestActorSuspend_FullMethodName = "/ateapi.WorkerService/RequestActorSuspend" - WorkerService_ReportActorSnapshotState_FullMethodName = "/ateapi.WorkerService/ReportActorSnapshotState" - WorkerService_ReportActorCrashed_FullMethodName = "/ateapi.WorkerService/ReportActorCrashed" + WorkerService_AcquireWorkerEpoch_FullMethodName = "/substrate.ateapi.v1.WorkerService/AcquireWorkerEpoch" + WorkerService_RegisterWorker_FullMethodName = "/substrate.ateapi.v1.WorkerService/RegisterWorker" + WorkerService_SetWorkerSandboxRuntimes_FullMethodName = "/substrate.ateapi.v1.WorkerService/SetWorkerSandboxRuntimes" + WorkerService_MintWorkerActorCertificate_FullMethodName = "/substrate.ateapi.v1.WorkerService/MintWorkerActorCertificate" + WorkerService_MintWorkerActorJwt_FullMethodName = "/substrate.ateapi.v1.WorkerService/MintWorkerActorJwt" + WorkerService_RequestActorSuspend_FullMethodName = "/substrate.ateapi.v1.WorkerService/RequestActorSuspend" + WorkerService_ReportActorSnapshotState_FullMethodName = "/substrate.ateapi.v1.WorkerService/ReportActorSnapshotState" + WorkerService_ReportActorCrashed_FullMethodName = "/substrate.ateapi.v1.WorkerService/ReportActorCrashed" ) // WorkerServiceClient is the client API for WorkerService service. @@ -2406,7 +2406,7 @@ func _WorkerService_ReportActorCrashed_Handler(srv interface{}, ctx context.Cont // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var WorkerService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "ateapi.WorkerService", + ServiceName: "substrate.ateapi.v1.WorkerService", HandlerType: (*WorkerServiceServer)(nil), Methods: []grpc.MethodDesc{ { @@ -2443,5 +2443,5 @@ var WorkerService_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "ateapi.proto", + Metadata: "api/ateapi/v1/ateapi.proto", } diff --git a/pkg/proto/ateapipb/source.go b/api/ateapi/v1/source.go similarity index 97% rename from pkg/proto/ateapipb/source.go rename to api/ateapi/v1/source.go index 03340efe1a..950d00afbc 100644 --- a/pkg/proto/ateapipb/source.go +++ b/api/ateapi/v1/source.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package ateapipb +package ateapi import _ "embed" diff --git a/pkg/proto/credproviderpb/credprovider.pb.go b/api/credprovider/v1/credprovider.pb.go similarity index 61% rename from pkg/proto/credproviderpb/credprovider.pb.go rename to api/credprovider/v1/credprovider.pb.go index e2046707ac..a2f41f7dbd 100644 --- a/pkg/proto/credproviderpb/credprovider.pb.go +++ b/api/credprovider/v1/credprovider.pb.go @@ -16,9 +16,9 @@ // versions: // protoc-gen-go v1.36.11-devel // protoc v4.25.3 -// source: credprovider.proto +// source: api/credprovider/v1/credprovider.proto -package credproviderpb +package credprovider import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -51,7 +51,7 @@ type FetchSecretRequest struct { func (x *FetchSecretRequest) Reset() { *x = FetchSecretRequest{} - mi := &file_credprovider_proto_msgTypes[0] + mi := &file_api_credprovider_v1_credprovider_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -63,7 +63,7 @@ func (x *FetchSecretRequest) String() string { func (*FetchSecretRequest) ProtoMessage() {} func (x *FetchSecretRequest) ProtoReflect() protoreflect.Message { - mi := &file_credprovider_proto_msgTypes[0] + mi := &file_api_credprovider_v1_credprovider_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -76,7 +76,7 @@ func (x *FetchSecretRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchSecretRequest.ProtoReflect.Descriptor instead. func (*FetchSecretRequest) Descriptor() ([]byte, []int) { - return file_credprovider_proto_rawDescGZIP(), []int{0} + return file_api_credprovider_v1_credprovider_proto_rawDescGZIP(), []int{0} } func (x *FetchSecretRequest) GetUri() string { @@ -104,7 +104,7 @@ type FetchSecretResponse struct { func (x *FetchSecretResponse) Reset() { *x = FetchSecretResponse{} - mi := &file_credprovider_proto_msgTypes[1] + mi := &file_api_credprovider_v1_credprovider_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -116,7 +116,7 @@ func (x *FetchSecretResponse) String() string { func (*FetchSecretResponse) ProtoMessage() {} func (x *FetchSecretResponse) ProtoReflect() protoreflect.Message { - mi := &file_credprovider_proto_msgTypes[1] + mi := &file_api_credprovider_v1_credprovider_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -129,7 +129,7 @@ func (x *FetchSecretResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchSecretResponse.ProtoReflect.Descriptor instead. func (*FetchSecretResponse) Descriptor() ([]byte, []int) { - return file_credprovider_proto_rawDescGZIP(), []int{1} + return file_api_credprovider_v1_credprovider_proto_rawDescGZIP(), []int{1} } func (x *FetchSecretResponse) GetOpaqueBytes() []byte { @@ -139,39 +139,39 @@ func (x *FetchSecretResponse) GetOpaqueBytes() []byte { return nil } -var File_credprovider_proto protoreflect.FileDescriptor +var File_api_credprovider_v1_credprovider_proto protoreflect.FileDescriptor -const file_credprovider_proto_rawDesc = "" + +const file_api_credprovider_v1_credprovider_proto_rawDesc = "" + "\n" + - "\x12credprovider.proto\x12\fcredprovider\"N\n" + + "&api/credprovider/v1/credprovider.proto\x12\x19substrate.credprovider.v1\"N\n" + "\x12FetchSecretRequest\x12\x10\n" + "\x03uri\x18\x01 \x01(\tR\x03uri\x12&\n" + "\x0factor_spiffe_id\x18\x02 \x01(\tR\ractorSpiffeId\"=\n" + "\x13FetchSecretResponse\x12&\n" + - "\fopaque_bytes\x18\x01 \x01(\fB\x03\x80\x01\x01R\vopaqueBytes2j\n" + - "\x12CredentialProvider\x12T\n" + - "\vFetchSecret\x12 .credprovider.FetchSecretRequest\x1a!.credprovider.FetchSecretResponse\"\x00B/Z-go.ate.dev/substrate/pkg/proto/credproviderpbb\x06proto3" + "\fopaque_bytes\x18\x01 \x01(\fB\x03\x80\x01\x01R\vopaqueBytes2\x84\x01\n" + + "\x12CredentialProvider\x12n\n" + + "\vFetchSecret\x12-.substrate.credprovider.v1.FetchSecretRequest\x1a..substrate.credprovider.v1.FetchSecretResponse\"\x00B7Z5go.ate.dev/substrate/api/credprovider/v1;credproviderb\x06proto3" var ( - file_credprovider_proto_rawDescOnce sync.Once - file_credprovider_proto_rawDescData []byte + file_api_credprovider_v1_credprovider_proto_rawDescOnce sync.Once + file_api_credprovider_v1_credprovider_proto_rawDescData []byte ) -func file_credprovider_proto_rawDescGZIP() []byte { - file_credprovider_proto_rawDescOnce.Do(func() { - file_credprovider_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_credprovider_proto_rawDesc), len(file_credprovider_proto_rawDesc))) +func file_api_credprovider_v1_credprovider_proto_rawDescGZIP() []byte { + file_api_credprovider_v1_credprovider_proto_rawDescOnce.Do(func() { + file_api_credprovider_v1_credprovider_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_api_credprovider_v1_credprovider_proto_rawDesc), len(file_api_credprovider_v1_credprovider_proto_rawDesc))) }) - return file_credprovider_proto_rawDescData + return file_api_credprovider_v1_credprovider_proto_rawDescData } -var file_credprovider_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_credprovider_proto_goTypes = []any{ - (*FetchSecretRequest)(nil), // 0: credprovider.FetchSecretRequest - (*FetchSecretResponse)(nil), // 1: credprovider.FetchSecretResponse +var file_api_credprovider_v1_credprovider_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_api_credprovider_v1_credprovider_proto_goTypes = []any{ + (*FetchSecretRequest)(nil), // 0: substrate.credprovider.v1.FetchSecretRequest + (*FetchSecretResponse)(nil), // 1: substrate.credprovider.v1.FetchSecretResponse } -var file_credprovider_proto_depIdxs = []int32{ - 0, // 0: credprovider.CredentialProvider.FetchSecret:input_type -> credprovider.FetchSecretRequest - 1, // 1: credprovider.CredentialProvider.FetchSecret:output_type -> credprovider.FetchSecretResponse +var file_api_credprovider_v1_credprovider_proto_depIdxs = []int32{ + 0, // 0: substrate.credprovider.v1.CredentialProvider.FetchSecret:input_type -> substrate.credprovider.v1.FetchSecretRequest + 1, // 1: substrate.credprovider.v1.CredentialProvider.FetchSecret:output_type -> substrate.credprovider.v1.FetchSecretResponse 1, // [1:2] is the sub-list for method output_type 0, // [0:1] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name @@ -179,26 +179,26 @@ var file_credprovider_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for field type_name } -func init() { file_credprovider_proto_init() } -func file_credprovider_proto_init() { - if File_credprovider_proto != nil { +func init() { file_api_credprovider_v1_credprovider_proto_init() } +func file_api_credprovider_v1_credprovider_proto_init() { + if File_api_credprovider_v1_credprovider_proto != nil { return } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_credprovider_proto_rawDesc), len(file_credprovider_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_credprovider_v1_credprovider_proto_rawDesc), len(file_api_credprovider_v1_credprovider_proto_rawDesc)), NumEnums: 0, NumMessages: 2, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_credprovider_proto_goTypes, - DependencyIndexes: file_credprovider_proto_depIdxs, - MessageInfos: file_credprovider_proto_msgTypes, + GoTypes: file_api_credprovider_v1_credprovider_proto_goTypes, + DependencyIndexes: file_api_credprovider_v1_credprovider_proto_depIdxs, + MessageInfos: file_api_credprovider_v1_credprovider_proto_msgTypes, }.Build() - File_credprovider_proto = out.File - file_credprovider_proto_goTypes = nil - file_credprovider_proto_depIdxs = nil + File_api_credprovider_v1_credprovider_proto = out.File + file_api_credprovider_v1_credprovider_proto_goTypes = nil + file_api_credprovider_v1_credprovider_proto_depIdxs = nil } diff --git a/pkg/proto/credproviderpb/credprovider.proto b/api/credprovider/v1/credprovider.proto similarity index 94% rename from pkg/proto/credproviderpb/credprovider.proto rename to api/credprovider/v1/credprovider.proto index 758604c178..ac4bc1fd0d 100644 --- a/pkg/proto/credproviderpb/credprovider.proto +++ b/api/credprovider/v1/credprovider.proto @@ -14,9 +14,9 @@ syntax = "proto3"; -package credprovider; +package substrate.credprovider.v1; -option go_package = "go.ate.dev/substrate/pkg/proto/credproviderpb"; +option go_package = "go.ate.dev/substrate/api/credprovider/v1;credprovider"; // CredentialProvider is the plugin API a secret backend implements so Substrate // infrastructure (e.g. the egress gateway's credential injector) can fetch an diff --git a/pkg/proto/credproviderpb/credprovider_grpc.pb.go b/api/credprovider/v1/credprovider_grpc.pb.go similarity index 95% rename from pkg/proto/credproviderpb/credprovider_grpc.pb.go rename to api/credprovider/v1/credprovider_grpc.pb.go index b646b45c21..bcba421a18 100644 --- a/pkg/proto/credproviderpb/credprovider_grpc.pb.go +++ b/api/credprovider/v1/credprovider_grpc.pb.go @@ -16,9 +16,9 @@ // versions: // - protoc-gen-go-grpc v1.6.2 // - protoc v4.25.3 -// source: credprovider.proto +// source: api/credprovider/v1/credprovider.proto -package credproviderpb +package credprovider import ( context "context" @@ -33,7 +33,7 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - CredentialProvider_FetchSecret_FullMethodName = "/credprovider.CredentialProvider/FetchSecret" + CredentialProvider_FetchSecret_FullMethodName = "/substrate.credprovider.v1.CredentialProvider/FetchSecret" ) // CredentialProviderClient is the client API for CredentialProvider service. @@ -136,7 +136,7 @@ func _CredentialProvider_FetchSecret_Handler(srv interface{}, ctx context.Contex // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var CredentialProvider_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "credprovider.CredentialProvider", + ServiceName: "substrate.credprovider.v1.CredentialProvider", HandlerType: (*CredentialProviderServer)(nil), Methods: []grpc.MethodDesc{ { @@ -145,5 +145,5 @@ var CredentialProvider_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "credprovider.proto", + Metadata: "api/credprovider/v1/credprovider.proto", } diff --git a/pkg/api/v1alpha1/csidriverconfig_types.go b/api/infra/k8s/ate/v1/csidriverconfig_types.go similarity index 99% rename from pkg/api/v1alpha1/csidriverconfig_types.go rename to api/infra/k8s/ate/v1/csidriverconfig_types.go index 23a566699a..00206fccc2 100644 --- a/pkg/api/v1alpha1/csidriverconfig_types.go +++ b/api/infra/k8s/ate/v1/csidriverconfig_types.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v1alpha1 +package v1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/api/infra/k8s/ate/v1/gen.go b/api/infra/k8s/ate/v1/gen.go new file mode 100644 index 0000000000..aafe285e78 --- /dev/null +++ b/api/infra/k8s/ate/v1/gen.go @@ -0,0 +1,20 @@ +// Copyright 2026 Google LLC +// +// 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 v1 + +//go:generate bash ../../../../../hack/run-tool.sh controller-gen crd:headerFile=../../../../../hack/boilerplate/sh.txt object:headerFile=../../../../../hack/boilerplate/go.txt paths="./" output:crd:dir="../../../../../manifests/ate-install/generated/" +//go:generate bash ../../../../../hack/run-tool.sh client-gen --go-header-file=../../../../../hack/boilerplate/go.txt --clientset-name versioned --input-base go.ate.dev/substrate --input api/infra/k8s/ate/v1 --output-pkg go.ate.dev/substrate/pkg/client/clientset --output-dir ../../../../../pkg/client/clientset +//go:generate bash ../../../../../hack/run-tool.sh lister-gen --go-header-file=../../../../../hack/boilerplate/go.txt --output-pkg go.ate.dev/substrate/pkg/client/listers --output-dir ../../../../../pkg/client/listers go.ate.dev/substrate/api/infra/k8s/ate/v1 +//go:generate bash ../../../../../hack/run-tool.sh informer-gen --go-header-file=../../../../../hack/boilerplate/go.txt --versioned-clientset-package go.ate.dev/substrate/pkg/client/clientset/versioned --listers-package go.ate.dev/substrate/pkg/client/listers --output-pkg go.ate.dev/substrate/pkg/client/informers --output-dir ../../../../../pkg/client/informers go.ate.dev/substrate/api/infra/k8s/ate/v1 diff --git a/pkg/api/v1alpha1/groupversion_info.go b/api/infra/k8s/ate/v1/groupversion_info.go similarity index 93% rename from pkg/api/v1alpha1/groupversion_info.go rename to api/infra/k8s/ate/v1/groupversion_info.go index f93974de10..4b5529d43a 100644 --- a/pkg/api/v1alpha1/groupversion_info.go +++ b/api/infra/k8s/ate/v1/groupversion_info.go @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package v1alpha1 contains API Schema definitions for the agents v1alpha1 API group. +// Package v1 contains API Schema definitions for the ate.dev v1 API group. // +kubebuilder:object:generate=true // +groupName=ate.dev -package v1alpha1 +package v1 import ( "k8s.io/apimachinery/pkg/runtime/schema" @@ -24,7 +24,7 @@ import ( var ( // GroupVersion is group version used to register these objects. - GroupVersion = schema.GroupVersion{Group: "ate.dev", Version: "v1alpha1"} + GroupVersion = schema.GroupVersion{Group: "ate.dev", Version: "v1"} // SchemeGroupVersion is group version used to register these objects SchemeGroupVersion = GroupVersion diff --git a/pkg/api/v1alpha1/main_test.go b/api/infra/k8s/ate/v1/main_test.go similarity index 98% rename from pkg/api/v1alpha1/main_test.go rename to api/infra/k8s/ate/v1/main_test.go index 6a087530d5..f0def88224 100644 --- a/pkg/api/v1alpha1/main_test.go +++ b/api/infra/k8s/ate/v1/main_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v1alpha1 +package v1 import ( "fmt" diff --git a/pkg/api/v1alpha1/sandboxconfig_types.go b/api/infra/k8s/ate/v1/sandboxconfig_types.go similarity index 99% rename from pkg/api/v1alpha1/sandboxconfig_types.go rename to api/infra/k8s/ate/v1/sandboxconfig_types.go index 3c5276c418..ab28685d44 100644 --- a/pkg/api/v1alpha1/sandboxconfig_types.go +++ b/api/infra/k8s/ate/v1/sandboxconfig_types.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v1alpha1 +package v1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/api/v1alpha1/sandboxconfig_types_test.go b/api/infra/k8s/ate/v1/sandboxconfig_types_test.go similarity index 99% rename from pkg/api/v1alpha1/sandboxconfig_types_test.go rename to api/infra/k8s/ate/v1/sandboxconfig_types_test.go index f5869ec696..70d3d91633 100644 --- a/pkg/api/v1alpha1/sandboxconfig_types_test.go +++ b/api/infra/k8s/ate/v1/sandboxconfig_types_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v1alpha1 +package v1 import ( "testing" diff --git a/pkg/api/v1alpha1/sandboxconfig_validation_test.go b/api/infra/k8s/ate/v1/sandboxconfig_validation_test.go similarity index 98% rename from pkg/api/v1alpha1/sandboxconfig_validation_test.go rename to api/infra/k8s/ate/v1/sandboxconfig_validation_test.go index 5f495831b3..6b6663cec9 100644 --- a/pkg/api/v1alpha1/sandboxconfig_validation_test.go +++ b/api/infra/k8s/ate/v1/sandboxconfig_validation_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v1alpha1 +package v1 import ( "context" @@ -38,7 +38,7 @@ const gvisorAssetMsg = "'gvisor' (release tarball) asset" // vapManifestPath is the SandboxConfig ValidatingAdmissionPolicy shipped with // the install — loaded here so the test guards the policy we actually ship. -const vapManifestPath = "../../../manifests/ate-install/sandboxconfig-validation.yaml" +const vapManifestPath = "../../../../../manifests/ate-install/sandboxconfig-validation.yaml" // sandboxVersion returns a version with the given name and assets. func sandboxVersion(name string, assets map[string]map[string]AssetFile) SandboxVersionConfig { @@ -351,8 +351,8 @@ func TestShippedSandboxConfigManifests(t *testing.T) { applyVAP(t, ctx) for _, path := range []string{ - "../../../manifests/ate-install/sandboxconfig-gvisor.yaml", - "../../../manifests/microvm/sandboxconfig-microvm.yaml.tmpl", + "../../../../../manifests/ate-install/sandboxconfig-gvisor.yaml", + "../../../../../manifests/microvm/sandboxconfig-microvm.yaml.tmpl", } { t.Run(path, func(t *testing.T) { raw, err := os.ReadFile(path) diff --git a/pkg/api/v1alpha1/workerpool_types.go b/api/infra/k8s/ate/v1/workerpool_types.go similarity index 99% rename from pkg/api/v1alpha1/workerpool_types.go rename to api/infra/k8s/ate/v1/workerpool_types.go index 752e36b7a3..f34ebb7091 100644 --- a/pkg/api/v1alpha1/workerpool_types.go +++ b/api/infra/k8s/ate/v1/workerpool_types.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v1alpha1 +package v1 import ( corev1 "k8s.io/api/core/v1" diff --git a/pkg/api/v1alpha1/workerpool_types_test.go b/api/infra/k8s/ate/v1/workerpool_types_test.go similarity index 99% rename from pkg/api/v1alpha1/workerpool_types_test.go rename to api/infra/k8s/ate/v1/workerpool_types_test.go index d51bfd2e0a..27cb48ab0d 100644 --- a/pkg/api/v1alpha1/workerpool_types_test.go +++ b/api/infra/k8s/ate/v1/workerpool_types_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v1alpha1 +package v1 import "testing" diff --git a/pkg/api/v1alpha1/workerpool_validation_test.go b/api/infra/k8s/ate/v1/workerpool_validation_test.go similarity index 99% rename from pkg/api/v1alpha1/workerpool_validation_test.go rename to api/infra/k8s/ate/v1/workerpool_validation_test.go index dbaa294231..ce2712268a 100644 --- a/pkg/api/v1alpha1/workerpool_validation_test.go +++ b/api/infra/k8s/ate/v1/workerpool_validation_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v1alpha1 +package v1 import ( "context" diff --git a/pkg/api/v1alpha1/zz_generated.deepcopy.go b/api/infra/k8s/ate/v1/zz_generated.deepcopy.go similarity index 98% rename from pkg/api/v1alpha1/zz_generated.deepcopy.go rename to api/infra/k8s/ate/v1/zz_generated.deepcopy.go index bee9dcfcad..7ac86477c9 100644 --- a/pkg/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/infra/k8s/ate/v1/zz_generated.deepcopy.go @@ -16,10 +16,10 @@ // Code generated by controller-gen. DO NOT EDIT. -package v1alpha1 +package v1 import ( - "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -350,19 +350,19 @@ func (in *WorkerPoolPodTemplate) DeepCopyInto(out *WorkerPoolPodTemplate) { } if in.Tolerations != nil { in, out := &in.Tolerations, &out.Tolerations - *out = make([]v1.Toleration, len(*in)) + *out = make([]corev1.Toleration, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.NodeAffinity != nil { in, out := &in.NodeAffinity, &out.NodeAffinity - *out = new(v1.NodeAffinity) + *out = new(corev1.NodeAffinity) (*in).DeepCopyInto(*out) } if in.Resources != nil { in, out := &in.Resources, &out.Resources - *out = new(v1.ResourceRequirements) + *out = new(corev1.ResourceRequirements) (*in).DeepCopyInto(*out) } if in.ServiceAccountName != nil { diff --git a/pkg/proto/objectstorepb/v1/objectstore.pb.go b/api/objectstore/v1/objectstore.pb.go similarity index 72% rename from pkg/proto/objectstorepb/v1/objectstore.pb.go rename to api/objectstore/v1/objectstore.pb.go index e422197c89..b2cce06346 100644 --- a/pkg/proto/objectstorepb/v1/objectstore.pb.go +++ b/api/objectstore/v1/objectstore.pb.go @@ -16,9 +16,9 @@ // versions: // protoc-gen-go v1.36.11-devel // protoc v4.25.3 -// source: objectstore.proto +// source: api/objectstore/v1/objectstore.proto -package objectstorev1 +package objectstore import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -59,7 +59,7 @@ type FetchSnapshotRequest struct { func (x *FetchSnapshotRequest) Reset() { *x = FetchSnapshotRequest{} - mi := &file_objectstore_proto_msgTypes[0] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -71,7 +71,7 @@ func (x *FetchSnapshotRequest) String() string { func (*FetchSnapshotRequest) ProtoMessage() {} func (x *FetchSnapshotRequest) ProtoReflect() protoreflect.Message { - mi := &file_objectstore_proto_msgTypes[0] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -84,7 +84,7 @@ func (x *FetchSnapshotRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchSnapshotRequest.ProtoReflect.Descriptor instead. func (*FetchSnapshotRequest) Descriptor() ([]byte, []int) { - return file_objectstore_proto_rawDescGZIP(), []int{0} + return file_api_objectstore_v1_objectstore_proto_rawDescGZIP(), []int{0} } func (x *FetchSnapshotRequest) GetSnapshotUri() string { @@ -123,7 +123,7 @@ type FetchSnapshotResponse struct { func (x *FetchSnapshotResponse) Reset() { *x = FetchSnapshotResponse{} - mi := &file_objectstore_proto_msgTypes[1] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -135,7 +135,7 @@ func (x *FetchSnapshotResponse) String() string { func (*FetchSnapshotResponse) ProtoMessage() {} func (x *FetchSnapshotResponse) ProtoReflect() protoreflect.Message { - mi := &file_objectstore_proto_msgTypes[1] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -148,7 +148,7 @@ func (x *FetchSnapshotResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchSnapshotResponse.ProtoReflect.Descriptor instead. func (*FetchSnapshotResponse) Descriptor() ([]byte, []int) { - return file_objectstore_proto_rawDescGZIP(), []int{1} + return file_api_objectstore_v1_objectstore_proto_rawDescGZIP(), []int{1} } // UploadSnapshotRequest asks the plugin to upload snapshot files. @@ -174,7 +174,7 @@ type UploadSnapshotRequest struct { func (x *UploadSnapshotRequest) Reset() { *x = UploadSnapshotRequest{} - mi := &file_objectstore_proto_msgTypes[2] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -186,7 +186,7 @@ func (x *UploadSnapshotRequest) String() string { func (*UploadSnapshotRequest) ProtoMessage() {} func (x *UploadSnapshotRequest) ProtoReflect() protoreflect.Message { - mi := &file_objectstore_proto_msgTypes[2] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -199,7 +199,7 @@ func (x *UploadSnapshotRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadSnapshotRequest.ProtoReflect.Descriptor instead. func (*UploadSnapshotRequest) Descriptor() ([]byte, []int) { - return file_objectstore_proto_rawDescGZIP(), []int{2} + return file_api_objectstore_v1_objectstore_proto_rawDescGZIP(), []int{2} } func (x *UploadSnapshotRequest) GetSnapshotUri() string { @@ -238,7 +238,7 @@ type UploadSnapshotResponse struct { func (x *UploadSnapshotResponse) Reset() { *x = UploadSnapshotResponse{} - mi := &file_objectstore_proto_msgTypes[3] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -250,7 +250,7 @@ func (x *UploadSnapshotResponse) String() string { func (*UploadSnapshotResponse) ProtoMessage() {} func (x *UploadSnapshotResponse) ProtoReflect() protoreflect.Message { - mi := &file_objectstore_proto_msgTypes[3] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -263,7 +263,7 @@ func (x *UploadSnapshotResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadSnapshotResponse.ProtoReflect.Descriptor instead. func (*UploadSnapshotResponse) Descriptor() ([]byte, []int) { - return file_objectstore_proto_rawDescGZIP(), []int{3} + return file_api_objectstore_v1_objectstore_proto_rawDescGZIP(), []int{3} } // CleanupSnapshotRequest names the snapshots to delete. @@ -279,7 +279,7 @@ type CleanupSnapshotRequest struct { func (x *CleanupSnapshotRequest) Reset() { *x = CleanupSnapshotRequest{} - mi := &file_objectstore_proto_msgTypes[4] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -291,7 +291,7 @@ func (x *CleanupSnapshotRequest) String() string { func (*CleanupSnapshotRequest) ProtoMessage() {} func (x *CleanupSnapshotRequest) ProtoReflect() protoreflect.Message { - mi := &file_objectstore_proto_msgTypes[4] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -304,7 +304,7 @@ func (x *CleanupSnapshotRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CleanupSnapshotRequest.ProtoReflect.Descriptor instead. func (*CleanupSnapshotRequest) Descriptor() ([]byte, []int) { - return file_objectstore_proto_rawDescGZIP(), []int{4} + return file_api_objectstore_v1_objectstore_proto_rawDescGZIP(), []int{4} } func (x *CleanupSnapshotRequest) GetSnapshotUri() string { @@ -322,7 +322,7 @@ type CleanupSnapshotResponse struct { func (x *CleanupSnapshotResponse) Reset() { *x = CleanupSnapshotResponse{} - mi := &file_objectstore_proto_msgTypes[5] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -334,7 +334,7 @@ func (x *CleanupSnapshotResponse) String() string { func (*CleanupSnapshotResponse) ProtoMessage() {} func (x *CleanupSnapshotResponse) ProtoReflect() protoreflect.Message { - mi := &file_objectstore_proto_msgTypes[5] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -347,7 +347,7 @@ func (x *CleanupSnapshotResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CleanupSnapshotResponse.ProtoReflect.Descriptor instead. func (*CleanupSnapshotResponse) Descriptor() ([]byte, []int) { - return file_objectstore_proto_rawDescGZIP(), []int{5} + return file_api_objectstore_v1_objectstore_proto_rawDescGZIP(), []int{5} } // CopySnapshotRequest names the source and destination snapshots. @@ -363,7 +363,7 @@ type CopySnapshotRequest struct { func (x *CopySnapshotRequest) Reset() { *x = CopySnapshotRequest{} - mi := &file_objectstore_proto_msgTypes[6] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -375,7 +375,7 @@ func (x *CopySnapshotRequest) String() string { func (*CopySnapshotRequest) ProtoMessage() {} func (x *CopySnapshotRequest) ProtoReflect() protoreflect.Message { - mi := &file_objectstore_proto_msgTypes[6] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -388,7 +388,7 @@ func (x *CopySnapshotRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CopySnapshotRequest.ProtoReflect.Descriptor instead. func (*CopySnapshotRequest) Descriptor() ([]byte, []int) { - return file_objectstore_proto_rawDescGZIP(), []int{6} + return file_api_objectstore_v1_objectstore_proto_rawDescGZIP(), []int{6} } func (x *CopySnapshotRequest) GetSrcUri() string { @@ -413,7 +413,7 @@ type CopySnapshotResponse struct { func (x *CopySnapshotResponse) Reset() { *x = CopySnapshotResponse{} - mi := &file_objectstore_proto_msgTypes[7] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -425,7 +425,7 @@ func (x *CopySnapshotResponse) String() string { func (*CopySnapshotResponse) ProtoMessage() {} func (x *CopySnapshotResponse) ProtoReflect() protoreflect.Message { - mi := &file_objectstore_proto_msgTypes[7] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -438,7 +438,7 @@ func (x *CopySnapshotResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CopySnapshotResponse.ProtoReflect.Descriptor instead. func (*CopySnapshotResponse) Descriptor() ([]byte, []int) { - return file_objectstore_proto_rawDescGZIP(), []int{7} + return file_api_objectstore_v1_objectstore_proto_rawDescGZIP(), []int{7} } // FetchAssetRequest asks the plugin to fetch one content-addressed asset. @@ -466,7 +466,7 @@ type FetchAssetRequest struct { func (x *FetchAssetRequest) Reset() { *x = FetchAssetRequest{} - mi := &file_objectstore_proto_msgTypes[8] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -478,7 +478,7 @@ func (x *FetchAssetRequest) String() string { func (*FetchAssetRequest) ProtoMessage() {} func (x *FetchAssetRequest) ProtoReflect() protoreflect.Message { - mi := &file_objectstore_proto_msgTypes[8] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -491,7 +491,7 @@ func (x *FetchAssetRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchAssetRequest.ProtoReflect.Descriptor instead. func (*FetchAssetRequest) Descriptor() ([]byte, []int) { - return file_objectstore_proto_rawDescGZIP(), []int{8} + return file_api_objectstore_v1_objectstore_proto_rawDescGZIP(), []int{8} } func (x *FetchAssetRequest) GetAssetUri() string { @@ -530,7 +530,7 @@ type FetchAssetResponse struct { func (x *FetchAssetResponse) Reset() { *x = FetchAssetResponse{} - mi := &file_objectstore_proto_msgTypes[9] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -542,7 +542,7 @@ func (x *FetchAssetResponse) String() string { func (*FetchAssetResponse) ProtoMessage() {} func (x *FetchAssetResponse) ProtoReflect() protoreflect.Message { - mi := &file_objectstore_proto_msgTypes[9] + mi := &file_api_objectstore_v1_objectstore_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -555,14 +555,14 @@ func (x *FetchAssetResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchAssetResponse.ProtoReflect.Descriptor instead. func (*FetchAssetResponse) Descriptor() ([]byte, []int) { - return file_objectstore_proto_rawDescGZIP(), []int{9} + return file_api_objectstore_v1_objectstore_proto_rawDescGZIP(), []int{9} } -var File_objectstore_proto protoreflect.FileDescriptor +var File_api_objectstore_v1_objectstore_proto protoreflect.FileDescriptor -const file_objectstore_proto_rawDesc = "" + +const file_api_objectstore_v1_objectstore_proto_rawDesc = "" + "\n" + - "\x11objectstore.proto\x12\x0eobjectstore.v1\"\x90\x01\n" + + "$api/objectstore/v1/objectstore.proto\x12\x18substrate.objectstore.v1\"\x90\x01\n" + "\x14FetchSnapshotRequest\x12!\n" + "\fsnapshot_uri\x18\x01 \x01(\tR\vsnapshotUri\x12 \n" + "\tactor_jwt\x18\x02 \x01(\tB\x03\x80\x01\x01R\bactorJwt\x12\x1d\n" + @@ -590,53 +590,53 @@ const file_objectstore_proto_rawDesc = "" + "\n" + "write_path\x18\x03 \x01(\tR\twritePath\x12\x1b\n" + "\tmax_bytes\x18\x04 \x01(\x03R\bmaxBytes\"\x14\n" + - "\x12FetchAssetResponse2\xd1\x01\n" + - "\fNodeProvider\x12^\n" + - "\rFetchSnapshot\x12$.objectstore.v1.FetchSnapshotRequest\x1a%.objectstore.v1.FetchSnapshotResponse\"\x00\x12a\n" + - "\x0eUploadSnapshot\x12%.objectstore.v1.UploadSnapshotRequest\x1a&.objectstore.v1.UploadSnapshotResponse\"\x002\xd4\x01\n" + - "\x0fControlProvider\x12d\n" + - "\x0fCleanupSnapshot\x12&.objectstore.v1.CleanupSnapshotRequest\x1a'.objectstore.v1.CleanupSnapshotResponse\"\x00\x12[\n" + - "\fCopySnapshot\x12#.objectstore.v1.CopySnapshotRequest\x1a$.objectstore.v1.CopySnapshotResponse\"\x002f\n" + - "\rAssetProvider\x12U\n" + + "\x12FetchAssetResponse2\xf9\x01\n" + + "\fNodeProvider\x12r\n" + + "\rFetchSnapshot\x12..substrate.objectstore.v1.FetchSnapshotRequest\x1a/.substrate.objectstore.v1.FetchSnapshotResponse\"\x00\x12u\n" + + "\x0eUploadSnapshot\x12/.substrate.objectstore.v1.UploadSnapshotRequest\x1a0.substrate.objectstore.v1.UploadSnapshotResponse\"\x002\xfc\x01\n" + + "\x0fControlProvider\x12x\n" + + "\x0fCleanupSnapshot\x120.substrate.objectstore.v1.CleanupSnapshotRequest\x1a1.substrate.objectstore.v1.CleanupSnapshotResponse\"\x00\x12o\n" + + "\fCopySnapshot\x12-.substrate.objectstore.v1.CopySnapshotRequest\x1a..substrate.objectstore.v1.CopySnapshotResponse\"\x002z\n" + + "\rAssetProvider\x12i\n" + "\n" + - "FetchAsset\x12!.objectstore.v1.FetchAssetRequest\x1a\".objectstore.v1.FetchAssetResponse\"\x00B?Z=go.ate.dev/substrate/pkg/proto/objectstorepb/v1;objectstorev1b\x06proto3" + "FetchAsset\x12+.substrate.objectstore.v1.FetchAssetRequest\x1a,.substrate.objectstore.v1.FetchAssetResponse\"\x00B5Z3go.ate.dev/substrate/api/objectstore/v1;objectstoreb\x06proto3" var ( - file_objectstore_proto_rawDescOnce sync.Once - file_objectstore_proto_rawDescData []byte + file_api_objectstore_v1_objectstore_proto_rawDescOnce sync.Once + file_api_objectstore_v1_objectstore_proto_rawDescData []byte ) -func file_objectstore_proto_rawDescGZIP() []byte { - file_objectstore_proto_rawDescOnce.Do(func() { - file_objectstore_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_objectstore_proto_rawDesc), len(file_objectstore_proto_rawDesc))) +func file_api_objectstore_v1_objectstore_proto_rawDescGZIP() []byte { + file_api_objectstore_v1_objectstore_proto_rawDescOnce.Do(func() { + file_api_objectstore_v1_objectstore_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_api_objectstore_v1_objectstore_proto_rawDesc), len(file_api_objectstore_v1_objectstore_proto_rawDesc))) }) - return file_objectstore_proto_rawDescData -} - -var file_objectstore_proto_msgTypes = make([]protoimpl.MessageInfo, 10) -var file_objectstore_proto_goTypes = []any{ - (*FetchSnapshotRequest)(nil), // 0: objectstore.v1.FetchSnapshotRequest - (*FetchSnapshotResponse)(nil), // 1: objectstore.v1.FetchSnapshotResponse - (*UploadSnapshotRequest)(nil), // 2: objectstore.v1.UploadSnapshotRequest - (*UploadSnapshotResponse)(nil), // 3: objectstore.v1.UploadSnapshotResponse - (*CleanupSnapshotRequest)(nil), // 4: objectstore.v1.CleanupSnapshotRequest - (*CleanupSnapshotResponse)(nil), // 5: objectstore.v1.CleanupSnapshotResponse - (*CopySnapshotRequest)(nil), // 6: objectstore.v1.CopySnapshotRequest - (*CopySnapshotResponse)(nil), // 7: objectstore.v1.CopySnapshotResponse - (*FetchAssetRequest)(nil), // 8: objectstore.v1.FetchAssetRequest - (*FetchAssetResponse)(nil), // 9: objectstore.v1.FetchAssetResponse -} -var file_objectstore_proto_depIdxs = []int32{ - 0, // 0: objectstore.v1.NodeProvider.FetchSnapshot:input_type -> objectstore.v1.FetchSnapshotRequest - 2, // 1: objectstore.v1.NodeProvider.UploadSnapshot:input_type -> objectstore.v1.UploadSnapshotRequest - 4, // 2: objectstore.v1.ControlProvider.CleanupSnapshot:input_type -> objectstore.v1.CleanupSnapshotRequest - 6, // 3: objectstore.v1.ControlProvider.CopySnapshot:input_type -> objectstore.v1.CopySnapshotRequest - 8, // 4: objectstore.v1.AssetProvider.FetchAsset:input_type -> objectstore.v1.FetchAssetRequest - 1, // 5: objectstore.v1.NodeProvider.FetchSnapshot:output_type -> objectstore.v1.FetchSnapshotResponse - 3, // 6: objectstore.v1.NodeProvider.UploadSnapshot:output_type -> objectstore.v1.UploadSnapshotResponse - 5, // 7: objectstore.v1.ControlProvider.CleanupSnapshot:output_type -> objectstore.v1.CleanupSnapshotResponse - 7, // 8: objectstore.v1.ControlProvider.CopySnapshot:output_type -> objectstore.v1.CopySnapshotResponse - 9, // 9: objectstore.v1.AssetProvider.FetchAsset:output_type -> objectstore.v1.FetchAssetResponse + return file_api_objectstore_v1_objectstore_proto_rawDescData +} + +var file_api_objectstore_v1_objectstore_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_api_objectstore_v1_objectstore_proto_goTypes = []any{ + (*FetchSnapshotRequest)(nil), // 0: substrate.objectstore.v1.FetchSnapshotRequest + (*FetchSnapshotResponse)(nil), // 1: substrate.objectstore.v1.FetchSnapshotResponse + (*UploadSnapshotRequest)(nil), // 2: substrate.objectstore.v1.UploadSnapshotRequest + (*UploadSnapshotResponse)(nil), // 3: substrate.objectstore.v1.UploadSnapshotResponse + (*CleanupSnapshotRequest)(nil), // 4: substrate.objectstore.v1.CleanupSnapshotRequest + (*CleanupSnapshotResponse)(nil), // 5: substrate.objectstore.v1.CleanupSnapshotResponse + (*CopySnapshotRequest)(nil), // 6: substrate.objectstore.v1.CopySnapshotRequest + (*CopySnapshotResponse)(nil), // 7: substrate.objectstore.v1.CopySnapshotResponse + (*FetchAssetRequest)(nil), // 8: substrate.objectstore.v1.FetchAssetRequest + (*FetchAssetResponse)(nil), // 9: substrate.objectstore.v1.FetchAssetResponse +} +var file_api_objectstore_v1_objectstore_proto_depIdxs = []int32{ + 0, // 0: substrate.objectstore.v1.NodeProvider.FetchSnapshot:input_type -> substrate.objectstore.v1.FetchSnapshotRequest + 2, // 1: substrate.objectstore.v1.NodeProvider.UploadSnapshot:input_type -> substrate.objectstore.v1.UploadSnapshotRequest + 4, // 2: substrate.objectstore.v1.ControlProvider.CleanupSnapshot:input_type -> substrate.objectstore.v1.CleanupSnapshotRequest + 6, // 3: substrate.objectstore.v1.ControlProvider.CopySnapshot:input_type -> substrate.objectstore.v1.CopySnapshotRequest + 8, // 4: substrate.objectstore.v1.AssetProvider.FetchAsset:input_type -> substrate.objectstore.v1.FetchAssetRequest + 1, // 5: substrate.objectstore.v1.NodeProvider.FetchSnapshot:output_type -> substrate.objectstore.v1.FetchSnapshotResponse + 3, // 6: substrate.objectstore.v1.NodeProvider.UploadSnapshot:output_type -> substrate.objectstore.v1.UploadSnapshotResponse + 5, // 7: substrate.objectstore.v1.ControlProvider.CleanupSnapshot:output_type -> substrate.objectstore.v1.CleanupSnapshotResponse + 7, // 8: substrate.objectstore.v1.ControlProvider.CopySnapshot:output_type -> substrate.objectstore.v1.CopySnapshotResponse + 9, // 9: substrate.objectstore.v1.AssetProvider.FetchAsset:output_type -> substrate.objectstore.v1.FetchAssetResponse 5, // [5:10] is the sub-list for method output_type 0, // [0:5] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name @@ -644,26 +644,26 @@ var file_objectstore_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for field type_name } -func init() { file_objectstore_proto_init() } -func file_objectstore_proto_init() { - if File_objectstore_proto != nil { +func init() { file_api_objectstore_v1_objectstore_proto_init() } +func file_api_objectstore_v1_objectstore_proto_init() { + if File_api_objectstore_v1_objectstore_proto != nil { return } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_objectstore_proto_rawDesc), len(file_objectstore_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_objectstore_v1_objectstore_proto_rawDesc), len(file_api_objectstore_v1_objectstore_proto_rawDesc)), NumEnums: 0, NumMessages: 10, NumExtensions: 0, NumServices: 3, }, - GoTypes: file_objectstore_proto_goTypes, - DependencyIndexes: file_objectstore_proto_depIdxs, - MessageInfos: file_objectstore_proto_msgTypes, + GoTypes: file_api_objectstore_v1_objectstore_proto_goTypes, + DependencyIndexes: file_api_objectstore_v1_objectstore_proto_depIdxs, + MessageInfos: file_api_objectstore_v1_objectstore_proto_msgTypes, }.Build() - File_objectstore_proto = out.File - file_objectstore_proto_goTypes = nil - file_objectstore_proto_depIdxs = nil + File_api_objectstore_v1_objectstore_proto = out.File + file_api_objectstore_v1_objectstore_proto_goTypes = nil + file_api_objectstore_v1_objectstore_proto_depIdxs = nil } diff --git a/pkg/proto/objectstorepb/v1/objectstore.proto b/api/objectstore/v1/objectstore.proto similarity index 98% rename from pkg/proto/objectstorepb/v1/objectstore.proto rename to api/objectstore/v1/objectstore.proto index 698eab75f3..70a62867b7 100644 --- a/pkg/proto/objectstorepb/v1/objectstore.proto +++ b/api/objectstore/v1/objectstore.proto @@ -14,9 +14,9 @@ syntax = "proto3"; -package objectstore.v1; +package substrate.objectstore.v1; -option go_package = "go.ate.dev/substrate/pkg/proto/objectstorepb/v1;objectstorev1"; +option go_package = "go.ate.dev/substrate/api/objectstore/v1;objectstore"; // NodeProvider is the plugin API an object storage platform implements // on every node. atelet calls it to move actor snapshots between the node and diff --git a/pkg/proto/objectstorepb/v1/objectstore_grpc.pb.go b/api/objectstore/v1/objectstore_grpc.pb.go similarity index 96% rename from pkg/proto/objectstorepb/v1/objectstore_grpc.pb.go rename to api/objectstore/v1/objectstore_grpc.pb.go index 4bd992a7a8..856dfb82c0 100644 --- a/pkg/proto/objectstorepb/v1/objectstore_grpc.pb.go +++ b/api/objectstore/v1/objectstore_grpc.pb.go @@ -16,9 +16,9 @@ // versions: // - protoc-gen-go-grpc v1.6.2 // - protoc v4.25.3 -// source: objectstore.proto +// source: api/objectstore/v1/objectstore.proto -package objectstorev1 +package objectstore import ( context "context" @@ -33,8 +33,8 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - NodeProvider_FetchSnapshot_FullMethodName = "/objectstore.v1.NodeProvider/FetchSnapshot" - NodeProvider_UploadSnapshot_FullMethodName = "/objectstore.v1.NodeProvider/UploadSnapshot" + NodeProvider_FetchSnapshot_FullMethodName = "/substrate.objectstore.v1.NodeProvider/FetchSnapshot" + NodeProvider_UploadSnapshot_FullMethodName = "/substrate.objectstore.v1.NodeProvider/UploadSnapshot" ) // NodeProviderClient is the client API for NodeProvider service. @@ -206,7 +206,7 @@ func _NodeProvider_UploadSnapshot_Handler(srv interface{}, ctx context.Context, // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var NodeProvider_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "objectstore.v1.NodeProvider", + ServiceName: "substrate.objectstore.v1.NodeProvider", HandlerType: (*NodeProviderServer)(nil), Methods: []grpc.MethodDesc{ { @@ -219,12 +219,12 @@ var NodeProvider_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "objectstore.proto", + Metadata: "api/objectstore/v1/objectstore.proto", } const ( - ControlProvider_CleanupSnapshot_FullMethodName = "/objectstore.v1.ControlProvider/CleanupSnapshot" - ControlProvider_CopySnapshot_FullMethodName = "/objectstore.v1.ControlProvider/CopySnapshot" + ControlProvider_CleanupSnapshot_FullMethodName = "/substrate.objectstore.v1.ControlProvider/CleanupSnapshot" + ControlProvider_CopySnapshot_FullMethodName = "/substrate.objectstore.v1.ControlProvider/CopySnapshot" ) // ControlProviderClient is the client API for ControlProvider service. @@ -364,7 +364,7 @@ func _ControlProvider_CopySnapshot_Handler(srv interface{}, ctx context.Context, // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var ControlProvider_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "objectstore.v1.ControlProvider", + ServiceName: "substrate.objectstore.v1.ControlProvider", HandlerType: (*ControlProviderServer)(nil), Methods: []grpc.MethodDesc{ { @@ -377,11 +377,11 @@ var ControlProvider_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "objectstore.proto", + Metadata: "api/objectstore/v1/objectstore.proto", } const ( - AssetProvider_FetchAsset_FullMethodName = "/objectstore.v1.AssetProvider/FetchAsset" + AssetProvider_FetchAsset_FullMethodName = "/substrate.objectstore.v1.AssetProvider/FetchAsset" ) // AssetProviderClient is the client API for AssetProvider service. @@ -512,7 +512,7 @@ func _AssetProvider_FetchAsset_Handler(srv interface{}, ctx context.Context, dec // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var AssetProvider_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "objectstore.v1.AssetProvider", + ServiceName: "substrate.objectstore.v1.AssetProvider", HandlerType: (*AssetProviderServer)(nil), Methods: []grpc.MethodDesc{ { @@ -521,5 +521,5 @@ var AssetProvider_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "objectstore.proto", + Metadata: "api/objectstore/v1/objectstore.proto", } diff --git a/benchmarking/atunnel/README.md b/benchmarking/atunnel/README.md index d1defc54ac..f22930b381 100644 --- a/benchmarking/atunnel/README.md +++ b/benchmarking/atunnel/README.md @@ -77,8 +77,8 @@ Which subcommand runs where: same order: - at startup: `tunnel.Start` with the worker's own flags, through `tunnel.RegisterFlags`; -- per actor: `tunnel.PrepareEgress`, `actornet.ServeSandbox`, and - `tunnel.Activate`; +- per actor: `tunnel.PrepareEgress`, `actornet.ServeSandbox`, + `tunnel.ActivateEgress`, and `tunnel.ActivateIngress`; - at teardown: `tunnel.Deactivate`, then closing the sandbox network. Each actor gets real network namespaces, the nftables redirect, an egress diff --git a/benchmarking/atunnel/internal/workerhost/workerhost.go b/benchmarking/atunnel/internal/workerhost/workerhost.go index ff7bc107f7..1080741a83 100644 --- a/benchmarking/atunnel/internal/workerhost/workerhost.go +++ b/benchmarking/atunnel/internal/workerhost/workerhost.go @@ -117,7 +117,10 @@ func (h *Host) host(ctx context.Context, attribution resources.ActorAttribution, h.mu.Lock() h.actors = append(h.actors, &actor{attribution: attribution, session: session}) h.mu.Unlock() - return h.tunnel.Activate(attribution, session.Dialer(), egress) + if err := h.tunnel.ActivateEgress(attribution, egress); err != nil { + return err + } + return h.tunnel.ActivateIngress(attribution, session.Dialer()) } // Info returns the hosted actors. diff --git a/benchmarking/locust/Dockerfile b/benchmarking/locust/Dockerfile index c2ecb40d8c..15c704772d 100644 --- a/benchmarking/locust/Dockerfile +++ b/benchmarking/locust/Dockerfile @@ -13,7 +13,7 @@ # limitations under the License. # Build context must be the monorepo root so the Go builder can pull in -# cmd/, internal/, pkg/, and vendor/. build_and_push.sh sets this up. +# api/, cmd/, internal/, pkg/, and vendor/. build_and_push.sh sets this up. # Stage 1: Python dependency builder FROM python:3.11-slim AS pydeps @@ -28,7 +28,7 @@ WORKDIR /src COPY benchmarking/locust/codegen/requirements.txt benchmarking/locust/codegen/ RUN pip install --no-cache-dir -r benchmarking/locust/codegen/requirements.txt COPY benchmarking/locust/codegen/generate.sh benchmarking/locust/codegen/ -COPY pkg/proto pkg/proto +COPY api api COPY internal/proto internal/proto RUN PYTHON=python3 OUT_DIR=/out benchmarking/locust/codegen/generate.sh @@ -40,6 +40,7 @@ ENV GOTOOLCHAIN=auto WORKDIR /src COPY go.mod go.sum ./ COPY vendor ./vendor +COPY api ./api COPY cmd ./cmd COPY internal ./internal COPY pkg ./pkg diff --git a/benchmarking/locust/cluster_facts.py b/benchmarking/locust/cluster_facts.py index 1f983565c5..b39aee4b39 100644 --- a/benchmarking/locust/cluster_facts.py +++ b/benchmarking/locust/cluster_facts.py @@ -293,36 +293,12 @@ def append_trial_summary( # a truncated sample understates the peak without looking wrong. observed = [] - # The flag stands in only when no sample was read at all. - peak_users = max(observed) if observed else args.users - - # Locust counts VUs, not actors, and one VU drives --actors-per-user of them. - per_user = args.actors_per_user or 1 - peak_actors = peak_users * per_user - - node_count = facts.get("node_count") - cores = facts.get("allocatable_cores") - ram_gb = facts.get("allocatable_ram_gb") - pod_count = facts.get("worker_pod_count") - - actors_per_node = round(peak_actors / node_count, 2) if node_count else None - actors_per_vcpu = round(peak_actors / cores, 2) if cores else None - actors_per_gb_ram = round(peak_actors / ram_gb, 2) if ram_gb else None - - # Actors per pod across every sample, ramp-up included. Under a load shape - # there is no one target to measure steadiness against, so the - # distribution covers the whole run. - actors_per_pod_p50, actors_per_pod_p90, actors_per_pod_p99 = None, None, None - if observed and pod_count: - ratios = sorted(round(u * per_user / pod_count, 4) for u in observed) - n = len(ratios) - actors_per_pod_p50 = round(ratios[int(n * 0.50)], 2) - actors_per_pod_p90 = round(ratios[min(int(n * 0.90), n - 1)], 2) - actors_per_pod_p99 = round(ratios[min(int(n * 0.99), n - 1)], 2) - # One ratio per row Locust reported, so a test's own operation names carry # through. Absent when the test has no such row, null when it ran nothing. failure_ratios: dict[str, float | None] = {"aggregate_failure_ratio": None} + create_actor_successes: int | None = None + delete_actor_requests = 0 + retired_task_requests = 0 if stats_csv.exists(): try: with open(stats_csv, encoding="utf-8") as f: @@ -338,6 +314,12 @@ def append_trial_summary( if name == "Aggregated": failure_ratios["aggregate_failure_ratio"] = ratio continue + if name == "CreateActor": + create_actor_successes = max(requests - failures, 0) + elif name == "DeleteActor": + delete_actor_requests = requests + elif name == "TaskWallClock": + retired_task_requests = requests key = re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", name) key = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1_\2", key) key = re.sub(r"[^a-z0-9]+", "_", key.lower()).strip("_") @@ -345,9 +327,54 @@ def append_trial_summary( except Exception as e: _log(logs, f"Notice: could not parse {stats_csv}: {e}") failure_ratios = {"aggregate_failure_ratio": None} + create_actor_successes = None + delete_actor_requests = 0 + retired_task_requests = 0 else: _log(logs, f"Notice: {stats_csv} not found; failure ratios unknown") + # The flag stands in only when no sample was read at all. + peak_users = max(observed) if observed else args.users + + # Locust counts VUs, not actors, and one VU drives --actors-per-user of them. + per_user = args.actors_per_user or 1 + peak_actors = peak_users * per_user + + # Locust's User Count tracks spawned VU goroutines even when CreateActor + # fails or broken actors are deleted during the run. When the test records + # CreateActor in stats.csv, cap by the actors still alive at the end of the + # run (stats.csv is written before boomer's shutdown DeleteActor sweep). + # In sweperf, each completed TaskWallClock retires its actor with + # DeleteActor before starting a fresh one, so only unretired deletes count + # as failed/wedged actors. + if create_actor_successes is not None: + unretired_deletes = max(delete_actor_requests - retired_task_requests, 0) + live_actors = max(create_actor_successes - unretired_deletes, 0) + peak_actors = min(peak_actors, live_actors) + + node_count = facts.get("node_count") + cores = facts.get("allocatable_cores") + ram_gb = facts.get("allocatable_ram_gb") + pod_count = facts.get("worker_pod_count") + + actors_per_node = round(peak_actors / node_count, 2) if node_count else None + actors_per_vcpu = round(peak_actors / cores, 2) if cores else None + actors_per_gb_ram = round(peak_actors / ram_gb, 2) if ram_gb else None + + # Actors per pod across every sample, ramp-up included. Under a load shape + # there is no one target to measure steadiness against, so the + # distribution covers the whole run. + actors_per_pod_p50, actors_per_pod_p90, actors_per_pod_p99 = None, None, None + if observed and pod_count: + ratios = sorted( + round(min(u * per_user, peak_actors) / pod_count, 4) + for u in observed + ) + n = len(ratios) + actors_per_pod_p50 = round(ratios[int(n * 0.50)], 2) + actors_per_pod_p90 = round(ratios[min(int(n * 0.90), n - 1)], 2) + actors_per_pod_p99 = round(ratios[min(int(n * 0.99), n - 1)], 2) + # Whether workers hosted more than one actor at once (a multi-actor # worker), going by the median actors per pod. multi_actor_worker = ( diff --git a/benchmarking/locust/codegen/generate.sh b/benchmarking/locust/codegen/generate.sh index d62b1da6a3..cdaaedb0ee 100755 --- a/benchmarking/locust/codegen/generate.sh +++ b/benchmarking/locust/codegen/generate.sh @@ -37,7 +37,7 @@ CODEGEN_DIR="benchmarking/locust/codegen" OUT_DIR="${OUT_DIR:-benchmarking/locust/common}" if [[ $# -eq 0 ]]; then - set -- pkg/proto/ateapipb/ateapi.proto internal/proto/glutton/glutton.proto + set -- api/ateapi/v1/ateapi.proto internal/proto/glutton/glutton.proto fi if [[ -z "${PYTHON:-}" ]]; then diff --git a/benchmarking/locust/unit_tests/test_cluster_facts.py b/benchmarking/locust/unit_tests/test_cluster_facts.py index 13ad41b08b..7bfee84f02 100644 --- a/benchmarking/locust/unit_tests/test_cluster_facts.py +++ b/benchmarking/locust/unit_tests/test_cluster_facts.py @@ -457,6 +457,66 @@ def test_per_rpc_failure_ratios(self): self.assertNotIn("resume_actor_failure_ratio", row["measurements"]) self.assertNotIn("suspend_actor_failure_ratio", row["measurements"]) + def test_live_actors_from_create_and_delete(self): + metal_facts = { + **FACTS, + "node_count": 1, + "allocatable_cores": 191.25, + "allocatable_ram_gb": 369.51, + "worker_pod_count": 100, + } + # 1523 CreateActor (0 failed) minus 223 DeleteActor (warmup retries) + # leaves 1300 surviving actors at run end. + stats_ok = (STATS_HEADER + + "grpc,CreateActor,1523,0\n" + + "grpc,DeleteActor,223,0\n" + + ",Aggregated,5000,0\n") + with tempfile.TemporaryDirectory() as td: + m = summarize(metal_facts, td, stats_ok, users=1300, + user_counts=[650, 1300, 1300])["measurements"] + self.assertEqual(m["actors_per_node"], "1300.0") + self.assertEqual(m["actors_per_vcpu"], "6.8") + self.assertEqual(m["actors_per_pod_p50"], "13.0") + self.assertEqual(m["multi_actor_worker"], "true") + + # 100% CreateActor failure: Locust still spawned 1300 VU goroutines, + # but 0 actors were created, so density is 0 rather than 1300. + stats_fail = (STATS_HEADER + + "grpc,CreateActor,44507,44507\n" + + ",Aggregated,44507,44507\n") + with tempfile.TemporaryDirectory() as td: + m = summarize(metal_facts, td, stats_fail, users=1300, + user_counts=[650, 1300, 1300])["measurements"] + self.assertEqual(m["actors_per_node"], "0.0") + self.assertEqual(m["actors_per_vcpu"], "0.0") + self.assertEqual(m["actors_per_gb_ram"], "0.0") + self.assertEqual(m["actors_per_pod_p50"], "0.0") + self.assertEqual(m["multi_actor_worker"], "false") + + # Partial survival: 800 created, 100 deleted -> 700 surviving actors. + stats_partial = (STATS_HEADER + + "grpc,CreateActor,900,100\n" + + "grpc,DeleteActor,100,0\n" + + ",Aggregated,1000,100\n") + with tempfile.TemporaryDirectory() as td: + m = summarize(metal_facts, td, stats_partial, users=1300, + user_counts=[650, 1300, 1300])["measurements"] + self.assertEqual(m["actors_per_node"], "700.0") + self.assertEqual(m["actors_per_pod_p50"], "7.0") + + # sweperf retires completed trajectories (TaskWallClock) with + # DeleteActor mid-run; VUs between trajectories at run end still count. + stats_sweperf = (STATS_HEADER + + "grpc,CreateActor,490,0\n" + + "grpc,DeleteActor,400,0\n" + + "actor,TaskWallClock,400,0\n" + + ",Aggregated,1290,0\n") + with tempfile.TemporaryDirectory() as td: + m = summarize(metal_facts, td, stats_sweperf, users=100, + user_counts=[50, 100, 100])["measurements"] + self.assertEqual(m["actors_per_node"], "100.0") + self.assertEqual(m["actors_per_pod_p50"], "1.0") + def test_worker_pod_snapshot(self): api = fake_api(ns_pods=[ worker_pod("a", restarts=2, last="OOMKilled"), diff --git a/benchmarking/nighthawk-egress/egress-policy.yaml b/benchmarking/nighthawk-egress/egress-policy.yaml index 5e4bca28a1..673b2c82c4 100644 --- a/benchmarking/nighthawk-egress/egress-policy.yaml +++ b/benchmarking/nighthawk-egress/egress-policy.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Substrate EgressPolicy resource (protojson-shaped ateapipb.EgressPolicy, +# Substrate EgressPolicy resource (protojson-shaped ateapi.EgressPolicy, # NOT a Kubernetes CRD) for Nighthawk traffic-driver actors in the `nighthawk` # atespace. Applied to an actor with: # kubectl-ate create egress-policy -a nighthawk -f egress-policy.yaml diff --git a/benchmarking/nighthawk-egress/traffic-driver-template.yaml.tmpl b/benchmarking/nighthawk-egress/traffic-driver-template.yaml.tmpl index acaad876e7..27c68f984b 100644 --- a/benchmarking/nighthawk-egress/traffic-driver-template.yaml.tmpl +++ b/benchmarking/nighthawk-egress/traffic-driver-template.yaml.tmpl @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Substrate ActorTemplate resource (protojson-shaped ateapipb.ActorTemplate, -# NOT the ate.dev/v1alpha1 CRD) for the Nighthawk egress traffic-driver actor. +# Substrate ActorTemplate resource (protojson-shaped ateapi.ActorTemplate, +# NOT the ate.dev/v1 CRD) for the Nighthawk egress traffic-driver actor. # Applied with `kubectl-ate create actor-template -f -` by # deploy-traffic-driver.sh; the `nighthawk` atespace must exist. # diff --git a/benchmarking/nighthawk-egress/traffic-driver.yaml.tmpl b/benchmarking/nighthawk-egress/traffic-driver.yaml.tmpl index 478dd935eb..6853b65fbb 100644 --- a/benchmarking/nighthawk-egress/traffic-driver.yaml.tmpl +++ b/benchmarking/nighthawk-egress/traffic-driver.yaml.tmpl @@ -24,7 +24,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: traffic-driver diff --git a/benchmarking/nighthawk-ingress/Dockerfile b/benchmarking/nighthawk-ingress/Dockerfile index dafc03c657..949b484343 100644 --- a/benchmarking/nighthawk-ingress/Dockerfile +++ b/benchmarking/nighthawk-ingress/Dockerfile @@ -64,8 +64,8 @@ WORKDIR /src COPY benchmarking/locust/codegen/requirements.txt benchmarking/locust/codegen/ RUN pip install --no-cache-dir -r benchmarking/locust/codegen/requirements.txt COPY benchmarking/locust/codegen/generate.sh benchmarking/locust/codegen/ -COPY pkg/proto pkg/proto -RUN PYTHON=python3 OUT_DIR=/out benchmarking/locust/codegen/generate.sh pkg/proto/ateapipb/ateapi.proto +COPY api api +RUN PYTHON=python3 OUT_DIR=/out benchmarking/locust/codegen/generate.sh api/ateapi/v1/ateapi.proto # --- Stage 3: runtime ------------------------------------------------------- # nighthawk-dev has no stable tags; pinned by digest so the pull is diff --git a/benchmarking/workloads/manifests/ate-env-template.yaml.tmpl b/benchmarking/workloads/manifests/ate-env-template.yaml.tmpl index 7b5605c58f..2640d0846e 100644 --- a/benchmarking/workloads/manifests/ate-env-template.yaml.tmpl +++ b/benchmarking/workloads/manifests/ate-env-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the ate-env +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the ate-env # benchmark workload, created through the ate API by workloads/deploy.sh. metadata: atespace: benchmark-workloads diff --git a/benchmarking/workloads/manifests/glutton-durdir-data-template.yaml.tmpl b/benchmarking/workloads/manifests/glutton-durdir-data-template.yaml.tmpl index ee169fdeed..d507e18483 100644 --- a/benchmarking/workloads/manifests/glutton-durdir-data-template.yaml.tmpl +++ b/benchmarking/workloads/manifests/glutton-durdir-data-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the # glutton-durdir-data benchmark workload, created through the ate API by # workloads/deploy.sh. Suspend uploads ONLY the durable dir (DATA-scope # commit); resume from it is a cold boot. diff --git a/benchmarking/workloads/manifests/glutton-durdir-full-template.yaml.tmpl b/benchmarking/workloads/manifests/glutton-durdir-full-template.yaml.tmpl index 30aacdc7fb..0cbc965059 100644 --- a/benchmarking/workloads/manifests/glutton-durdir-full-template.yaml.tmpl +++ b/benchmarking/workloads/manifests/glutton-durdir-full-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the # glutton-durdir-full benchmark workload, created through the ate API by # workloads/deploy.sh. Like glutton-durdir-data but with FULL-scope commits. metadata: diff --git a/benchmarking/workloads/manifests/glutton-storage-template.yaml.tmpl b/benchmarking/workloads/manifests/glutton-storage-template.yaml.tmpl index 0ccd569269..ad7dcb28bb 100644 --- a/benchmarking/workloads/manifests/glutton-storage-template.yaml.tmpl +++ b/benchmarking/workloads/manifests/glutton-storage-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the glutton-storage +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the glutton-storage # benchmark workload, created through the ate API by workloads/deploy.sh. # Attaches an external volume backed by ${STORAGE_CLASS_NAME}. The DurDir load # runs it with --durdir-template glutton-storage. diff --git a/benchmarking/workloads/manifests/glutton-template.yaml.tmpl b/benchmarking/workloads/manifests/glutton-template.yaml.tmpl index 46fd41e7a5..7ed6d25d1b 100644 --- a/benchmarking/workloads/manifests/glutton-template.yaml.tmpl +++ b/benchmarking/workloads/manifests/glutton-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the glutton +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the glutton # benchmark workload, created through the ate API by workloads/deploy.sh. metadata: atespace: benchmark-workloads diff --git a/benchmarking/workloads/manifests/kernelmem-template.yaml.tmpl b/benchmarking/workloads/manifests/kernelmem-template.yaml.tmpl index e970a15195..7019662db9 100644 --- a/benchmarking/workloads/manifests/kernelmem-template.yaml.tmpl +++ b/benchmarking/workloads/manifests/kernelmem-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the kernelmem +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the kernelmem # benchmark workload (locust/tests/kernelmem.py): fills kernel memory with # dentry cache and sleeping processes to size kernel-state snapshots. Not # part of deploy.sh's default template set; deploy with diff --git a/benchmarking/workloads/manifests/sleep-template.yaml.tmpl b/benchmarking/workloads/manifests/sleep-template.yaml.tmpl index d7e04f67aa..5f9ced3242 100644 --- a/benchmarking/workloads/manifests/sleep-template.yaml.tmpl +++ b/benchmarking/workloads/manifests/sleep-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the sleep +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the sleep # benchmark workload, created through the ate API by workloads/deploy.sh. metadata: atespace: benchmark-workloads diff --git a/benchmarking/workloads/manifests/usermem-template.yaml.tmpl b/benchmarking/workloads/manifests/usermem-template.yaml.tmpl index 29a34a25fd..5b0bd1fc54 100644 --- a/benchmarking/workloads/manifests/usermem-template.yaml.tmpl +++ b/benchmarking/workloads/manifests/usermem-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the usermem +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the usermem # benchmark workload (locust/tests/usermem.py): stress holds 1 GiB of user # memory to size memory snapshots. Not part of deploy.sh's default template # set; deploy with WORKLOAD_TEMPLATES="usermem ...". Its memory limit is diff --git a/benchmarking/workloads/manifests/workloads.yaml.tmpl b/benchmarking/workloads/manifests/workloads.yaml.tmpl index e72b93d18a..bfcc597d36 100644 --- a/benchmarking/workloads/manifests/workloads.yaml.tmpl +++ b/benchmarking/workloads/manifests/workloads.yaml.tmpl @@ -24,7 +24,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: benchmark-worker diff --git a/charts/substrate-crds/templates/ate.dev_csidriverconfigs.yaml b/charts/substrate-crds/templates/ate.dev_csidriverconfigs.yaml index 0a53226fc3..557779da6c 100644 --- a/charts/substrate-crds/templates/ate.dev_csidriverconfigs.yaml +++ b/charts/substrate-crds/templates/ate.dev_csidriverconfigs.yaml @@ -36,7 +36,7 @@ spec: - jsonPath: .metadata.creationTimestamp name: Age type: date - name: v1alpha1 + name: v1 schema: openAPIV3Schema: description: CSIDriverConfig is the Schema for the csidriverconfigs API diff --git a/charts/substrate-crds/templates/ate.dev_sandboxconfigs.yaml b/charts/substrate-crds/templates/ate.dev_sandboxconfigs.yaml index 3e7c7e085f..58f3597cf3 100644 --- a/charts/substrate-crds/templates/ate.dev_sandboxconfigs.yaml +++ b/charts/substrate-crds/templates/ate.dev_sandboxconfigs.yaml @@ -39,7 +39,7 @@ spec: - jsonPath: .metadata.creationTimestamp name: Age type: date - name: v1alpha1 + name: v1 schema: openAPIV3Schema: description: |- diff --git a/charts/substrate-crds/templates/ate.dev_workerpools.yaml b/charts/substrate-crds/templates/ate.dev_workerpools.yaml index bc4e72e16f..d964ac6f1f 100644 --- a/charts/substrate-crds/templates/ate.dev_workerpools.yaml +++ b/charts/substrate-crds/templates/ate.dev_workerpools.yaml @@ -48,7 +48,7 @@ spec: - jsonPath: .metadata.creationTimestamp name: Age type: date - name: v1alpha1 + name: v1 schema: openAPIV3Schema: description: WorkerPool is the Schema for the workerpools API diff --git a/charts/substrate/README.md b/charts/substrate/README.md index 967d06061a..4ae503fd25 100644 --- a/charts/substrate/README.md +++ b/charts/substrate/README.md @@ -84,6 +84,18 @@ See `values.yaml` for the full set; the important keys: ## Upgrading sandbox and snapshot configuration +Public APIs now use versioned packages under `api/`. Upgrade clients, control +plane, workers, credential providers, object-store plugins, and agentgateway +together: gRPC service names now start with `substrate..v1`. + +WorkerPool, SandboxConfig, and CSIDriverConfig resources now use `ate.dev/v1`. +Update custom manifests and install `substrate-crds` before the application +chart. Existing clusters need a storage-version migration before replacing the +old CRDs: Kubernetes rejects the v1-only definitions while `status.storedVersions` +still contains `v1alpha1`. This release does not provide a conversion webhook or +an automated migration. Back up existing resources and plan their migration +before upgrading. + External volumes now require `preview: [ExternalVolumes]` and a client that opts in to the same gate (for `kubectl ate`, pass `--preview=ExternalVolumes`). Actor and ActorTemplate container resource limits must include positive CPU and diff --git a/charts/substrate/templates/ate-controller.yaml b/charts/substrate/templates/ate-controller.yaml index 40a6414374..1470f4c7c1 100644 --- a/charts/substrate/templates/ate-controller.yaml +++ b/charts/substrate/templates/ate-controller.yaml @@ -35,6 +35,20 @@ roleRef: name: {{ include "substrate.fullname" (list "ate-controller" .) }} apiGroup: rbac.authorization.k8s.io --- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "substrate.fullname" (list "ate-controller" .) }} + namespace: {{ .Release.Namespace }} +subjects: +- kind: ServiceAccount + name: {{ include "substrate.fullname" (list "ate-controller" .) }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: Role + name: {{ include "substrate.fullname" (list "ate-controller" .) }} + apiGroup: rbac.authorization.k8s.io +--- kind: Service apiVersion: v1 metadata: diff --git a/charts/substrate/templates/k8s-credential-provider.yaml b/charts/substrate/templates/k8s-credential-provider.yaml index f96f38a870..718e60879c 100644 --- a/charts/substrate/templates/k8s-credential-provider.yaml +++ b/charts/substrate/templates/k8s-credential-provider.yaml @@ -82,7 +82,8 @@ spec: - "--listen-address=:50051" - "--metrics-address=:9090" - "--health-address=:9091" - - "--status-address=:4040" + # The /statusz page binds 127.0.0.1 for port-forward access. + - "--status-address=127.0.0.1:4040" # Use this Service's DNS certificate; only the egress injector may call. - "--server-cred-bundle=/run/servicedns.podcert.ate.dev/credential-bundle.pem" - "--client-ca-file=/run/podidentity.podcert.ate.dev/trust-bundle.pem" @@ -97,8 +98,6 @@ spec: containerPort: 9090 - name: health containerPort: 9091 - - name: statusz - containerPort: 4040 readinessProbe: httpGet: path: /readyz diff --git a/charts/substrate/templates/role.yaml b/charts/substrate/templates/role.yaml index 669fcc25b4..17e87c76dc 100644 --- a/charts/substrate/templates/role.yaml +++ b/charts/substrate/templates/role.yaml @@ -27,14 +27,6 @@ rules: - get - list - watch -- apiGroups: - - "" - resources: - - secrets - verbs: - - get - - list - - watch - apiGroups: - "" resources: @@ -141,6 +133,16 @@ metadata: name: {{ include "substrate.fullname" (list "ate-controller" .) }} namespace: {{ .Release.Namespace }} rules: +- apiGroups: + - "" + resourceNames: + - egress-mitm-ca-pool + resources: + - secrets + verbs: + - get + - list + - watch - apiGroups: - discovery.k8s.io resources: diff --git a/charts/substrate/templates/sandboxconfig-gvisor.yaml b/charts/substrate/templates/sandboxconfig-gvisor.yaml index 888f7f68ce..911edf0c3d 100644 --- a/charts/substrate/templates/sandboxconfig-gvisor.yaml +++ b/charts/substrate/templates/sandboxconfig-gvisor.yaml @@ -25,7 +25,7 @@ limitations under the License. # A bump adds a version and points defaultVersion at it. Keep the # previous version unless it has a known vulnerability: an actor restores its # memory only on the version its snapshot was taken with. -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: SandboxConfig metadata: name: gvisor-default diff --git a/charts/substrate/templates/sandboxconfig-validation.yaml b/charts/substrate/templates/sandboxconfig-validation.yaml index 947b84f173..f71c076d93 100644 --- a/charts/substrate/templates/sandboxconfig-validation.yaml +++ b/charts/substrate/templates/sandboxconfig-validation.yaml @@ -28,7 +28,7 @@ spec: matchConstraints: resourceRules: - apiGroups: ["ate.dev"] - apiVersions: ["v1alpha1"] + apiVersions: ["v1"] operations: ["CREATE", "UPDATE"] resources: ["sandboxconfigs"] validations: diff --git a/charts/substrate/tests/control_plane_test.yaml b/charts/substrate/tests/control_plane_test.yaml index a803cdd54e..6929288577 100644 --- a/charts/substrate/tests/control_plane_test.yaml +++ b/charts/substrate/tests/control_plane_test.yaml @@ -16,6 +16,7 @@ suite: Control plane integration templates: - ate-api-server.yaml - ate-api-config.yaml +- ate-controller.yaml - role.yaml - atelet.yaml - k8s-credential-provider.yaml @@ -120,6 +121,14 @@ tests: - equal: path: spec.template.spec.containers[0].readinessProbe.httpGet.port value: health + - contains: + path: spec.template.spec.containers[0].args + content: --status-address=127.0.0.1:4040 + - notContains: + path: spec.template.spec.containers[0].ports + content: + name: statusz + containerPort: 4040 - it: denies ingress by default in the release namespace template: ate-system-networkpolicies.yaml documentSelector: @@ -260,6 +269,49 @@ tests: apiGroups: [ate.dev] resources: [sandboxconfigs] verbs: [get, list, patch, watch] + - notContains: + path: rules + content: + apiGroups: [""] + resources: [secrets] + verbs: [get, list, watch] +- it: limits controller secret reads to the MITM CA pool in the release namespace + template: role.yaml + documentSelector: + path: kind + value: Role + asserts: + - equal: + path: metadata.namespace + value: custom-system + - contains: + path: rules + content: + apiGroups: [""] + resourceNames: [egress-mitm-ca-pool] + resources: [secrets] + verbs: [get, list, watch] +- it: grants the controller its namespaced permissions + template: ate-controller.yaml + documentSelector: + path: kind + value: RoleBinding + asserts: + - equal: + path: metadata.namespace + value: custom-system + - equal: + path: roleRef + value: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: custom-ate-controller + - equal: + path: subjects + value: + - kind: ServiceAccount + name: custom-ate-controller + namespace: custom-system - it: limits API configuration reads to pools and CSI drivers template: ate-api-server.yaml documentSelector: diff --git a/charts/substrate/values.yaml b/charts/substrate/values.yaml index 517d9178f0..336fd71cac 100644 --- a/charts/substrate/values.yaml +++ b/charts/substrate/values.yaml @@ -235,5 +235,5 @@ image: images: rustfs: rustfs/rustfs:1.0.0-beta.3@sha256:378642b05b7dcb4849fb77ebe6aca4ced1c3f66e7e504247df95a5c9018d3358 awsCli: amazon/aws-cli:2.17.0@sha256:643507c10ada7964ca6157b3d799f030b90577643da9955d319a77399ed80d73 - agentgateway: ghcr.io/kagent-dev/substrate/agentgateway:cd65181fd52e@sha256:ebebf5a7fa2a54fb524ccce1f6f74ee6e7ef22d661f22e212717fd0a68dadb33 + agentgateway: ghcr.io/kagent-dev/substrate/agentgateway:c8550278b2f2@sha256:5703311439f92a898603e2abed32edcbaf6ec659dbb4d617568cef6d9c6fc789 busybox: busybox:1.36 diff --git a/cmd/ate-setup/internal/demos/demotest/demotest.go b/cmd/ate-setup/internal/demos/demotest/demotest.go index 9c5550caf4..5e845ba967 100644 --- a/cmd/ate-setup/internal/demos/demotest/demotest.go +++ b/cmd/ate-setup/internal/demos/demotest/demotest.go @@ -71,7 +71,7 @@ func AssertRendered(t *testing.T, manifest []byte) { // AssertRenderedActorTemplate checks that a rendered protojson ActorTemplate // manifest has every placeholder resolved and strictly parses into the -// ateapipb.ActorTemplate it will be created as, and that it names the given +// ateapi.ActorTemplate it will be created as, and that it names the given // (atespace, name). ko:// image references are left as written: they are // plain strings to the proto, resolved only at deploy time. func AssertRenderedActorTemplate(t *testing.T, manifest []byte, want resources.ActorTemplateRef) { diff --git a/cmd/ate-setup/internal/kube/client_test.go b/cmd/ate-setup/internal/kube/client_test.go index 66a75a8431..a65064b0e0 100644 --- a/cmd/ate-setup/internal/kube/client_test.go +++ b/cmd/ate-setup/internal/kube/client_test.go @@ -42,23 +42,23 @@ func TestInvalidateDiscoveryRebuildsTheRESTMapper(t *testing.T) { } sandboxConfig := schema.GroupKind{Group: "ate.dev", Kind: "SandboxConfig"} - if _, err := c.mapper.RESTMapping(sandboxConfig, "v1alpha1"); err == nil { + if _, err := c.mapper.RESTMapping(sandboxConfig, "v1"); err == nil { t.Fatal("RESTMapping() resolved SandboxConfig before its CRD was installed, want an error") } // The CRD lands, as `deploy crds` would install it. cs.Fake.Resources = append(cs.Fake.Resources, &metav1.APIResourceList{ - GroupVersion: "ate.dev/v1alpha1", + GroupVersion: "ate.dev/v1", APIResources: []metav1.APIResource{{Name: "sandboxconfigs", Kind: "SandboxConfig", Namespaced: true}}, }) c.InvalidateDiscovery() - mapping, err := c.mapper.RESTMapping(sandboxConfig, "v1alpha1") + mapping, err := c.mapper.RESTMapping(sandboxConfig, "v1") if err != nil { t.Fatalf("RESTMapping() after InvalidateDiscovery() error = %v, want the new CRD to be mappable", err) } - want := schema.GroupVersionResource{Group: "ate.dev", Version: "v1alpha1", Resource: "sandboxconfigs"} + want := schema.GroupVersionResource{Group: "ate.dev", Version: "v1", Resource: "sandboxconfigs"} if mapping.Resource != want { t.Errorf("mapping.Resource = %v, want %v", mapping.Resource, want) } @@ -70,7 +70,7 @@ func TestInvalidateDiscoveryRebuildsTheRESTMapper(t *testing.T) { cs.Fake.Resources = cs.Fake.Resources[:1] c.InvalidateDiscovery() - if _, err := c.mapper.RESTMapping(sandboxConfig, "v1alpha1"); err == nil { + if _, err := c.mapper.RESTMapping(sandboxConfig, "v1"); err == nil { t.Error("RESTMapping() still resolved SandboxConfig after its CRD left discovery, want an error") } } diff --git a/cmd/ate-setup/internal/steps/actors.go b/cmd/ate-setup/internal/steps/actors.go index fccfabb556..e4a5cca955 100644 --- a/cmd/ate-setup/internal/steps/actors.go +++ b/cmd/ate-setup/internal/steps/actors.go @@ -17,8 +17,8 @@ package steps import ( "context" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateclient" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // TemplateRef identifies a demo's ActorTemplate. Actors are deleted by matching @@ -33,13 +33,13 @@ type TemplateRef struct { } // listAllActors pages through every actor in every atespace. -func listAllActors(ctx context.Context, client *ateclient.Client) ([]*ateapipb.Actor, error) { - var all []*ateapipb.Actor +func listAllActors(ctx context.Context, client *ateclient.Client) ([]*ateapi.Actor, error) { + var all []*ateapi.Actor pageToken := "" for { // An empty Atespace lists across all atespaces. - resp, err := client.ListActors(ctx, &ateapipb.ListActorsRequest{ - Options: &ateapipb.ListOptions{PageSize: 1000, PageToken: pageToken}, + resp, err := client.ListActors(ctx, &ateapi.ListActorsRequest{ + Options: &ateapi.ListOptions{PageSize: 1000, PageToken: pageToken}, }) if err != nil { return nil, err diff --git a/cmd/ate-setup/internal/steps/csi.go b/cmd/ate-setup/internal/steps/csi.go index b05d71842f..cb06345e9d 100644 --- a/cmd/ate-setup/internal/steps/csi.go +++ b/cmd/ate-setup/internal/steps/csi.go @@ -271,7 +271,7 @@ spec: log.Infof("Creating the hostpath.csi.k8s.io CSIDriverConfig...") if err := e.applyInline(ctx, ` -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: CSIDriverConfig metadata: name: hostpath.csi.k8s.io @@ -457,7 +457,7 @@ spec: // csiNFSDriverConfig registers the NFS driver; its serverName is the one DNS name servicednssigner issues, ..svc. const csiNFSDriverConfig = ` -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: CSIDriverConfig metadata: name: nfs.csi.k8s.io diff --git a/cmd/ate-setup/internal/steps/delete.go b/cmd/ate-setup/internal/steps/delete.go index b8cb7a0adf..7223e8a332 100644 --- a/cmd/ate-setup/internal/steps/delete.go +++ b/cmd/ate-setup/internal/steps/delete.go @@ -26,9 +26,9 @@ import ( "k8s.io/client-go/dynamic" "k8s.io/client-go/util/retry" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/ate-setup/internal/log" "go.ate.dev/substrate/internal/clustertrustbundle" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" ) // DeleteAteSystem removes the control plane. @@ -82,7 +82,7 @@ func (e *Env) DeleteAteSystem(ctx context.Context) error { // Removing the protection finalizer by hand is safe here. atecontroller, // which would remove it, went away with the namespace. Deleting the CRDs // above deleted every WorkerPool, so no pool uses a config anymore. - if err := releaseSandboxConfigs(ctx, e.Kube.Dynamic.Resource(atev1alpha1.GroupVersion.WithResource("sandboxconfigs"))); err != nil { + if err := releaseSandboxConfigs(ctx, e.Kube.Dynamic.Resource(atev1.GroupVersion.WithResource("sandboxconfigs"))); err != nil { return err } // The podcertificate controller republishes its bundles every few @@ -113,7 +113,7 @@ func releaseSandboxConfigs(ctx context.Context, res dynamic.ResourceInterface) e return err } finalizers := slices.DeleteFunc(sc.GetFinalizers(), func(f string) bool { - return f == atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer + return f == atev1.SandboxConfigWorkerPoolProtectionFinalizer }) if len(finalizers) == len(sc.GetFinalizers()) { return nil diff --git a/cmd/ate-setup/internal/steps/delete_test.go b/cmd/ate-setup/internal/steps/delete_test.go index a2f97f47de..9274cadc6f 100644 --- a/cmd/ate-setup/internal/steps/delete_test.go +++ b/cmd/ate-setup/internal/steps/delete_test.go @@ -36,10 +36,10 @@ import ( ktesting "k8s.io/client-go/testing" "k8s.io/client-go/util/retry" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/ate-setup/internal/config" "go.ate.dev/substrate/cmd/ate-setup/internal/kube" "go.ate.dev/substrate/internal/clustertrustbundle" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" ) // fakeSandboxConfigs is an in-memory dynamic.ResourceInterface implementing @@ -58,7 +58,7 @@ type fakeSandboxConfigs struct { updates int } -var sandboxConfigsGR = atev1alpha1.GroupVersion.WithResource("sandboxconfigs").GroupResource() +var sandboxConfigsGR = atev1.GroupVersion.WithResource("sandboxconfigs").GroupResource() func (f *fakeSandboxConfigs) List(context.Context, metav1.ListOptions) (*unstructured.UnstructuredList, error) { if f.listErr != nil { @@ -69,7 +69,7 @@ func (f *fakeSandboxConfigs) List(context.Context, metav1.ListOptions) (*unstruc list.Items = append(list.Items, *o.DeepCopy()) } for _, name := range f.gone { - list.Items = append(list.Items, *newSandboxConfig(name, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer)) + list.Items = append(list.Items, *newSandboxConfig(name, atev1.SandboxConfigWorkerPoolProtectionFinalizer)) } return list, nil } @@ -94,14 +94,14 @@ func (f *fakeSandboxConfigs) Update(_ context.Context, obj *unstructured.Unstruc func newSandboxConfig(name string, finalizers ...string) *unstructured.Unstructured { u := &unstructured.Unstructured{} - u.SetGroupVersionKind(atev1alpha1.GroupVersion.WithKind("SandboxConfig")) + u.SetGroupVersionKind(atev1.GroupVersion.WithKind("SandboxConfig")) u.SetName(name) u.SetFinalizers(finalizers) return u } func TestReleaseSandboxConfigs(t *testing.T) { - const inUse = atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer + const inUse = atev1.SandboxConfigWorkerPoolProtectionFinalizer tests := []struct { name string res *fakeSandboxConfigs diff --git a/cmd/ate-setup/internal/steps/substrate.go b/cmd/ate-setup/internal/steps/substrate.go index 1b09386138..c5a3be7801 100644 --- a/cmd/ate-setup/internal/steps/substrate.go +++ b/cmd/ate-setup/internal/steps/substrate.go @@ -25,11 +25,11 @@ import ( "google.golang.org/protobuf/encoding/protojson" "sigs.k8s.io/yaml" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ate-setup/internal/log" "go.ate.dev/substrate/internal/ateclient" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // AteClient connects to the ate-api-server, port-forwarding if needed. It @@ -45,9 +45,9 @@ func (e *Env) AteClient(ctx context.Context) (*ateclient.Client, error) { // EnsureAtespace creates the atespace if it does not already exist. The store // enforces that an ActorTemplate's atespace exists at create time. func EnsureAtespace(ctx context.Context, client *ateclient.Client, atespace string) error { - _, err := client.CreateAtespace(ctx, &ateapipb.CreateAtespaceRequest{ - Atespace: &ateapipb.Atespace{ - Metadata: &ateapipb.ResourceMetadata{Name: atespace}, + _, err := client.CreateAtespace(ctx, &ateapi.CreateAtespaceRequest{ + Atespace: &ateapi.Atespace{ + Metadata: &ateapi.ResourceMetadata{Name: atespace}, }, }) if status.Code(err) == codes.AlreadyExists { @@ -60,7 +60,7 @@ func EnsureAtespace(ctx context.Context, client *ateclient.Client, atespace stri // document into an ActorTemplate, as `kubectl ate create actor-template` // does. Parsing is strict: unknown fields are an error, so typos don't // silently drop configuration. -func ActorTemplateFromManifest(manifest []byte) (*ateapipb.ActorTemplate, error) { +func ActorTemplateFromManifest(manifest []byte) (*ateapi.ActorTemplate, error) { jsonData, err := yaml.YAMLToJSON(manifest) if err != nil { return nil, fmt.Errorf("invalid YAML: %w", err) @@ -68,7 +68,7 @@ func ActorTemplateFromManifest(manifest []byte) (*ateapipb.ActorTemplate, error) if string(jsonData) == "null" { return nil, fmt.Errorf("manifest is empty") } - template := &ateapipb.ActorTemplate{} + template := &ateapi.ActorTemplate{} if err := protojson.Unmarshal(jsonData, template); err != nil { return nil, err } @@ -78,9 +78,9 @@ func ActorTemplateFromManifest(manifest []byte) (*ateapipb.ActorTemplate, error) // CreateActorTemplate creates the template through the ate API. Actor // templates are immutable (no update RPC), so an existing template is left // in place: delete the demo and redeploy to change it. -func CreateActorTemplate(ctx context.Context, client *ateclient.Client, template *ateapipb.ActorTemplate) error { +func CreateActorTemplate(ctx context.Context, client *ateclient.Client, template *ateapi.ActorTemplate) error { ref := resources.ActorTemplateRefFromActorTemplate(template) - _, err := client.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ActorTemplate: template}) + _, err := client.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ActorTemplate: template}) if status.Code(err) == codes.AlreadyExists { log.Stepf("actor template %s already exists; keeping it (delete the demo to replace it)", ref) return nil @@ -101,10 +101,10 @@ func WaitActorTemplateGolden(ctx context.Context, client *ateclient.Client, ref // template reconciler. var lastErr error for { - template, err := client.GetActorTemplate(ctx, &ateapipb.GetActorTemplateRequest{ActorTemplate: ref.ToObjectRef()}) + template, err := client.GetActorTemplate(ctx, &ateapi.GetActorTemplateRequest{ActorTemplate: ref.ToObjectRef()}) lastErr = err if err == nil { - if template.GetSnapshotConfig().GetGoldenSnapshotConfig().GetMode() == ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED { + if template.GetSnapshotConfig().GetGoldenSnapshotConfig().GetMode() == ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED { // The template opted out: no golden snapshot will ever appear, // and none is needed. return nil @@ -167,7 +167,7 @@ func (e *Env) DeleteSubstrateDemo(ctx context.Context, refs []resources.ActorTem } actorRef := resources.ActorRefFromActor(actor) log.Stepf(" deleting actor %s/%s", actorRef.Atespace, actorRef.Name) - if _, err := client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ + if _, err := client.DeleteActor(ctx, &ateapi.DeleteActorRequest{ Actor: actorRef.ToObjectRef(), }); err != nil { log.Warnf("while deleting actor %s/%s: %v", actorRef.Atespace, actorRef.Name, err) @@ -176,13 +176,13 @@ func (e *Env) DeleteSubstrateDemo(ctx context.Context, refs []resources.ActorTem } for _, ref := range refs { - if _, err := client.DeleteActorTemplate(ctx, &ateapipb.DeleteActorTemplateRequest{ActorTemplate: ref.ToObjectRef()}); err != nil && status.Code(err) != codes.NotFound { + if _, err := client.DeleteActorTemplate(ctx, &ateapi.DeleteActorTemplateRequest{ActorTemplate: ref.ToObjectRef()}); err != nil && status.Code(err) != codes.NotFound { log.Warnf("while deleting actor template %s: %v", ref, err) } } for _, atespace := range atespaces { - if _, err := client.DeleteAtespace(ctx, &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: atespace}}); err != nil && status.Code(err) != codes.NotFound { + if _, err := client.DeleteAtespace(ctx, &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: atespace}}); err != nil && status.Code(err) != codes.NotFound { log.Warnf("while deleting atespace %s: %v", atespace, err) } } diff --git a/cmd/ate-setup/internal/steps/substrate_test.go b/cmd/ate-setup/internal/steps/substrate_test.go index 8feaaba3ea..d29c0ec174 100644 --- a/cmd/ate-setup/internal/steps/substrate_test.go +++ b/cmd/ate-setup/internal/steps/substrate_test.go @@ -24,10 +24,10 @@ import ( "google.golang.org/grpc" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ate-setup/internal/config" "go.ate.dev/substrate/internal/ateclient" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // TestActorTemplateFromManifestDemos parses the protojson ActorTemplate @@ -152,11 +152,11 @@ func TestActorTemplateFromManifestErrors(t *testing.T) { // failingControlClient fails every GetActorTemplate with a fixed error. type failingControlClient struct { - ateapipb.ControlClient + ateapi.ControlClient err error } -func (f failingControlClient) GetActorTemplate(ctx context.Context, in *ateapipb.GetActorTemplateRequest, opts ...grpc.CallOption) (*ateapipb.ActorTemplate, error) { +func (f failingControlClient) GetActorTemplate(ctx context.Context, in *ateapi.GetActorTemplateRequest, opts ...grpc.CallOption) (*ateapi.ActorTemplate, error) { return nil, f.err } @@ -179,13 +179,13 @@ func TestWaitActorTemplateGoldenTimeoutIncludesLastError(t *testing.T) { // disabledTemplateClient serves one ActorTemplate that opted out of the // golden snapshot and has no golden status. type disabledTemplateClient struct { - ateapipb.ControlClient + ateapi.ControlClient } -func (disabledTemplateClient) GetActorTemplate(_ context.Context, in *ateapipb.GetActorTemplateRequest, _ ...grpc.CallOption) (*ateapipb.ActorTemplate, error) { - return &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: in.GetActorTemplate().GetAtespace(), Name: in.GetActorTemplate().GetName()}, - SnapshotConfig: &ateapipb.SnapshotConfig{GoldenSnapshotConfig: &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED}}, +func (disabledTemplateClient) GetActorTemplate(_ context.Context, in *ateapi.GetActorTemplateRequest, _ ...grpc.CallOption) (*ateapi.ActorTemplate, error) { + return &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: in.GetActorTemplate().GetAtespace(), Name: in.GetActorTemplate().GetName()}, + SnapshotConfig: &ateapi.SnapshotConfig{GoldenSnapshotConfig: &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED}}, }, nil } diff --git a/cmd/ate-setup/internal/steps/systemnetworkpolicy_test.go b/cmd/ate-setup/internal/steps/systemnetworkpolicy_test.go index 807a6e3f2c..4eca40bbcc 100644 --- a/cmd/ate-setup/internal/steps/systemnetworkpolicy_test.go +++ b/cmd/ate-setup/internal/steps/systemnetworkpolicy_test.go @@ -62,7 +62,7 @@ var unadmittedPorts = map[string][]string{ // The provider ships its own policy admitting only the egress gateway's // gRPC, and docs/egress-credential-injection.md promises nothing else // gets in; its probes come from the node. - "k8s-credential-provider": {"statusz", "metrics", "health"}, + "k8s-credential-provider": {"metrics", "health"}, // kind only: the rustfs web console. "rustfs": {"console"}, } diff --git a/cmd/ateapi/internal/apivalidation/AGENTS.md b/cmd/ateapi/internal/apivalidation/AGENTS.md index 18208904ce..a03595f645 100644 --- a/cmd/ateapi/internal/apivalidation/AGENTS.md +++ b/cmd/ateapi/internal/apivalidation/AGENTS.md @@ -3,7 +3,7 @@ See `docs/api-validation.md` for how declarative validation (DV) works in Substrate, its limitations, and best practices. - `zz_generated.validation.go` is generated by `hack/update/codegen.sh`. Never edit it by hand. -- Every `ateapipb` message whose name ends in `Request` gets generated validation from its DV tags. +- Every `ateapi` message whose name ends in `Request` gets generated validation from its DV tags. - Validation code only: generated DV code, custom validators, and thin exported shims that callers such as RPC handlers use. - One file per resource. Shared validation and messages go in `common.go`. - Tests cover exported functions only, with one table-driven test per exported function that covers all of its cases. diff --git a/cmd/ateapi/internal/apivalidation/access_policy.go b/cmd/ateapi/internal/apivalidation/access_policy.go index 430e06f961..401d3f94b4 100644 --- a/cmd/ateapi/internal/apivalidation/access_policy.go +++ b/cmd/ateapi/internal/apivalidation/access_policy.go @@ -18,8 +18,8 @@ import ( "context" "slices" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/authz" - "go.ate.dev/substrate/pkg/proto/ateapipb" "k8s.io/apimachinery/pkg/api/operation" "k8s.io/apimachinery/pkg/util/validation/field" ) @@ -34,18 +34,18 @@ var ( bindingsPath = field.NewPath("access_policy", "bindings") ) -func ValidateCreateGlobalAccessPolicyRequest(ctx context.Context, req *ateapipb.CreateGlobalAccessPolicyRequest) field.ErrorList { +func ValidateCreateGlobalAccessPolicyRequest(ctx context.Context, req *ateapi.CreateGlobalAccessPolicyRequest) field.ErrorList { op := MakeCreateOp(ctx) errs := Validate_CreateGlobalAccessPolicyRequest(ctx, op, nil, req, nil) return append(errs, validateBindings(bindingsPath, req.GetAccessPolicy(), validGlobalRoles)...) } -func ValidateGetGlobalAccessPolicyRequest(ctx context.Context, req *ateapipb.GetGlobalAccessPolicyRequest) field.ErrorList { +func ValidateGetGlobalAccessPolicyRequest(ctx context.Context, req *ateapi.GetGlobalAccessPolicyRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_GetGlobalAccessPolicyRequest(ctx, op, nil, req, nil) } -func ValidateUpdateGlobalAccessPolicyRequest(ctx context.Context, req *ateapipb.UpdateGlobalAccessPolicyRequest) field.ErrorList { +func ValidateUpdateGlobalAccessPolicyRequest(ctx context.Context, req *ateapi.UpdateGlobalAccessPolicyRequest) field.ErrorList { // Modeled as a create: this validates the request itself. The result is // validated against the stored value by ValidateGlobalAccessPolicyUpdate. op := MakeCreateOp(ctx) @@ -55,24 +55,24 @@ func ValidateUpdateGlobalAccessPolicyRequest(ctx context.Context, req *ateapipb. // ValidateGlobalAccessPolicyUpdate validates an updated global policy against // the stored one. -func ValidateGlobalAccessPolicyUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapipb.AccessPolicy) field.ErrorList { +func ValidateGlobalAccessPolicyUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapi.AccessPolicy) field.ErrorList { op := MakeUpdateOp(ctx) errs := Validate_AccessPolicy(ctx, op, fldPath, newVal, oldVal) return append(errs, validateBindings(fldPath.Child("bindings"), newVal, validGlobalRoles)...) } -func ValidateCreateAtespaceAccessPolicyRequest(ctx context.Context, req *ateapipb.CreateAtespaceAccessPolicyRequest) field.ErrorList { +func ValidateCreateAtespaceAccessPolicyRequest(ctx context.Context, req *ateapi.CreateAtespaceAccessPolicyRequest) field.ErrorList { op := MakeCreateOp(ctx) errs := Validate_CreateAtespaceAccessPolicyRequest(ctx, op, nil, req, nil) return append(errs, validateBindings(bindingsPath, req.GetAccessPolicy(), validAtespaceRoles)...) } -func ValidateGetAtespaceAccessPolicyRequest(ctx context.Context, req *ateapipb.GetAtespaceAccessPolicyRequest) field.ErrorList { +func ValidateGetAtespaceAccessPolicyRequest(ctx context.Context, req *ateapi.GetAtespaceAccessPolicyRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_GetAtespaceAccessPolicyRequest(ctx, op, nil, req, nil) } -func ValidateUpdateAtespaceAccessPolicyRequest(ctx context.Context, req *ateapipb.UpdateAtespaceAccessPolicyRequest) field.ErrorList { +func ValidateUpdateAtespaceAccessPolicyRequest(ctx context.Context, req *ateapi.UpdateAtespaceAccessPolicyRequest) field.ErrorList { // Modeled as a create: this validates the request itself. The result is // validated against the stored value by ValidateAtespaceAccessPolicyUpdate. op := MakeCreateOp(ctx) @@ -82,20 +82,20 @@ func ValidateUpdateAtespaceAccessPolicyRequest(ctx context.Context, req *ateapip // ValidateAtespaceAccessPolicyUpdate validates an updated atespace policy // against the stored one. -func ValidateAtespaceAccessPolicyUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapipb.AccessPolicy) field.ErrorList { +func ValidateAtespaceAccessPolicyUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapi.AccessPolicy) field.ErrorList { op := MakeUpdateOp(ctx) errs := Validate_AccessPolicy(ctx, op, fldPath, newVal, oldVal) return append(errs, validateBindings(fldPath.Child("bindings"), newVal, validAtespaceRoles)...) } -func ValidateDeleteAtespaceAccessPolicyRequest(ctx context.Context, req *ateapipb.DeleteAtespaceAccessPolicyRequest) field.ErrorList { +func ValidateDeleteAtespaceAccessPolicyRequest(ctx context.Context, req *ateapi.DeleteAtespaceAccessPolicyRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_DeleteAtespaceAccessPolicyRequest(ctx, op, nil, req, nil) } // ValidateCustom_AccessPolicy_Metadata requires an access policy to be the // unatespaced singleton named "default". -func ValidateCustom_AccessPolicy_Metadata(_ context.Context, _ operation.Operation, root *field.Path, meta, _ *ateapipb.ResourceMetadata) field.ErrorList { +func ValidateCustom_AccessPolicy_Metadata(_ context.Context, _ operation.Operation, root *field.Path, meta, _ *ateapi.ResourceMetadata) field.ErrorList { var errs field.ErrorList if meta.GetAtespace() != "" { errs = append(errs, field.Forbidden(root.Child("atespace"), "must not be set")) @@ -118,7 +118,7 @@ func ValidateCustom_DeleteAtespaceAccessPolicyRequest_Name(_ context.Context, _ // validateBindings checks that each binding names an allowed role at most once, // that every member is a valid OpenFGA user, and that the policy stays within // maxMembersPerPolicy. -func validateBindings(fldPath *field.Path, policy *ateapipb.AccessPolicy, allowedRoles []string) field.ErrorList { +func validateBindings(fldPath *field.Path, policy *ateapi.AccessPolicy, allowedRoles []string) field.ErrorList { if policy == nil { return nil } diff --git a/cmd/ateapi/internal/apivalidation/access_policy_test.go b/cmd/ateapi/internal/apivalidation/access_policy_test.go index 0190a2aa3f..2c7d0cec71 100644 --- a/cmd/ateapi/internal/apivalidation/access_policy_test.go +++ b/cmd/ateapi/internal/apivalidation/access_policy_test.go @@ -19,9 +19,9 @@ import ( "fmt" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/authz" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "k8s.io/apimachinery/pkg/util/validation/field" ) @@ -30,10 +30,10 @@ var ( policyBindings = accessPolicyPath.Child("bindings") ) -func validAccessPolicy(mutate ...func(*ateapipb.AccessPolicy)) *ateapipb.AccessPolicy { - p := &ateapipb.AccessPolicy{ - Metadata: &ateapipb.ResourceMetadata{Name: "default"}, - Bindings: []*ateapipb.Binding{ +func validAccessPolicy(mutate ...func(*ateapi.AccessPolicy)) *ateapi.AccessPolicy { + p := &ateapi.AccessPolicy{ + Metadata: &ateapi.ResourceMetadata{Name: "default"}, + Bindings: []*ateapi.Binding{ {Role: authz.RoleOwner, Members: []string{"user:alice@example.com"}}, {Role: authz.RoleViewer, Members: []string{"user:bob@example.com"}}, }, @@ -57,106 +57,106 @@ func TestValidateCreateGlobalAccessPolicyRequest(t *testing.T) { ctx := context.Background() tests := []struct { name string - req *ateapipb.CreateGlobalAccessPolicyRequest + req *ateapi.CreateGlobalAccessPolicyRequest wantError field.ErrorList }{{ name: "valid", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy()}, + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy()}, }, { name: "valid without bindings", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings = nil })}, }, { name: "missing access_policy", - req: &ateapipb.CreateGlobalAccessPolicyRequest{}, + req: &ateapi.CreateGlobalAccessPolicyRequest{}, wantError: field.ErrorList{field.Required(accessPolicyPath, "")}, }, { name: "missing metadata", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Metadata = nil })}, wantError: field.ErrorList{field.Required(accessPolicyPath.Child("metadata"), "")}, }, { // A nil entry is rejected as a whole; validateBindings skips it. name: "nil binding", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings = append(p.Bindings, nil) })}, wantError: field.ErrorList{field.Required(policyBindings.Index(2), "")}, }, { name: "atespace set", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Metadata.Atespace = "team-a" })}, wantError: field.ErrorList{field.Forbidden(accessPolicyPath.Child("metadata", "atespace"), "")}, }, { name: "missing name", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Metadata.Name = "" })}, wantError: field.ErrorList{field.Required(accessPolicyPath.Child("metadata", "name"), "")}, }, { name: "name not default", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Metadata.Name = "other" })}, wantError: field.ErrorList{field.Invalid(accessPolicyPath.Child("metadata", "name"), nil, "").WithOrigin("custom=default")}, }, { // editor is an atespace-only role. name: "editor role", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Role = authz.RoleEditor })}, wantError: field.ErrorList{field.NotSupported[string](policyBindings.Index(0).Child("role"), "", nil)}, }, { name: "unknown role", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[1].Role = "admin" })}, wantError: field.ErrorList{field.NotSupported[string](policyBindings.Index(1).Child("role"), "", nil)}, }, { // System component roles are granted only by ateapi's configuration. name: "system component role", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[1].Role = authz.RoleIngressRouter })}, wantError: field.ErrorList{field.NotSupported[string](policyBindings.Index(1).Child("role"), "", nil)}, }, { name: "duplicate role", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[1].Role = authz.RoleOwner })}, wantError: field.ErrorList{field.Duplicate(policyBindings.Index(1).Child("role"), nil)}, }, { name: "member without user prefix", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Members = []string{"alice@example.com"} })}, wantError: field.ErrorList{field.Invalid(policyBindings.Index(0).Child("members").Index(0), nil, "")}, }, { name: "member with a control character", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Members = []string{"user:alice\tbob"} })}, wantError: field.ErrorList{field.Invalid(policyBindings.Index(0).Child("members").Index(0), nil, "")}, }, { name: "wildcard member", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[1].Members = []string{"user:*"} })}, wantError: field.ErrorList{field.Invalid(policyBindings.Index(1).Child("members").Index(0), nil, "")}, }, { name: "members at the policy limit", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { - p.Bindings = []*ateapipb.Binding{{Role: authz.RoleViewer, Members: membersOfSize(maxMembersPerPolicy)}} + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { + p.Bindings = []*ateapi.Binding{{Role: authz.RoleViewer, Members: membersOfSize(maxMembersPerPolicy)}} })}, }, { // Each binding is within its own limit; together they exceed the // policy's. name: "members over the policy limit across bindings", - req: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { - p.Bindings = []*ateapipb.Binding{ + req: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { + p.Bindings = []*ateapi.Binding{ {Role: authz.RoleOwner, Members: membersOfSize(1)}, {Role: authz.RoleViewer, Members: membersOfSize(maxMembersPerPolicy)}, } @@ -174,18 +174,18 @@ func TestValidateGetGlobalAccessPolicyRequest(t *testing.T) { ctx := context.Background() tests := []struct { name string - req *ateapipb.GetGlobalAccessPolicyRequest + req *ateapi.GetGlobalAccessPolicyRequest wantError field.ErrorList }{{ name: "valid", - req: &ateapipb.GetGlobalAccessPolicyRequest{Name: resources.SingletonName}, + req: &ateapi.GetGlobalAccessPolicyRequest{Name: resources.SingletonName}, }, { name: "missing name", - req: &ateapipb.GetGlobalAccessPolicyRequest{}, + req: &ateapi.GetGlobalAccessPolicyRequest{}, wantError: field.ErrorList{field.Required(field.NewPath("name"), "")}, }, { name: "wrong name", - req: &ateapipb.GetGlobalAccessPolicyRequest{Name: "other"}, + req: &ateapi.GetGlobalAccessPolicyRequest{Name: "other"}, wantError: field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("custom=default")}, }} for _, tt := range tests { @@ -199,18 +199,18 @@ func TestValidateUpdateGlobalAccessPolicyRequest(t *testing.T) { ctx := context.Background() tests := []struct { name string - req *ateapipb.UpdateGlobalAccessPolicyRequest + req *ateapi.UpdateGlobalAccessPolicyRequest wantError field.ErrorList }{{ name: "valid", - req: &ateapipb.UpdateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy()}, + req: &ateapi.UpdateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy()}, }, { name: "missing access_policy", - req: &ateapipb.UpdateGlobalAccessPolicyRequest{}, + req: &ateapi.UpdateGlobalAccessPolicyRequest{}, wantError: field.ErrorList{field.Required(accessPolicyPath, "")}, }, { name: "editor role", - req: &ateapipb.UpdateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.UpdateGlobalAccessPolicyRequest{AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Role = authz.RoleEditor })}, wantError: field.ErrorList{field.NotSupported[string](policyBindings.Index(0).Child("role"), "", nil)}, @@ -226,20 +226,20 @@ func TestValidateGlobalAccessPolicyUpdate(t *testing.T) { ctx := context.Background() tests := []struct { name string - newVal *ateapipb.AccessPolicy + newVal *ateapi.AccessPolicy wantError field.ErrorList }{{ name: "valid", newVal: validAccessPolicy(), }, { name: "editor role", - newVal: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + newVal: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Role = authz.RoleEditor }), wantError: field.ErrorList{field.NotSupported[string](policyBindings.Index(0).Child("role"), "", nil)}, }, { name: "invalid member", - newVal: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + newVal: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[1].Members = []string{"user:"} }), wantError: field.ErrorList{field.Invalid(policyBindings.Index(1).Child("members").Index(0), nil, "")}, @@ -253,54 +253,54 @@ func TestValidateGlobalAccessPolicyUpdate(t *testing.T) { func TestValidateCreateAtespaceAccessPolicyRequest(t *testing.T) { ctx := context.Background() - atespace := &ateapipb.ObjectRef{Name: "team-a"} + atespace := &ateapi.ObjectRef{Name: "team-a"} tests := []struct { name string - req *ateapipb.CreateAtespaceAccessPolicyRequest + req *ateapi.CreateAtespaceAccessPolicyRequest wantError field.ErrorList }{{ name: "valid", - req: &ateapipb.CreateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy()}, + req: &ateapi.CreateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy()}, }, { name: "valid with editor role", - req: &ateapipb.CreateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[1].Role = authz.RoleEditor })}, }, { name: "missing atespace", - req: &ateapipb.CreateAtespaceAccessPolicyRequest{AccessPolicy: validAccessPolicy()}, + req: &ateapi.CreateAtespaceAccessPolicyRequest{AccessPolicy: validAccessPolicy()}, wantError: field.ErrorList{field.Required(field.NewPath("atespace"), "")}, }, { name: "missing access_policy", - req: &ateapipb.CreateAtespaceAccessPolicyRequest{Atespace: atespace}, + req: &ateapi.CreateAtespaceAccessPolicyRequest{Atespace: atespace}, wantError: field.ErrorList{field.Required(accessPolicyPath, "")}, }, { name: "missing name", - req: &ateapipb.CreateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Metadata.Name = "" })}, wantError: field.ErrorList{field.Required(accessPolicyPath.Child("metadata", "name"), "")}, }, { name: "name not default", - req: &ateapipb.CreateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Metadata.Name = "other" })}, wantError: field.ErrorList{field.Invalid(accessPolicyPath.Child("metadata", "name"), nil, "").WithOrigin("custom=default")}, }, { name: "unknown role", - req: &ateapipb.CreateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Role = "admin" })}, wantError: field.ErrorList{field.NotSupported[string](policyBindings.Index(0).Child("role"), "", nil)}, }, { name: "system component role", - req: &ateapipb.CreateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Role = authz.RoleEgressGateway })}, wantError: field.ErrorList{field.NotSupported[string](policyBindings.Index(0).Child("role"), "", nil)}, }, { name: "invalid member", - req: &ateapipb.CreateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.CreateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Members = []string{"group:eng"} })}, wantError: field.ErrorList{field.Invalid(policyBindings.Index(0).Child("members").Index(0), nil, "")}, @@ -316,22 +316,22 @@ func TestValidateGetAtespaceAccessPolicyRequest(t *testing.T) { ctx := context.Background() tests := []struct { name string - req *ateapipb.GetAtespaceAccessPolicyRequest + req *ateapi.GetAtespaceAccessPolicyRequest wantError field.ErrorList }{{ name: "valid", - req: &ateapipb.GetAtespaceAccessPolicyRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}, Name: resources.SingletonName}, + req: &ateapi.GetAtespaceAccessPolicyRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}, Name: resources.SingletonName}, }, { name: "missing atespace", - req: &ateapipb.GetAtespaceAccessPolicyRequest{Name: resources.SingletonName}, + req: &ateapi.GetAtespaceAccessPolicyRequest{Name: resources.SingletonName}, wantError: field.ErrorList{field.Required(field.NewPath("atespace"), "")}, }, { name: "missing name", - req: &ateapipb.GetAtespaceAccessPolicyRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}}, + req: &ateapi.GetAtespaceAccessPolicyRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}}, wantError: field.ErrorList{field.Required(field.NewPath("name"), "")}, }, { name: "wrong name", - req: &ateapipb.GetAtespaceAccessPolicyRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}, Name: "other"}, + req: &ateapi.GetAtespaceAccessPolicyRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}, Name: "other"}, wantError: field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("custom=default")}, }} for _, tt := range tests { @@ -343,21 +343,21 @@ func TestValidateGetAtespaceAccessPolicyRequest(t *testing.T) { func TestValidateUpdateAtespaceAccessPolicyRequest(t *testing.T) { ctx := context.Background() - atespace := &ateapipb.ObjectRef{Name: "team-a"} + atespace := &ateapi.ObjectRef{Name: "team-a"} tests := []struct { name string - req *ateapipb.UpdateAtespaceAccessPolicyRequest + req *ateapi.UpdateAtespaceAccessPolicyRequest wantError field.ErrorList }{{ name: "valid", - req: &ateapipb.UpdateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy()}, + req: &ateapi.UpdateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy()}, }, { name: "missing access_policy", - req: &ateapipb.UpdateAtespaceAccessPolicyRequest{Atespace: atespace}, + req: &ateapi.UpdateAtespaceAccessPolicyRequest{Atespace: atespace}, wantError: field.ErrorList{field.Required(accessPolicyPath, "")}, }, { name: "duplicate role", - req: &ateapipb.UpdateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + req: &ateapi.UpdateAtespaceAccessPolicyRequest{Atespace: atespace, AccessPolicy: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[1].Role = authz.RoleOwner })}, wantError: field.ErrorList{field.Duplicate(policyBindings.Index(1).Child("role"), nil)}, @@ -373,16 +373,16 @@ func TestValidateAtespaceAccessPolicyUpdate(t *testing.T) { ctx := context.Background() tests := []struct { name string - newVal *ateapipb.AccessPolicy + newVal *ateapi.AccessPolicy wantError field.ErrorList }{{ name: "valid with editor role", - newVal: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + newVal: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[1].Role = authz.RoleEditor }), }, { name: "unknown role", - newVal: validAccessPolicy(func(p *ateapipb.AccessPolicy) { + newVal: validAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Role = "admin" }), wantError: field.ErrorList{field.NotSupported[string](policyBindings.Index(0).Child("role"), "", nil)}, @@ -398,22 +398,22 @@ func TestValidateDeleteAtespaceAccessPolicyRequest(t *testing.T) { ctx := context.Background() tests := []struct { name string - req *ateapipb.DeleteAtespaceAccessPolicyRequest + req *ateapi.DeleteAtespaceAccessPolicyRequest wantError field.ErrorList }{{ name: "valid", - req: &ateapipb.DeleteAtespaceAccessPolicyRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}, Name: resources.SingletonName}, + req: &ateapi.DeleteAtespaceAccessPolicyRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}, Name: resources.SingletonName}, }, { name: "missing atespace", - req: &ateapipb.DeleteAtespaceAccessPolicyRequest{Name: resources.SingletonName}, + req: &ateapi.DeleteAtespaceAccessPolicyRequest{Name: resources.SingletonName}, wantError: field.ErrorList{field.Required(field.NewPath("atespace"), "")}, }, { name: "missing name", - req: &ateapipb.DeleteAtespaceAccessPolicyRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}}, + req: &ateapi.DeleteAtespaceAccessPolicyRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}}, wantError: field.ErrorList{field.Required(field.NewPath("name"), "")}, }, { name: "wrong name", - req: &ateapipb.DeleteAtespaceAccessPolicyRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}, Name: "other"}, + req: &ateapi.DeleteAtespaceAccessPolicyRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}, Name: "other"}, wantError: field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("custom=default")}, }} for _, tt := range tests { diff --git a/cmd/ateapi/internal/apivalidation/actor.go b/cmd/ateapi/internal/apivalidation/actor.go index b690c6c0c4..138e4f5e4a 100644 --- a/cmd/ateapi/internal/apivalidation/actor.go +++ b/cmd/ateapi/internal/apivalidation/actor.go @@ -17,32 +17,32 @@ package apivalidation import ( "context" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "k8s.io/apimachinery/pkg/api/operation" "k8s.io/apimachinery/pkg/api/validate" "k8s.io/apimachinery/pkg/util/validation/field" ) -func ValidateCreateActorRequest(ctx context.Context, req *ateapipb.CreateActorRequest) field.ErrorList { +func ValidateCreateActorRequest(ctx context.Context, req *ateapi.CreateActorRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_CreateActorRequest(ctx, op, nil, req, nil) } -func ValidateGetActorRequest(ctx context.Context, req *ateapipb.GetActorRequest) field.ErrorList { +func ValidateGetActorRequest(ctx context.Context, req *ateapi.GetActorRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_GetActorRequest(ctx, op, nil, req, nil) } -func ValidateListActorsRequest(ctx context.Context, req *ateapipb.ListActorsRequest) field.ErrorList { +func ValidateListActorsRequest(ctx context.Context, req *ateapi.ListActorsRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_ListActorsRequest(ctx, op, nil, req, nil) } -func ValidateUpdateActorRequest(ctx context.Context, req *ateapipb.UpdateActorRequest) field.ErrorList { +func ValidateUpdateActorRequest(ctx context.Context, req *ateapi.UpdateActorRequest) field.ErrorList { // Call the generated validation. // We model this as a create rather than an update because updates assume // the existence of a "current" value, which we do not have yet. This is @@ -52,53 +52,53 @@ func ValidateUpdateActorRequest(ctx context.Context, req *ateapipb.UpdateActorRe return Validate_UpdateActorRequest(ctx, op, nil, req, nil) } -func ValidateDeleteActorRequest(ctx context.Context, req *ateapipb.DeleteActorRequest) field.ErrorList { +func ValidateDeleteActorRequest(ctx context.Context, req *ateapi.DeleteActorRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_DeleteActorRequest(ctx, op, nil, req, nil) } -func ValidateResumeActorRequest(ctx context.Context, req *ateapipb.ResumeActorRequest) field.ErrorList { +func ValidateResumeActorRequest(ctx context.Context, req *ateapi.ResumeActorRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_ResumeActorRequest(ctx, op, nil, req, nil) } -func ValidateSuspendActorRequest(ctx context.Context, req *ateapipb.SuspendActorRequest) field.ErrorList { +func ValidateSuspendActorRequest(ctx context.Context, req *ateapi.SuspendActorRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_SuspendActorRequest(ctx, op, nil, req, nil) } -func ValidateRevertActorRequest(ctx context.Context, req *ateapipb.RevertActorRequest) field.ErrorList { +func ValidateRevertActorRequest(ctx context.Context, req *ateapi.RevertActorRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_RevertActorRequest(ctx, op, nil, req, nil) } -func ValidateMintActorJWTRequest(ctx context.Context, req *ateapipb.MintActorJwtRequest) field.ErrorList { +func ValidateMintActorJWTRequest(ctx context.Context, req *ateapi.MintActorJwtRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_MintActorJwtRequest(ctx, op, nil, req, nil) } -func ValidateMintActorCertificateRequest(ctx context.Context, req *ateapipb.MintActorCertificateRequest) field.ErrorList { +func ValidateMintActorCertificateRequest(ctx context.Context, req *ateapi.MintActorCertificateRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_MintActorCertificateRequest(ctx, op, nil, req, nil) } -func ValidateMintWorkerActorCertificateRequest(ctx context.Context, req *ateapipb.MintWorkerActorCertificateRequest) field.ErrorList { +func ValidateMintWorkerActorCertificateRequest(ctx context.Context, req *ateapi.MintWorkerActorCertificateRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_MintWorkerActorCertificateRequest(ctx, op, nil, req, nil) } -func ValidateMintWorkerActorJwtRequest(ctx context.Context, req *ateapipb.MintWorkerActorJwtRequest) field.ErrorList { +func ValidateMintWorkerActorJwtRequest(ctx context.Context, req *ateapi.MintWorkerActorJwtRequest) field.ErrorList { op := operation.Operation{Type: operation.Create} return Validate_MintWorkerActorJwtRequest(ctx, op, nil, req, nil) } -func ValidateActorUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapipb.Actor, requireStatus bool) field.ErrorList { +func ValidateActorUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapi.Actor, requireStatus bool) field.ErrorList { // Call the generated validation. op := MakeUpdateOp(ctx) errs := Validate_Actor(ctx, op, fldPath, newVal, oldVal) @@ -112,7 +112,7 @@ func ValidateActorUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVa } // This exists only because nested subfield tags are not supported yet. -func ValidateCustom_UpdateActorRequest_Actor(ctx context.Context, op operation.Operation, fldPath *field.Path, actor, _ *ateapipb.Actor) field.ErrorList { +func ValidateCustom_UpdateActorRequest_Actor(ctx context.Context, op operation.Operation, fldPath *field.Path, actor, _ *ateapi.Actor) field.ErrorList { if actor == nil || actor.Metadata == nil { return nil // handled by DV } diff --git a/cmd/ateapi/internal/apivalidation/actor_template.go b/cmd/ateapi/internal/apivalidation/actor_template.go index 3e21dca0c1..cad1b5aa34 100644 --- a/cmd/ateapi/internal/apivalidation/actor_template.go +++ b/cmd/ateapi/internal/apivalidation/actor_template.go @@ -18,39 +18,39 @@ import ( "context" "fmt" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "k8s.io/apimachinery/pkg/api/operation" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" ) -func ValidateCreateActorTemplateRequest(ctx context.Context, req *ateapipb.CreateActorTemplateRequest) field.ErrorList { +func ValidateCreateActorTemplateRequest(ctx context.Context, req *ateapi.CreateActorTemplateRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_CreateActorTemplateRequest(ctx, op, nil, req, nil) } -func ValidateGetActorTemplateRequest(ctx context.Context, req *ateapipb.GetActorTemplateRequest) field.ErrorList { +func ValidateGetActorTemplateRequest(ctx context.Context, req *ateapi.GetActorTemplateRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_GetActorTemplateRequest(ctx, op, nil, req, nil) } -func ValidateListActorTemplatesRequest(ctx context.Context, req *ateapipb.ListActorTemplatesRequest) field.ErrorList { +func ValidateListActorTemplatesRequest(ctx context.Context, req *ateapi.ListActorTemplatesRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_ListActorTemplatesRequest(ctx, op, nil, req, nil) } -func ValidateDeleteActorTemplateRequest(ctx context.Context, req *ateapipb.DeleteActorTemplateRequest) field.ErrorList { +func ValidateDeleteActorTemplateRequest(ctx context.Context, req *ateapi.DeleteActorTemplateRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_DeleteActorTemplateRequest(ctx, op, nil, req, nil) } -func ValidateActorTemplateUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapipb.ActorTemplate) field.ErrorList { +func ValidateActorTemplateUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapi.ActorTemplate) field.ErrorList { // Call the generated validation. op := MakeUpdateOp(ctx) return Validate_ActorTemplate(ctx, op, fldPath, newVal, oldVal) @@ -58,9 +58,9 @@ func ValidateActorTemplateUpdate(ctx context.Context, fldPath *field.Path, newVa // ValidateCustom_CreateActorTemplateRequest_ActorTemplate holds the rules // that span more than one field of a template. -func ValidateCustom_CreateActorTemplateRequest_ActorTemplate(_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *ateapipb.ActorTemplate) field.ErrorList { +func ValidateCustom_CreateActorTemplateRequest_ActorTemplate(_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *ateapi.ActorTemplate) field.ErrorList { var errs field.ErrorList - if value.GetGoldenEgressPolicy() != nil && value.GetSnapshotConfig().GetGoldenSnapshotConfig().GetMode() == ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED { + if value.GetGoldenEgressPolicy() != nil && value.GetSnapshotConfig().GetGoldenSnapshotConfig().GetMode() == ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED { errs = append(errs, field.Forbidden(fldPath.Child("golden_egress_policy"), "requires golden snapshots to be enabled")) } declared := make(map[string]bool, len(value.GetVolumes())) @@ -85,7 +85,7 @@ func ValidateCustom_CreateActorTemplateRequest_ActorTemplate(_ context.Context, // ValidateCustom_ActorTemplate_Resources requires both a cpu and a memory // limit, which the scheduler books against worker capacity. -func ValidateCustom_ActorTemplate_Resources(_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *ateapipb.ResourceRequirements) field.ErrorList { +func ValidateCustom_ActorTemplate_Resources(_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *ateapi.ResourceRequirements) field.ErrorList { var errs field.ErrorList if value.GetLimits().GetCpuMillicores() == 0 { errs = append(errs, field.Required(fldPath.Child("limits", "cpu_millicores"), "")) @@ -106,7 +106,7 @@ func ValidateCustom_VolumeMount_MountPath(_ context.Context, _ operation.Operati // ValidateCustom_Container_VolumeMounts rejects mounts that nest under one // another. Mount-path uniqueness is enforced by the list key. -func ValidateCustom_Container_VolumeMounts(_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ []*ateapipb.VolumeMount) field.ErrorList { +func ValidateCustom_Container_VolumeMounts(_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ []*ateapi.VolumeMount) field.ErrorList { paths := make([]string, len(value)) for i, m := range value { paths[i] = m.GetMountPath() @@ -126,7 +126,7 @@ func ValidateCustom_TrustBundleDataSource_Path(_ context.Context, _ operation.Op // actor_metadata entry and requires every projected file path to be unique // across all data sources: atelet writes them in order into one tree, so a // repeated path silently clobbers the earlier file. -func ValidateCustom_SystemInfoVolumeSource_DataSources(_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ []*ateapipb.SystemInfoDataSource) field.ErrorList { +func ValidateCustom_SystemInfoVolumeSource_DataSources(_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ []*ateapi.SystemInfoDataSource) field.ErrorList { var errs field.ErrorList seen := sets.New[string]() sawMetadata := false diff --git a/cmd/ateapi/internal/apivalidation/actor_template_test.go b/cmd/ateapi/internal/apivalidation/actor_template_test.go index f5417f84e6..a2d8de5e56 100644 --- a/cmd/ateapi/internal/apivalidation/actor_template_test.go +++ b/cmd/ateapi/internal/apivalidation/actor_template_test.go @@ -20,167 +20,167 @@ import ( "strings" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "k8s.io/apimachinery/pkg/util/validation/field" ) func TestValidateCreateActorTemplateRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.CreateActorTemplateRequest + req *ateapi.CreateActorTemplateRequest want field.ErrorList }{{ "valid", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate()}, + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate()}, nil, }, { "valid golden egress rules", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{{Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{80}}}}}} + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.GoldenEgressPolicy = &ateapi.EgressPolicyTemplate{Rules: []*ateapi.EgressRule{{Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{80}}}}}} })}, nil, }, { "missing golden egress rules", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{} + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.GoldenEgressPolicy = &ateapi.EgressPolicyTemplate{} })}, field.ErrorList{field.Required(field.NewPath("actor_template", "golden_egress_policy", "rules"), "")}, }, { "empty golden egress rules", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{}} + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.GoldenEgressPolicy = &ateapi.EgressPolicyTemplate{Rules: []*ateapi.EgressRule{}} })}, field.ErrorList{field.Required(field.NewPath("actor_template", "golden_egress_policy", "rules"), "")}, }, { "invalid golden egress hostname", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{{Http: &ateapipb.HttpRule{Hostnames: []string{"bad/host"}, Ports: &ateapipb.Ports{Numbers: []int32{80}}}}}} + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.GoldenEgressPolicy = &ateapi.EgressPolicyTemplate{Rules: []*ateapi.EgressRule{{Http: &ateapi.HttpRule{Hostnames: []string{"bad/host"}, Ports: &ateapi.Ports{Numbers: []int32{80}}}}}} })}, field.ErrorList{field.Invalid(field.NewPath("actor_template", "golden_egress_policy", "rules").Index(0).Child("http", "hostnames").Index(0), nil, "")}, }, { "golden egress rules tie across protocols", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{ - {Https: &ateapipb.HttpsRule{Hostnames: []string{"api.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{443}}}}, - {TlsPassthrough: &ateapipb.TlsPassthroughRule{Hostnames: []string{"api.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{443}}}}, + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.GoldenEgressPolicy = &ateapi.EgressPolicyTemplate{Rules: []*ateapi.EgressRule{ + {Https: &ateapi.HttpsRule{Hostnames: []string{"api.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{443}}}}, + {TlsPassthrough: &ateapi.TlsPassthroughRule{Hostnames: []string{"api.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{443}}}}, }} })}, field.ErrorList{field.Invalid(field.NewPath("actor_template", "golden_egress_policy", "rules").Index(1).Child("tls_passthrough", "hostnames").Index(0), nil, "")}, }, { "too many golden egress rules", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{} + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.GoldenEgressPolicy = &ateapi.EgressPolicyTemplate{} for i := range 257 { - tmpl.GoldenEgressPolicy.Rules = append(tmpl.GoldenEgressPolicy.Rules, &ateapipb.EgressRule{Http: &ateapipb.HttpRule{Hostnames: []string{fmt.Sprintf("host-%d.example.com", i)}, Ports: &ateapipb.Ports{Numbers: []int32{80}}}}) + tmpl.GoldenEgressPolicy.Rules = append(tmpl.GoldenEgressPolicy.Rules, &ateapi.EgressRule{Http: &ateapi.HttpRule{Hostnames: []string{fmt.Sprintf("host-%d.example.com", i)}, Ports: &ateapi.Ports{Numbers: []int32{80}}}}) } })}, field.ErrorList{field.TooMany(field.NewPath("actor_template", "golden_egress_policy", "rules"), 257, 256).WithOrigin("maxItems")}, }, { "missing actor_template", - &ateapipb.CreateActorTemplateRequest{}, + &ateapi.CreateActorTemplateRequest{}, field.ErrorList{field.Required(field.NewPath("actor_template"), "")}, }, { "missing metadata.atespace", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.Metadata.Atespace = "" })}, field.ErrorList{field.Required(field.NewPath("actor_template", "metadata", "atespace"), "")}, }, { "invalid metadata.atespace", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.Metadata.Atespace = "NS_1" })}, field.ErrorList{field.Invalid(field.NewPath("actor_template", "metadata", "atespace"), "NS_1", "").WithOrigin("format=k8s-short-name")}, }, { "missing metadata.name", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.Metadata.Name = "" })}, field.ErrorList{field.Required(field.NewPath("actor_template", "metadata", "name"), "")}, }, { "invalid metadata.name", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.Metadata.Name = "Tmpl_A" })}, field.ErrorList{field.Invalid(field.NewPath("actor_template", "metadata", "name"), "Tmpl_A", "").WithOrigin("format=k8s-short-name")}, }, { "valid volumes fidelity", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.SnapshotConfig.PreferredFidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.SnapshotConfig.PreferredFidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES })}, nil, }, { "valid rootfs fidelity", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.SnapshotConfig.PreferredFidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.SnapshotConfig.PreferredFidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS })}, nil, }, { "invalid worker_selector label key", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"bad key": "v"}} + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"bad key": "v"}} })}, field.ErrorList{field.Invalid(field.NewPath("actor_template", "worker_selector", "match_labels"), "bad key", "").WithOrigin("format=k8s-label-key")}, }, { "no containers", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.Containers = nil })}, field.ErrorList{field.Required(field.NewPath("actor_template", "containers"), "")}, }, { "container missing name", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.Containers[0].Name = "" })}, field.ErrorList{field.Required(field.NewPath("actor_template", "containers").Index(0).Child("name"), "")}, }, { "container invalid name", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.Containers[0].Name = "Main_1" })}, field.ErrorList{field.Invalid(field.NewPath("actor_template", "containers").Index(0).Child("name"), "Main_1", "").WithOrigin("format=k8s-short-name")}, }, { "container missing image", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.Containers[0].Image = "" })}, field.ErrorList{field.Required(field.NewPath("actor_template", "containers").Index(0).Child("image"), "")}, }, { "volume mount referencing a declared volume", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{Name: "data", DurableDir: &ateapipb.DurableDirVolumeSource{}}} - tmpl.Containers[0].VolumeMounts = []*ateapipb.VolumeMount{{Name: "data", MountPath: "/var/data"}} + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "data", DurableDir: &ateapi.DurableDirVolumeSource{}}} + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} })}, nil, }, { "volume mount referencing an undeclared volume", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].VolumeMounts = []*ateapipb.VolumeMount{{Name: "ghost-vol", MountPath: "/var/data"}} + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "ghost-vol", MountPath: "/var/data"}} })}, field.ErrorList{field.Invalid(field.NewPath("actor_template", "containers").Index(0).Child("volume_mounts").Index(0).Child("name"), "ghost-vol", "")}, }, { "missing snapshot_config is allowed", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.SnapshotConfig = nil })}, nil, }, { "snapshot_config.storage_location is not needed when the preview gate is off", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.SnapshotConfig.StorageLocation = "" })}, nil, }, { "storage_location without a bucket", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.SnapshotConfig.StorageLocation = "my-bucket/snapshots" })}, field.ErrorList{field.Invalid(field.NewPath("actor_template", "snapshot_config", "storage_location"), "my-bucket/snapshots", "")}, }, { "storage_location with a query", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.SnapshotConfig.StorageLocation = "gs://my-bucket/snapshots?versions=true" })}, field.ErrorList{field.Invalid(field.NewPath("actor_template", "snapshot_config", "storage_location"), "gs://my-bucket/snapshots?versions=true", "")}, @@ -188,34 +188,34 @@ func TestValidateCreateActorTemplateRequest(t *testing.T) { // preferred_fidelity has no default of its own at this layer, so leaving it // unset is a required violation. "preferred_fidelity unset", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.SnapshotConfig.PreferredFidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.SnapshotConfig.PreferredFidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED })}, field.ErrorList{ field.Required(field.NewPath("actor_template", "snapshot_config", "preferred_fidelity"), ""), }, }, { "missing resources", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.Resources = nil })}, field.ErrorList{field.Required(field.NewPath("actor_template", "resources"), "")}, }, { "missing cpu", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.Resources = &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(0, 512<<20)} + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.Resources = &ateapi.ResourceRequirements{Limits: resources.CPUMemory(0, 512<<20)} })}, field.ErrorList{field.Required(field.NewPath("actor_template", "resources", "limits", "cpu_millicores"), "")}, }, { "missing memory", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.Resources = &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 0)} + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.Resources = &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 0)} })}, field.ErrorList{field.Required(field.NewPath("actor_template", "resources", "limits", "memory_bytes"), "")}, }, { "empty resources", - &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.Resources = &ateapipb.ResourceRequirements{} + &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.Resources = &ateapi.ResourceRequirements{} })}, field.ErrorList{ field.Required(field.NewPath("actor_template", "resources", "limits", "cpu_millicores"), ""), @@ -239,8 +239,8 @@ func TestValidateCreateActorTemplateRequest(t *testing.T) { func TestValidateCreateActorTemplateRequest_PreviewRestricted(t *testing.T) { setPreviewForTest(t, "ALL") - req := &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{Name: "data", External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{CapacityBytes: 10 << 30, StorageClassName: "fast-ssd"}}}} + req := &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, StorageClassName: "fast-ssd"}}}} })} t.Run("allowed", func(t *testing.T) { @@ -258,12 +258,12 @@ func TestValidateCreateActorTemplateRequest_PreviewRestricted(t *testing.T) { func TestValidateCreateActorTemplateRequest_PerTemplateSnapshotLocationOptIn(t *testing.T) { storageLocation := field.NewPath("actor_template", "snapshot_config", "storage_location") - withoutLocation := func(tmpl *ateapipb.ActorTemplate) { tmpl.SnapshotConfig.StorageLocation = "" } + withoutLocation := func(tmpl *ateapi.ActorTemplate) { tmpl.SnapshotConfig.StorageLocation = "" } tests := []struct { name string gates string optOut bool - mutate func(*ateapipb.ActorTemplate) + mutate func(*ateapi.ActorTemplate) want field.ErrorList }{{ name: "gate off, opted out, location set", @@ -297,11 +297,11 @@ func TestValidateCreateActorTemplateRequest_PerTemplateSnapshotLocationOptIn(t * if tt.optOut { ctx = preview.ContextWithOptOut(ctx) } - var mutations []func(*ateapipb.ActorTemplate) + var mutations []func(*ateapi.ActorTemplate) if tt.mutate != nil { mutations = append(mutations, tt.mutate) } - req := &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(mutations...)} + req := &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(mutations...)} assertValidateErr(t, ValidateCreateActorTemplateRequest(ctx, req), tt.want) }) } @@ -310,23 +310,23 @@ func TestValidateCreateActorTemplateRequest_PerTemplateSnapshotLocationOptIn(t * func TestValidateGetActorTemplateRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.GetActorTemplateRequest + req *ateapi.GetActorTemplateRequest want field.ErrorList }{{ "valid", - &ateapipb.GetActorTemplateRequest{ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl-a"}}, + &ateapi.GetActorTemplateRequest{ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1", Name: "tmpl-a"}}, nil, }, { "missing actor_template", - &ateapipb.GetActorTemplateRequest{}, + &ateapi.GetActorTemplateRequest{}, field.ErrorList{field.Required(field.NewPath("actor_template"), "")}, }, { "missing atespace", - &ateapipb.GetActorTemplateRequest{ActorTemplate: &ateapipb.ObjectRef{Name: "tmpl-a"}}, + &ateapi.GetActorTemplateRequest{ActorTemplate: &ateapi.ObjectRef{Name: "tmpl-a"}}, field.ErrorList{field.Required(field.NewPath("actor_template", "atespace"), "")}, }, { "missing name", - &ateapipb.GetActorTemplateRequest{ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1"}}, + &ateapi.GetActorTemplateRequest{ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1"}}, field.ErrorList{field.Required(field.NewPath("actor_template", "name"), "")}, }} for _, tt := range tests { @@ -339,27 +339,27 @@ func TestValidateGetActorTemplateRequest(t *testing.T) { func TestValidateListActorTemplatesRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.ListActorTemplatesRequest + req *ateapi.ListActorTemplatesRequest want field.ErrorList }{{ "valid", - &ateapipb.ListActorTemplatesRequest{Options: &ateapipb.ListOptions{PageSize: 10}}, + &ateapi.ListActorTemplatesRequest{Options: &ateapi.ListOptions{PageSize: 10}}, nil, }, { "zero page size", - &ateapipb.ListActorTemplatesRequest{}, + &ateapi.ListActorTemplatesRequest{}, nil, }, { "valid atespace filter", - &ateapipb.ListActorTemplatesRequest{Atespace: "ns1"}, + &ateapi.ListActorTemplatesRequest{Atespace: "ns1"}, nil, }, { "invalid atespace filter", - &ateapipb.ListActorTemplatesRequest{Atespace: "NS_1"}, + &ateapi.ListActorTemplatesRequest{Atespace: "NS_1"}, field.ErrorList{field.Invalid(field.NewPath("atespace"), "NS_1", "").WithOrigin("format=k8s-short-name")}, }, { "negative page size", - &ateapipb.ListActorTemplatesRequest{Options: &ateapipb.ListOptions{PageSize: -1}}, + &ateapi.ListActorTemplatesRequest{Options: &ateapi.ListOptions{PageSize: -1}}, field.ErrorList{field.Invalid(field.NewPath("options", "page_size"), int32(-1), "").WithOrigin("minimum")}, }} for _, tt := range tests { @@ -372,23 +372,23 @@ func TestValidateListActorTemplatesRequest(t *testing.T) { func TestValidateDeleteActorTemplateRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.DeleteActorTemplateRequest + req *ateapi.DeleteActorTemplateRequest want field.ErrorList }{{ "valid", - &ateapipb.DeleteActorTemplateRequest{ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl-a"}}, + &ateapi.DeleteActorTemplateRequest{ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1", Name: "tmpl-a"}}, nil, }, { "missing actor_template", - &ateapipb.DeleteActorTemplateRequest{}, + &ateapi.DeleteActorTemplateRequest{}, field.ErrorList{field.Required(field.NewPath("actor_template"), "")}, }, { "missing atespace", - &ateapipb.DeleteActorTemplateRequest{ActorTemplate: &ateapipb.ObjectRef{Name: "tmpl-a"}}, + &ateapi.DeleteActorTemplateRequest{ActorTemplate: &ateapi.ObjectRef{Name: "tmpl-a"}}, field.ErrorList{field.Required(field.NewPath("actor_template", "atespace"), "")}, }, { "missing name", - &ateapipb.DeleteActorTemplateRequest{ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1"}}, + &ateapi.DeleteActorTemplateRequest{ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1"}}, field.ErrorList{field.Required(field.NewPath("actor_template", "name"), "")}, }} for _, tt := range tests { @@ -404,7 +404,7 @@ func TestValidateDeleteActorTemplateRequest(t *testing.T) { func TestValidateActorTemplate(t *testing.T) { tests := []struct { name string - mutate func(*ateapipb.ActorTemplate) // nil leaves the template valid + mutate func(*ateapi.ActorTemplate) // nil leaves the template valid // want is the result with no preview gates enabled. want field.ErrorList // wantWithPreview maps a --preview value to the result with those @@ -414,126 +414,126 @@ func TestValidateActorTemplate(t *testing.T) { name: "valid", }, { name: "golden snapshot enabled without wakeup probe", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.SnapshotConfig.GoldenSnapshotConfig = &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.SnapshotConfig.GoldenSnapshotConfig = &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED} }, }, { name: "golden snapshot disabled", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.SnapshotConfig.GoldenSnapshotConfig = &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.SnapshotConfig.GoldenSnapshotConfig = &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED} }, }, { name: "golden snapshot mode unspecified", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.SnapshotConfig.GoldenSnapshotConfig = &ateapipb.GoldenSnapshotConfig{} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.SnapshotConfig.GoldenSnapshotConfig = &ateapi.GoldenSnapshotConfig{} }, want: field.ErrorList{field.Required(field.NewPath("snapshot_config", "golden_snapshot_config", "mode"), "")}, }, { name: "golden snapshot mode negative", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.SnapshotConfig.GoldenSnapshotConfig = &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode(-1)} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.SnapshotConfig.GoldenSnapshotConfig = &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode(-1)} }, want: field.ErrorList{field.Invalid(field.NewPath("snapshot_config", "golden_snapshot_config", "mode"), nil, "").WithOrigin("minimum")}, }, { name: "golden snapshot mode unknown", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.SnapshotConfig.GoldenSnapshotConfig = &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode(3)} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.SnapshotConfig.GoldenSnapshotConfig = &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode(3)} }, want: field.ErrorList{field.Invalid(field.NewPath("snapshot_config", "golden_snapshot_config", "mode"), nil, "").WithOrigin("maximum")}, }, { name: "missing metadata", - mutate: func(tmpl *ateapipb.ActorTemplate) { tmpl.Metadata = nil }, + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Metadata = nil }, want: field.ErrorList{field.Required(field.NewPath("metadata"), "")}, }, { name: "missing metadata.atespace", - mutate: func(tmpl *ateapipb.ActorTemplate) { tmpl.Metadata.Atespace = "" }, + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Metadata.Atespace = "" }, want: field.ErrorList{field.Required(field.NewPath("metadata", "atespace"), "")}, }, { name: "invalid metadata.atespace", - mutate: func(tmpl *ateapipb.ActorTemplate) { tmpl.Metadata.Atespace = "NS1" }, + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Metadata.Atespace = "NS1" }, want: field.ErrorList{field.Invalid(field.NewPath("metadata", "atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "invalid metadata.name", - mutate: func(tmpl *ateapipb.ActorTemplate) { tmpl.Metadata.Name = "TMPL A" }, + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Metadata.Name = "TMPL A" }, want: field.ErrorList{field.Invalid(field.NewPath("metadata", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "worker_selector with an invalid label value", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"tier": "Not Valid"}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"tier": "Not Valid"}} }, want: field.ErrorList{field.Invalid(field.NewPath("worker_selector", "match_labels").Key("tier"), nil, "").WithOrigin("format=k8s-label-value")}, }, { name: "missing snapshot_config is allowed", - mutate: func(tmpl *ateapipb.ActorTemplate) { tmpl.SnapshotConfig = nil }, + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.SnapshotConfig = nil }, want: nil, }, { name: "storage_location too long", - mutate: func(tmpl *ateapipb.ActorTemplate) { + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.SnapshotConfig.StorageLocation = "gs://" + strings.Repeat("x", 1020) }, want: field.ErrorList{field.TooLong(field.NewPath("snapshot_config", "storage_location"), nil, 1024).WithOrigin("maxLength")}, }, { name: "missing storage_location", - mutate: func(tmpl *ateapipb.ActorTemplate) { tmpl.SnapshotConfig.StorageLocation = "" }, + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.SnapshotConfig.StorageLocation = "" }, // Optional with or without the gate: an empty field falls back to // --snapshot-location. want: nil, }, { name: "unspecified snapshot scope", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.SnapshotConfig.PreferredFidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.SnapshotConfig.PreferredFidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED }, want: field.ErrorList{ field.Required(field.NewPath("snapshot_config", "preferred_fidelity"), ""), }, }, { name: "preferred_fidelity outside the enum", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.SnapshotConfig.PreferredFidelity = ateapipb.SnapshotFidelity(99) + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.SnapshotConfig.PreferredFidelity = ateapi.SnapshotFidelity(99) }, want: field.ErrorList{field.Invalid(field.NewPath("snapshot_config", "preferred_fidelity"), nil, "").WithOrigin("maximum")}, }, { name: "negative preferred_fidelity", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.SnapshotConfig.PreferredFidelity = ateapipb.SnapshotFidelity(-1) + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.SnapshotConfig.PreferredFidelity = ateapi.SnapshotFidelity(-1) }, want: field.ErrorList{field.Invalid(field.NewPath("snapshot_config", "preferred_fidelity"), nil, "").WithOrigin("minimum")}, }, { name: "no containers", - mutate: func(tmpl *ateapipb.ActorTemplate) { tmpl.Containers = nil }, + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Containers = nil }, want: field.ErrorList{field.Required(field.NewPath("containers"), "")}, }, { name: "too many containers", - mutate: func(tmpl *ateapipb.ActorTemplate) { + mutate: func(tmpl *ateapi.ActorTemplate) { for i := 0; i < 10; i++ { - tmpl.Containers = append(tmpl.Containers, &ateapipb.Container{Name: fmt.Sprintf("c-%d", i), Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}) + tmpl.Containers = append(tmpl.Containers, &ateapi.Container{Name: fmt.Sprintf("c-%d", i), Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}) } }, want: field.ErrorList{field.TooMany(field.NewPath("containers"), 11, 10).WithOrigin("maxItems")}, }, { name: "duplicate container name", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers = append(tmpl.Containers, &ateapipb.Container{Name: "main", Image: "example.com/other:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}) + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers = append(tmpl.Containers, &ateapi.Container{Name: "main", Image: "example.com/other:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}) }, want: field.ErrorList{field.Duplicate(field.NewPath("containers").Index(1), nil)}, }, { name: "duplicate env name", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].Env = []*ateapipb.EnvVar{{Name: "PORT", Value: "1"}, {Name: "PORT", Value: "2"}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].Env = []*ateapi.EnvVar{{Name: "PORT", Value: "1"}, {Name: "PORT", Value: "2"}} }, want: field.ErrorList{field.Duplicate(field.NewPath("containers").Index(0).Child("env").Index(1), nil)}, }, { name: "the same volume mounted at two paths is allowed", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].VolumeMounts = []*ateapipb.VolumeMount{ + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{ {Name: "data", MountPath: "/var/data"}, {Name: "data", MountPath: "/mnt/data"}, } }, }, { name: "two volumes at the same path are rejected", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].VolumeMounts = []*ateapipb.VolumeMount{ + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{ {Name: "data", MountPath: "/var/data"}, {Name: "other", MountPath: "/var/data"}, } @@ -541,8 +541,8 @@ func TestValidateActorTemplate(t *testing.T) { want: field.ErrorList{field.Duplicate(field.NewPath("containers").Index(0).Child("volume_mounts").Index(1), nil)}, }, { name: "nested mount paths are rejected", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].VolumeMounts = []*ateapipb.VolumeMount{ + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{ {Name: "data", MountPath: "/data"}, {Name: "config", MountPath: "/data/config"}, } @@ -550,35 +550,35 @@ func TestValidateActorTemplate(t *testing.T) { want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("volume_mounts").Index(1).Child("mount_path"), nil, "")}, }, { name: "the same path in different containers is allowed", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers = append(tmpl.Containers, &ateapipb.Container{Name: "sidecar", Image: "example.com/side:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}) - tmpl.Containers[0].VolumeMounts = []*ateapipb.VolumeMount{{Name: "data", MountPath: "/var/data"}} - tmpl.Containers[1].VolumeMounts = []*ateapipb.VolumeMount{{Name: "data", MountPath: "/var/data"}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers = append(tmpl.Containers, &ateapi.Container{Name: "sidecar", Image: "example.com/side:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}) + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} + tmpl.Containers[1].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} }, }, { name: "duplicate volume name", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{ - {Name: "scratch", DurableDir: &ateapipb.DurableDirVolumeSource{}}, - {Name: "scratch", DurableDir: &ateapipb.DurableDirVolumeSource{}}, + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{ + {Name: "scratch", DurableDir: &ateapi.DurableDirVolumeSource{}}, + {Name: "scratch", DurableDir: &ateapi.DurableDirVolumeSource{}}, } }, want: field.ErrorList{field.Duplicate(field.NewPath("volumes").Index(1), nil)}, }, { name: "too many command entries", - mutate: func(tmpl *ateapipb.ActorTemplate) { + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Containers[0].Command = make([]string, 65) }, want: field.ErrorList{field.TooMany(field.NewPath("containers").Index(0).Child("command"), 65, 64).WithOrigin("maxItems")}, }, { name: "command entry too long", - mutate: func(tmpl *ateapipb.ActorTemplate) { + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Containers[0].Command = []string{strings.Repeat("x", 4097)} }, want: field.ErrorList{field.TooLong(field.NewPath("containers").Index(0).Child("command").Index(0), nil, 4096).WithOrigin("maxLength")}, }, { name: "valid command and args", - mutate: func(tmpl *ateapipb.ActorTemplate) { + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Containers[0].Command = []string{"/bin/app"} // Repeated argv values are legitimate; these lists are atomic, // not sets. @@ -586,36 +586,36 @@ func TestValidateActorTemplate(t *testing.T) { }, }, { name: "too many args entries", - mutate: func(tmpl *ateapipb.ActorTemplate) { + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Containers[0].Args = make([]string, 65) }, want: field.ErrorList{field.TooMany(field.NewPath("containers").Index(0).Child("args"), 65, 64).WithOrigin("maxItems")}, }, { name: "args entry too long", - mutate: func(tmpl *ateapipb.ActorTemplate) { + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Containers[0].Args = []string{strings.Repeat("x", 4097)} }, want: field.ErrorList{field.TooLong(field.NewPath("containers").Index(0).Child("args").Index(0), nil, 4096).WithOrigin("maxLength")}, }, { name: "too many volume_mounts", - mutate: func(tmpl *ateapipb.ActorTemplate) { + mutate: func(tmpl *ateapi.ActorTemplate) { for i := 0; i < 33; i++ { tmpl.Containers[0].VolumeMounts = append(tmpl.Containers[0].VolumeMounts, - &ateapipb.VolumeMount{Name: "data", MountPath: fmt.Sprintf("/mnt/p%d", i)}) + &ateapi.VolumeMount{Name: "data", MountPath: fmt.Sprintf("/mnt/p%d", i)}) } }, want: field.ErrorList{field.TooMany(field.NewPath("containers").Index(0).Child("volume_mounts"), 33, 32).WithOrigin("maxItems")}, }, { name: "too many env entries", - mutate: func(tmpl *ateapipb.ActorTemplate) { + mutate: func(tmpl *ateapi.ActorTemplate) { for i := 0; i < 33; i++ { - tmpl.Containers[0].Env = append(tmpl.Containers[0].Env, &ateapipb.EnvVar{Name: fmt.Sprintf("VAR_%d", i)}) + tmpl.Containers[0].Env = append(tmpl.Containers[0].Env, &ateapi.EnvVar{Name: fmt.Sprintf("VAR_%d", i)}) } }, want: field.ErrorList{field.TooMany(field.NewPath("containers").Index(0).Child("env"), 33, 32).WithOrigin("maxItems")}, }, { name: "image too long", - mutate: func(tmpl *ateapipb.ActorTemplate) { + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Containers[0].Image = strings.Repeat("x", 513) + "@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }, want: field.ErrorList{ @@ -624,318 +624,318 @@ func TestValidateActorTemplate(t *testing.T) { }, }, { name: "valid image: pinned by digest", - mutate: func(tmpl *ateapipb.ActorTemplate) { + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Containers[0].Image = "example.com/app@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }, }, { name: "container image missing digest", - mutate: func(tmpl *ateapipb.ActorTemplate) { + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Containers[0].Image = "example.com/app:v1" }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("image"), nil, "")}, }, { name: "container missing name", - mutate: func(tmpl *ateapipb.ActorTemplate) { tmpl.Containers[0].Name = "" }, + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Containers[0].Name = "" }, want: field.ErrorList{field.Required(field.NewPath("containers").Index(0).Child("name"), "")}, }, { name: "container invalid name", - mutate: func(tmpl *ateapipb.ActorTemplate) { tmpl.Containers[0].Name = "Main_1" }, + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Containers[0].Name = "Main_1" }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "container missing image", - mutate: func(tmpl *ateapipb.ActorTemplate) { tmpl.Containers[0].Image = "" }, + mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Containers[0].Image = "" }, want: field.ErrorList{field.Required(field.NewPath("containers").Index(0).Child("image"), "")}, }, { name: "valid env", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].Env = []*ateapipb.EnvVar{{Name: "PORT", Value: "8080"}, {Name: "DEBUG"}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].Env = []*ateapi.EnvVar{{Name: "PORT", Value: "8080"}, {Name: "DEBUG"}} }, }, { name: "env name with an equals sign", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].Env = []*ateapipb.EnvVar{{Name: "FOO=BAR"}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].Env = []*ateapi.EnvVar{{Name: "FOO=BAR"}} }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("env").Index(0).Child("name"), nil, "")}, }, { name: "env missing name", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].Env = []*ateapipb.EnvVar{{Value: "8080"}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].Env = []*ateapi.EnvVar{{Value: "8080"}} }, want: field.ErrorList{field.Required(field.NewPath("containers").Index(0).Child("env").Index(0).Child("name"), "")}, }, { name: "valid security_context capabilities", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].SecurityContext = &ateapipb.SecurityContext{Capabilities: &ateapipb.Capabilities{ + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].SecurityContext = &ateapi.SecurityContext{Capabilities: &ateapi.Capabilities{ Add: []string{"NET_BIND_SERVICE"}, Drop: []string{"ALL"}, }} }, }, { name: "capabilities add rejects ALL", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].SecurityContext = &ateapipb.SecurityContext{Capabilities: &ateapipb.Capabilities{Add: []string{"ALL"}}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].SecurityContext = &ateapi.SecurityContext{Capabilities: &ateapi.Capabilities{Add: []string{"ALL"}}} }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("security_context", "capabilities", "add").Index(0), nil, "")}, }, { name: "lowercase capability", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].SecurityContext = &ateapipb.SecurityContext{Capabilities: &ateapipb.Capabilities{Drop: []string{"net_raw"}}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].SecurityContext = &ateapi.SecurityContext{Capabilities: &ateapi.Capabilities{Drop: []string{"net_raw"}}} }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("security_context", "capabilities", "drop").Index(0), nil, "")}, }, { name: "duplicate capability", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].SecurityContext = &ateapipb.SecurityContext{Capabilities: &ateapipb.Capabilities{Add: []string{"NET_BIND_SERVICE", "NET_BIND_SERVICE"}}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].SecurityContext = &ateapi.SecurityContext{Capabilities: &ateapi.Capabilities{Add: []string{"NET_BIND_SERVICE", "NET_BIND_SERVICE"}}} }, want: field.ErrorList{field.Duplicate(field.NewPath("containers").Index(0).Child("security_context", "capabilities", "add").Index(1), nil)}, }, { name: "too many capabilities", - mutate: func(tmpl *ateapipb.ActorTemplate) { + mutate: func(tmpl *ateapi.ActorTemplate) { caps := make([]string, 65) for i := range caps { caps[i] = fmt.Sprintf("CAP%d", i) } - tmpl.Containers[0].SecurityContext = &ateapipb.SecurityContext{Capabilities: &ateapipb.Capabilities{Add: caps}} + tmpl.Containers[0].SecurityContext = &ateapi.SecurityContext{Capabilities: &ateapi.Capabilities{Add: caps}} }, want: field.ErrorList{field.TooMany(field.NewPath("containers").Index(0).Child("security_context", "capabilities", "add"), 65, 64).WithOrigin("maxItems")}, }, { name: "valid wakeup probe", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].WakeupProbe = &ateapipb.WakeupProbe{ - HttpGet: &ateapipb.HttpGetAction{Path: "/healthz", Port: 8080}, + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].WakeupProbe = &ateapi.WakeupProbe{ + HttpGet: &ateapi.HttpGetAction{Path: "/healthz", Port: 8080}, TimeoutSeconds: 60, } }, }, { name: "wakeup probe missing http_get", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].WakeupProbe = &ateapipb.WakeupProbe{TimeoutSeconds: 60} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].WakeupProbe = &ateapi.WakeupProbe{TimeoutSeconds: 60} }, want: field.ErrorList{field.Required(field.NewPath("containers").Index(0).Child("wakeup_probe", "http_get"), "")}, }, { name: "missing wakeup probe timeout_seconds", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].WakeupProbe = &ateapipb.WakeupProbe{HttpGet: &ateapipb.HttpGetAction{Path: "/healthz", Port: 8080}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].WakeupProbe = &ateapi.WakeupProbe{HttpGet: &ateapi.HttpGetAction{Path: "/healthz", Port: 8080}} }, want: field.ErrorList{field.Required(field.NewPath("containers").Index(0).Child("wakeup_probe", "timeout_seconds"), "")}, }, { name: "missing wakeup probe http_get.path", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].WakeupProbe = &ateapipb.WakeupProbe{HttpGet: &ateapipb.HttpGetAction{Port: 8080}, TimeoutSeconds: 60} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].WakeupProbe = &ateapi.WakeupProbe{HttpGet: &ateapi.HttpGetAction{Port: 8080}, TimeoutSeconds: 60} }, want: field.ErrorList{field.Required(field.NewPath("containers").Index(0).Child("wakeup_probe", "http_get", "path"), "")}, }, { name: "wakeup probe timeout_seconds out of range", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].WakeupProbe = &ateapipb.WakeupProbe{ - HttpGet: &ateapipb.HttpGetAction{Path: "/healthz", Port: 8080}, + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].WakeupProbe = &ateapi.WakeupProbe{ + HttpGet: &ateapi.HttpGetAction{Path: "/healthz", Port: 8080}, TimeoutSeconds: 3601, } }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("wakeup_probe", "timeout_seconds"), nil, "").WithOrigin("maximum")}, }, { name: "negative wakeup probe timeout_seconds", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].WakeupProbe = &ateapipb.WakeupProbe{ - HttpGet: &ateapipb.HttpGetAction{Path: "/healthz", Port: 8080}, + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].WakeupProbe = &ateapi.WakeupProbe{ + HttpGet: &ateapi.HttpGetAction{Path: "/healthz", Port: 8080}, TimeoutSeconds: -1, } }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("wakeup_probe", "timeout_seconds"), nil, "").WithOrigin("minimum")}, }, { name: "wakeup probe missing port", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].WakeupProbe = &ateapipb.WakeupProbe{ - HttpGet: &ateapipb.HttpGetAction{Path: "/healthz"}, + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].WakeupProbe = &ateapi.WakeupProbe{ + HttpGet: &ateapi.HttpGetAction{Path: "/healthz"}, TimeoutSeconds: 60, } }, want: field.ErrorList{field.Required(field.NewPath("containers").Index(0).Child("wakeup_probe", "http_get", "port"), "")}, }, { name: "negative wakeup probe port", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].WakeupProbe = &ateapipb.WakeupProbe{ - HttpGet: &ateapipb.HttpGetAction{Path: "/healthz", Port: -1}, + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].WakeupProbe = &ateapi.WakeupProbe{ + HttpGet: &ateapi.HttpGetAction{Path: "/healthz", Port: -1}, TimeoutSeconds: 60, } }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("wakeup_probe", "http_get", "port"), nil, "").WithOrigin("minimum")}, }, { name: "wakeup probe port out of range", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].WakeupProbe = &ateapipb.WakeupProbe{ - HttpGet: &ateapipb.HttpGetAction{Path: "/healthz", Port: 65536}, + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].WakeupProbe = &ateapi.WakeupProbe{ + HttpGet: &ateapi.HttpGetAction{Path: "/healthz", Port: 65536}, TimeoutSeconds: 60, } }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("wakeup_probe", "http_get", "port"), nil, "").WithOrigin("maximum")}, }, { name: "wakeup probe path with query string", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].WakeupProbe = &ateapipb.WakeupProbe{ - HttpGet: &ateapipb.HttpGetAction{Path: "/readyz?verbose=1", Port: 8080}, + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].WakeupProbe = &ateapi.WakeupProbe{ + HttpGet: &ateapi.HttpGetAction{Path: "/readyz?verbose=1", Port: 8080}, TimeoutSeconds: 60, } }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("wakeup_probe", "http_get", "path"), nil, "")}, }, { name: "wakeup probe path not starting with slash", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].WakeupProbe = &ateapipb.WakeupProbe{ - HttpGet: &ateapipb.HttpGetAction{Path: "readyz", Port: 8080}, + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].WakeupProbe = &ateapi.WakeupProbe{ + HttpGet: &ateapi.HttpGetAction{Path: "readyz", Port: 8080}, TimeoutSeconds: 60, } }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("wakeup_probe", "http_get", "path"), nil, "")}, }, { name: "valid volume_mount", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].VolumeMounts = []*ateapipb.VolumeMount{{Name: "data", MountPath: "/var/data"}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} }, }, { name: "volume_mount missing name", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].VolumeMounts = []*ateapipb.VolumeMount{{MountPath: "/var/data"}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{MountPath: "/var/data"}} }, want: field.ErrorList{field.Required(field.NewPath("containers").Index(0).Child("volume_mounts").Index(0).Child("name"), "")}, }, { name: "volume_mount invalid name", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].VolumeMounts = []*ateapipb.VolumeMount{{Name: "Data_1", MountPath: "/var/data"}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "Data_1", MountPath: "/var/data"}} }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("volume_mounts").Index(0).Child("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "volume_mount missing mount_path", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].VolumeMounts = []*ateapipb.VolumeMount{{Name: "data"}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data"}} }, want: field.ErrorList{field.Required(field.NewPath("containers").Index(0).Child("volume_mounts").Index(0).Child("mount_path"), "")}, }, { name: "relative mount_path", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].VolumeMounts = []*ateapipb.VolumeMount{{Name: "data", MountPath: "var/data"}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "var/data"}} }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("volume_mounts").Index(0).Child("mount_path"), nil, "")}, }, { name: "valid durable_dir volume", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{Name: "scratch", DurableDir: &ateapipb.DurableDirVolumeSource{}}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "scratch", DurableDir: &ateapi.DurableDirVolumeSource{}}} }, }, { name: "too many volumes", - mutate: func(tmpl *ateapipb.ActorTemplate) { + mutate: func(tmpl *ateapi.ActorTemplate) { for i := 0; i < 33; i++ { - tmpl.Volumes = append(tmpl.Volumes, &ateapipb.Volume{Name: fmt.Sprintf("vol-%d", i), DurableDir: &ateapipb.DurableDirVolumeSource{}}) + tmpl.Volumes = append(tmpl.Volumes, &ateapi.Volume{Name: fmt.Sprintf("vol-%d", i), DurableDir: &ateapi.DurableDirVolumeSource{}}) } }, want: field.ErrorList{field.TooMany(field.NewPath("volumes"), 33, 32).WithOrigin("maxItems")}, }, { name: "volume missing name", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{DurableDir: &ateapipb.DurableDirVolumeSource{}}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{DurableDir: &ateapi.DurableDirVolumeSource{}}} }, want: field.ErrorList{field.Required(field.NewPath("volumes").Index(0).Child("name"), "")}, }, { name: "volume invalid name", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{Name: "Scratch_1", DurableDir: &ateapipb.DurableDirVolumeSource{}}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "Scratch_1", DurableDir: &ateapi.DurableDirVolumeSource{}}} }, want: field.ErrorList{field.Invalid(field.NewPath("volumes").Index(0).Child("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "volume with no source", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{Name: "scratch"}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "scratch"}} }, want: field.ErrorList{field.Invalid(field.NewPath("volumes").Index(0), nil, "one of").WithOrigin("union")}, }, { name: "volume with two sources", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{ + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{ Name: "scratch", - DurableDir: &ateapipb.DurableDirVolumeSource{}, - Image: &ateapipb.ImageVolumeSource{Reference: "example.com/app@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}, + DurableDir: &ateapi.DurableDirVolumeSource{}, + Image: &ateapi.ImageVolumeSource{Reference: "example.com/app@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}, }} }, want: field.ErrorList{field.Invalid(field.NewPath("volumes").Index(0), nil, "one of").WithOrigin("union")}, }, { name: "valid image volume", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{Name: "tools", Image: &ateapipb.ImageVolumeSource{Reference: "example.com/app@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "tools", Image: &ateapi.ImageVolumeSource{Reference: "example.com/app@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}} }, }, { name: "image volume missing reference", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{Name: "tools", Image: &ateapipb.ImageVolumeSource{}}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "tools", Image: &ateapi.ImageVolumeSource{}}} }, want: field.ErrorList{field.Required(field.NewPath("volumes").Index(0).Child("image", "reference"), "")}, }, { name: "image volume reference missing digest", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{Name: "tools", Image: &ateapipb.ImageVolumeSource{Reference: "example.com/app:v1"}}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "tools", Image: &ateapi.ImageVolumeSource{Reference: "example.com/app:v1"}}} }, want: field.ErrorList{field.Invalid(field.NewPath("volumes").Index(0).Child("image", "reference"), nil, "")}, }, { name: "valid external volume template", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{Name: "data", External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{CapacityBytes: 10 << 30, StorageClassName: "fast-ssd"}}}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, StorageClassName: "fast-ssd"}}}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": nil}, }, { name: "external volume template missing capacity", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{Name: "data", External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{StorageClassName: "fast-ssd"}}}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "fast-ssd"}}}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": {field.Required(field.NewPath("volumes").Index(0).Child("external", "template", "capacity_bytes"), "")}}, }, { name: "external volume template negative capacity", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{Name: "data", External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{CapacityBytes: -1, StorageClassName: "fast-ssd"}}}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: -1, StorageClassName: "fast-ssd"}}}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": {field.Invalid(field.NewPath("volumes").Index(0).Child("external", "template", "capacity_bytes"), nil, "").WithOrigin("minimum")}}, }, { name: "external volume template missing storage_class_name", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{Name: "data", External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{CapacityBytes: 10 << 30}}}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30}}}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": {field.Required(field.NewPath("volumes").Index(0).Child("external", "template", "storage_class_name"), "")}}, }, { name: "external volume template invalid storage_class_name", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Volumes = []*ateapipb.Volume{{Name: "data", External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{CapacityBytes: 10 << 30, StorageClassName: "Fast SSD"}}}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, StorageClassName: "Fast SSD"}}}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": {field.Invalid(field.NewPath("volumes").Index(0).Child("external", "template", "storage_class_name"), nil, "").WithOrigin("format=k8s-long-name")}}, }, { name: "valid resources", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].Resources = &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(500, 2<<30)} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].Resources = &ateapi.ResourceRequirements{Limits: resources.CPUMemory(500, 2<<30)} }, }, { name: "negative cpu", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].Resources = &ateapipb.ResourceRequirements{Limits: &ateapipb.Resources{CpuMillicores: -1}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].Resources = &ateapi.ResourceRequirements{Limits: &ateapi.Resources{CpuMillicores: -1}} }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("resources", "limits", "cpu_millicores"), nil, "").WithOrigin("minimum")}, }, { name: "negative memory", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].Resources = &ateapipb.ResourceRequirements{Limits: &ateapipb.Resources{MemoryBytes: -1}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].Resources = &ateapi.ResourceRequirements{Limits: &ateapi.Resources{MemoryBytes: -1}} }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("resources", "limits", "memory_bytes"), nil, "").WithOrigin("minimum")}, }, { name: "cpu above maximum", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Containers[0].Resources = &ateapipb.ResourceRequirements{Limits: &ateapipb.Resources{CpuMillicores: 1000000}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Containers[0].Resources = &ateapi.ResourceRequirements{Limits: &ateapi.Resources{CpuMillicores: 1000000}} }, want: field.ErrorList{field.Invalid(field.NewPath("containers").Index(0).Child("resources", "limits", "cpu_millicores"), nil, "").WithOrigin("maximum")}, }, { name: "template-level resources validated too", - mutate: func(tmpl *ateapipb.ActorTemplate) { - tmpl.Resources = &ateapipb.ResourceRequirements{Limits: &ateapipb.Resources{CpuMillicores: 1000, MemoryBytes: -1}} + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Resources = &ateapi.ResourceRequirements{Limits: &ateapi.Resources{CpuMillicores: 1000, MemoryBytes: -1}} }, want: field.ErrorList{field.Invalid(field.NewPath("resources", "limits", "memory_bytes"), nil, "").WithOrigin("minimum")}, }} @@ -957,15 +957,15 @@ func TestValidateActorTemplate(t *testing.T) { // validation; mutations tweak it per test case. The snapshot scopes and // resume policy are set explicitly because TestValidateActorTemplate // exercises validation directly, without defaulting. -func validActorTemplate(mutations ...func(*ateapipb.ActorTemplate)) *ateapipb.ActorTemplate { - template := &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ns1", Name: "tmpl-a"}, - Containers: []*ateapipb.Container{{Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}, - SnapshotConfig: &ateapipb.SnapshotConfig{ +func validActorTemplate(mutations ...func(*ateapi.ActorTemplate)) *ateapi.ActorTemplate { + template := &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ns1", Name: "tmpl-a"}, + Containers: []*ateapi.Container{{Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}, + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: "gs://my-bucket/snapshots", - PreferredFidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + PreferredFidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, }, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, } for _, m := range mutations { m(template) diff --git a/cmd/ateapi/internal/apivalidation/actor_test.go b/cmd/ateapi/internal/apivalidation/actor_test.go index e52c315db6..272ba567cc 100644 --- a/cmd/ateapi/internal/apivalidation/actor_test.go +++ b/cmd/ateapi/internal/apivalidation/actor_test.go @@ -20,7 +20,7 @@ import ( "strings" "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "k8s.io/apimachinery/pkg/util/validation/field" ) @@ -29,8 +29,8 @@ func TestValidateCreateActorRequest(t *testing.T) { // is scrubbed on input, we don't need to test the status field here, other // than that it is optional. TestValidateActorUpdate covers status // validation and updates. - validReq := func(actor *ateapipb.Actor, mods ...func(actor *ateapipb.CreateActorRequest)) *ateapipb.CreateActorRequest { - req := &ateapipb.CreateActorRequest{ + validReq := func(actor *ateapi.Actor, mods ...func(actor *ateapi.CreateActorRequest)) *ateapi.CreateActorRequest { + req := &ateapi.CreateActorRequest{ Actor: actor, } for _, m := range mods { @@ -46,7 +46,7 @@ func TestValidateCreateActorRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.CreateActorRequest + req *ateapi.CreateActorRequest want field.ErrorList }{{ "valid", @@ -58,27 +58,27 @@ func TestValidateCreateActorRequest(t *testing.T) { nil, // ignored on input }, { "missing actor", - &ateapipb.CreateActorRequest{Actor: nil}, + &ateapi.CreateActorRequest{Actor: nil}, field.ErrorList{field.Required(field.NewPath("actor"), "")}, }, { "missing actor.metadata", - validReq(validActor(func(a *ateapipb.Actor) { a.Metadata = nil })), + validReq(validActor(func(a *ateapi.Actor) { a.Metadata = nil })), field.ErrorList{field.Required(field.NewPath("actor", "metadata"), "")}, }, { "missing actor.metadata.atespace", - validReq(validActor(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Atespace = "" }))), + validReq(validActor(withMetadata(func(m *ateapi.ResourceMetadata) { m.Atespace = "" }))), field.ErrorList{field.Required(field.NewPath("actor", "metadata", "atespace"), "")}, }, { "invalid actor.metadata.atespace", - validReq(validActor(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Atespace = "NS1" }))), + validReq(validActor(withMetadata(func(m *ateapi.ResourceMetadata) { m.Atespace = "NS1" }))), field.ErrorList{field.Invalid(field.NewPath("actor", "metadata", "atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "missing actor.metadata.name", - validReq(validActor(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Name = "" }))), + validReq(validActor(withMetadata(func(m *ateapi.ResourceMetadata) { m.Name = "" }))), field.ErrorList{field.Required(field.NewPath("actor", "metadata", "name"), "")}, }, { "invalid actor.metadata.name", - validReq(validActor(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Name = "ID1" }))), + validReq(validActor(withMetadata(func(m *ateapi.ResourceMetadata) { m.Name = "ID1" }))), field.ErrorList{field.Invalid(field.NewPath("actor", "metadata", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "valid actor.actor_template", @@ -86,7 +86,7 @@ func TestValidateCreateActorRequest(t *testing.T) { nil, }, { "missing actor.actor_template", - validReq(validActor(func(a *ateapipb.Actor) { a.ActorTemplate = nil })), + validReq(validActor(func(a *ateapi.Actor) { a.ActorTemplate = nil })), field.ErrorList{field.Required(field.NewPath("actor", "actor_template"), "")}, }, { "missing actor.actor_template.atespace", @@ -110,7 +110,7 @@ func TestValidateCreateActorRequest(t *testing.T) { nil, }, { "worker_selector with nil match_labels", - validReq(validActor(func(a *ateapipb.Actor) { a.WorkerSelector = &ateapipb.Selector{} })), + validReq(validActor(func(a *ateapi.Actor) { a.WorkerSelector = &ateapi.Selector{} })), field.ErrorList{field.Invalid(field.NewPath("actor", "worker_selector"), nil, "one of").WithOrigin("union")}, }, { "worker_selector with empty match_labels", @@ -166,8 +166,8 @@ func TestValidateActorUpdate(t *testing.T) { // test cases should live. validInput := validActor withStatus := withActorStatus - validOutput := func(mods ...func(*ateapipb.Actor)) *ateapipb.Actor { - allMods := []func(*ateapipb.Actor){withStatus()} // this needs to go first + validOutput := func(mods ...func(*ateapi.Actor)) *ateapi.Actor { + allMods := []func(*ateapi.Actor){withStatus()} // this needs to go first allMods = append(allMods, mods...) a := validActor(allMods...) return a @@ -180,8 +180,8 @@ func TestValidateActorUpdate(t *testing.T) { tests := []struct { name string - oldVal *ateapipb.Actor - newVal *ateapipb.Actor + oldVal *ateapi.Actor + newVal *ateapi.Actor // want is the result with no preview gates enabled. want field.ErrorList // wantWithPreview maps a --preview value to the result with those @@ -194,12 +194,12 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "missing actor.metadata", oldVal: validInput(), - newVal: validOutput(func(a *ateapipb.Actor) { a.Metadata = nil }), + newVal: validOutput(func(a *ateapi.Actor) { a.Metadata = nil }), want: field.ErrorList{field.Required(field.NewPath("metadata"), "")}, }, { name: "missing actor.metadata.atespace", oldVal: validInput(), - newVal: validOutput(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Atespace = "" })), + newVal: validOutput(withMetadata(func(m *ateapi.ResourceMetadata) { m.Atespace = "" })), want: field.ErrorList{ field.Required(field.NewPath("metadata", "atespace"), ""), field.Invalid(field.NewPath("metadata", "atespace"), nil, "").WithOrigin("immutable"), @@ -207,12 +207,12 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "invalid actor.metadata.atespace", oldVal: validInput(), - newVal: validOutput(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Atespace = "invalid value" })), + newVal: validOutput(withMetadata(func(m *ateapi.ResourceMetadata) { m.Atespace = "invalid value" })), want: field.ErrorList{field.Invalid(field.NewPath("metadata", "atespace"), nil, "").WithOrigin("immutable")}, }, { name: "missing actor.metadata.name", oldVal: validInput(), - newVal: validOutput(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Name = "" })), + newVal: validOutput(withMetadata(func(m *ateapi.ResourceMetadata) { m.Name = "" })), want: field.ErrorList{ field.Required(field.NewPath("metadata", "name"), ""), field.Invalid(field.NewPath("metadata", "name"), nil, "").WithOrigin("immutable"), @@ -220,7 +220,7 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "invalid actor.metadata.name", oldVal: validInput(), - newVal: validOutput(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Name = "invalid value" })), + newVal: validOutput(withMetadata(func(m *ateapi.ResourceMetadata) { m.Name = "invalid value" })), want: field.ErrorList{field.Invalid(field.NewPath("metadata", "name"), nil, "").WithOrigin("immutable")}, }, { name: "change actor.actor_template is allowed", @@ -229,7 +229,7 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "clear actor.actor_template", oldVal: validInput(withActorTemplate("as", "nm")), - newVal: validOutput(func(a *ateapipb.Actor) { a.ActorTemplate = nil }), + newVal: validOutput(func(a *ateapi.Actor) { a.ActorTemplate = nil }), want: field.ErrorList{field.Required(field.NewPath("actor_template"), "")}, }, { name: "add actor.source_tag", @@ -239,7 +239,7 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "clear actor.source_tag", oldVal: validInput(withSourceTag("as", "nm")), - newVal: validOutput(func(a *ateapipb.Actor) { a.SourceTag = nil }), + newVal: validOutput(func(a *ateapi.Actor) { a.SourceTag = nil }), want: field.ErrorList{field.Invalid(field.NewPath("source_tag"), nil, "").WithOrigin("immutable")}, }, { name: "change actor.source_tag", @@ -261,7 +261,7 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "invalid worker_selector with nil match_labels", oldVal: validInput(), - newVal: validOutput(func(a *ateapipb.Actor) { a.WorkerSelector = &ateapipb.Selector{} }), + newVal: validOutput(func(a *ateapi.Actor) { a.WorkerSelector = &ateapi.Selector{} }), want: field.ErrorList{field.Invalid(field.NewPath("worker_selector"), nil, "one of").WithOrigin("union")}, }, { name: "invalid worker_selector label key", @@ -286,7 +286,7 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "clear actor.source_tag", oldVal: validInput(withSourceTag("as", "nm")), - newVal: validOutput(func(a *ateapipb.Actor) { a.SourceTag = nil }), + newVal: validOutput(func(a *ateapi.Actor) { a.SourceTag = nil }), want: field.ErrorList{field.Invalid(field.NewPath("source_tag"), nil, "").WithOrigin("immutable")}, }, { name: "change actor.source_tag", @@ -296,50 +296,50 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "unspecified actor.status", oldVal: validInput(withStatus()), - newVal: validOutput(func(a *ateapipb.Actor) { a.Status = nil }), + newVal: validOutput(func(a *ateapi.Actor) { a.Status = nil }), want: field.ErrorList{field.Required(field.NewPath("status"), "")}, }, { name: "unspecified actor.status.state", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { s.State = 0 })), + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.State = 0 })), want: field.ErrorList{field.Required(field.NewPath("status", "state"), "")}, }, { name: "change actor.status.state", - oldVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { s.State = ateapipb.ActorState_ACTOR_STATE_RUNNING })), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { s.State = ateapipb.ActorState_ACTOR_STATE_CRASHED })), + oldVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.State = ateapi.ActorState_ACTOR_STATE_RUNNING })), + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.State = ateapi.ActorState_ACTOR_STATE_CRASHED })), }, { name: "negative actor.status.state", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { s.State = -1 })), + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.State = -1 })), want: field.ErrorList{field.Invalid(field.NewPath("status", "state"), nil, "").WithOrigin("minimum")}, }, { name: "just out of bounds actor.status.state", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { s.State = 10 })), + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.State = 10 })), want: field.ErrorList{field.Invalid(field.NewPath("status", "state"), nil, "").WithOrigin("maximum")}, }, { name: "invalid actor.status.state", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { s.State = 1234567890 })), + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.State = 1234567890 })), want: field.ErrorList{field.Invalid(field.NewPath("status", "state"), nil, "").WithOrigin("maximum")}, }, { name: "set valid actor.status.worker_assignment, IPv4", oldVal: validInput(withStatus()), - newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapipb.WorkerAssignment) { wa.WorkerPodIps = []string{"1.2.3.4"} }))), + newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapi.WorkerAssignment) { wa.WorkerPodIps = []string{"1.2.3.4"} }))), }, { name: "set valid actor.status.worker_assignment, IPv6", oldVal: validInput(withStatus()), - newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapipb.WorkerAssignment) { wa.WorkerPodIps = []string{"1234::5678"} }))), + newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapi.WorkerAssignment) { wa.WorkerPodIps = []string{"1234::5678"} }))), }, { name: "set valid actor.status.worker_assignment, dual-stack", oldVal: validInput(withStatus()), - newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapipb.WorkerAssignment) { + newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapi.WorkerAssignment) { wa.WorkerPodIps = []string{"1234::5678", "1.2.3.4"} }))), }, { name: "invalid actor.status.worker_assignment.worker_pod_ips: two IPv6", oldVal: validInput(withStatus()), - newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapipb.WorkerAssignment) { + newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapi.WorkerAssignment) { wa.WorkerPodIps = []string{"1234::5678", "1234::9"} }))), want: field.ErrorList{ @@ -348,7 +348,7 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "invalid actor.status.worker_assignment.worker_pod_ips: too many", oldVal: validInput(withStatus()), - newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapipb.WorkerAssignment) { + newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapi.WorkerAssignment) { wa.WorkerPodIps = []string{"1.2.3.4", "1234::5678", "1.2.3.5"} }))), want: field.ErrorList{ @@ -357,13 +357,13 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "set valid actor.status.worker_assignment.worker_spiffe_id", oldVal: validInput(withStatus()), - newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapipb.WorkerAssignment) { + newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapi.WorkerAssignment) { wa.WorkerSpiffeId = "spiffe://cluster.local/ns/ns/sa/ateworker" }))), }, { name: "invalid actor.status.worker_assignment.worker_spiffe_id", oldVal: validInput(withStatus()), - newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapipb.WorkerAssignment) { + newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapi.WorkerAssignment) { wa.WorkerSpiffeId = "ns/ns/sa/ateworker" }))), want: field.ErrorList{ @@ -372,19 +372,19 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "set valid actor.status.worker_assignment.sandbox_runtime", oldVal: validInput(withStatus()), - newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapipb.WorkerAssignment) { - wa.SandboxRuntime = &ateapipb.ActorSandboxRuntime{ + newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapi.WorkerAssignment) { + wa.SandboxRuntime = &ateapi.ActorSandboxRuntime{ SandboxClass: "gvisor", - Version: &ateapipb.VersionedSandboxCompat{SchemaVersion: "v1", Attributes: []*ateapipb.AttributeEntry{{Key: "architecture", Value: "amd64"}}}, + Version: &ateapi.VersionedSandboxCompat{SchemaVersion: "v1", Attributes: []*ateapi.AttributeEntry{{Key: "architecture", Value: "amd64"}}}, } }))), }, { name: "invalid actor.status.worker_assignment.sandbox_runtime.sandbox_class", oldVal: validInput(withStatus()), - newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapipb.WorkerAssignment) { - wa.SandboxRuntime = &ateapipb.ActorSandboxRuntime{ + newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapi.WorkerAssignment) { + wa.SandboxRuntime = &ateapi.ActorSandboxRuntime{ SandboxClass: "plain", - Version: &ateapipb.VersionedSandboxCompat{SchemaVersion: "v1", Attributes: []*ateapipb.AttributeEntry{{Key: "architecture", Value: "amd64"}}}, + Version: &ateapi.VersionedSandboxCompat{SchemaVersion: "v1", Attributes: []*ateapi.AttributeEntry{{Key: "architecture", Value: "amd64"}}}, } }))), want: field.ErrorList{ @@ -393,23 +393,23 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "clear actor.status.worker_assignment", oldVal: validInput(withStatus(withWorkerAssignment())), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { s.WorkerAssignment = nil })), + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.WorkerAssignment = nil })), }, { name: "modify actor.status.worker_assignment identity", oldVal: validInput(withStatus(withWorkerAssignment())), - newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapipb.WorkerAssignment) { wa.WorkerPod = "pod2" }))), + newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapi.WorkerAssignment) { wa.WorkerPod = "pod2" }))), want: field.ErrorList{field.Invalid(field.NewPath("status", "worker_assignment", "worker_pod"), nil, "").WithOrigin("update")}, }, { name: "modify actor.status.worker_assignment worker process", oldVal: validInput(withStatus(withWorkerAssignment())), - newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapipb.WorkerAssignment) { + newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapi.WorkerAssignment) { wa.WorkerEpoch = 2 wa.WorkerPodIps = []string{"10.9.8.7"} }))), }, { name: "empty actor.status.worker_assignment", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { s.WorkerAssignment = &ateapipb.WorkerAssignment{} })), + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.WorkerAssignment = &ateapi.WorkerAssignment{} })), want: field.ErrorList{ field.Required(field.NewPath("status", "worker_assignment", "worker"), ""), field.Required(field.NewPath("status", "worker_assignment", "worker_namespace"), ""), @@ -422,8 +422,8 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "invalid actor.status.worker_assignment", oldVal: validInput(), - newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapipb.WorkerAssignment) { - wa.Worker = &ateapipb.ObjectRef{Atespace: "not-allowed", Name: "bad value"} + newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapi.WorkerAssignment) { + wa.Worker = &ateapi.ObjectRef{Atespace: "not-allowed", Name: "bad value"} wa.WorkerNamespace = "invalid namespace" wa.WorkerPool = "invalid pool" wa.WorkerPod = "invalid pod" @@ -445,7 +445,7 @@ func TestValidateActorUpdate(t *testing.T) { // because we have manual IP format validation, let's be sure name: "invalid actor.status.worker_assignment.worker_pod_ips: leading 0s", oldVal: validInput(), - newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapipb.WorkerAssignment) { wa.WorkerPodIps = []string{"001.002.003.004"} }))), + newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapi.WorkerAssignment) { wa.WorkerPodIps = []string{"001.002.003.004"} }))), want: field.ErrorList{ field.Invalid(field.NewPath("status", "worker_assignment", "worker_pod_ips").Index(0), nil, "").WithOrigin("format=ip-strict"), }, @@ -453,102 +453,102 @@ func TestValidateActorUpdate(t *testing.T) { // because we have manual IP format validation, let's be sure name: "invalid actor.status.worker_assignment.worker_pod_ips: non-canonical", oldVal: validInput(), - newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapipb.WorkerAssignment) { wa.WorkerPodIps = []string{"0012::0034"} }))), + newVal: validOutput(withStatus(withWorkerAssignment(func(wa *ateapi.WorkerAssignment) { wa.WorkerPodIps = []string{"0012::0034"} }))), want: field.ErrorList{ field.Invalid(field.NewPath("status", "worker_assignment", "worker_pod_ips").Index(0), nil, "").WithOrigin("format=ip-strict"), }, }, { name: "valid actor.status.assigned_node", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.AssignedNode = "node-1" })), }, { name: "invalid actor.status.assigned_node", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.AssignedNode = "NOT A NODE" })), want: field.ErrorList{field.Invalid(field.NewPath("status", "assigned_node"), nil, "").WithOrigin("format=k8s-long-name")}, }, { name: "valid actor.status.last_assigned_generation", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 1 })), }, { name: "increasing actor.status.last_assigned_generation", - oldVal: validInput(withStatus(func(s *ateapipb.ActorStatus) { + oldVal: validInput(withStatus(func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 2 })), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 3 })), }, { name: "unchanged actor.status.last_assigned_generation", - oldVal: validInput(withStatus(func(s *ateapipb.ActorStatus) { + oldVal: validInput(withStatus(func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 3 })), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 3 })), }, { name: "decreasing actor.status.last_assigned_generation", - oldVal: validInput(withStatus(func(s *ateapipb.ActorStatus) { + oldVal: validInput(withStatus(func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 3 })), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 1 })), want: field.ErrorList{field.Invalid(field.NewPath("status", "last_assigned_generation"), nil, "").WithOrigin("monotonic")}, }, { name: "unsetting actor.status.last_assigned_generation", - oldVal: validInput(withStatus(func(s *ateapipb.ActorStatus) { + oldVal: validInput(withStatus(func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 3 })), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 0 })), want: field.ErrorList{field.Invalid(field.NewPath("status", "last_assigned_generation"), nil, "").WithOrigin("update")}, }, { name: "negative actor.status.last_assigned_generation", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = -1 })), want: field.ErrorList{field.Invalid(field.NewPath("status", "last_assigned_generation"), nil, "").WithOrigin("minimum")}, }, { name: "valid actor.status.snapshots with durable object snapshot", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{validSnapshot()} + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{validSnapshot()} })), }, { name: "valid actor.status.snapshots actor_template_uid", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{validSnapshot(func(snap *ateapipb.Snapshot) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{validSnapshot(func(snap *ateapi.Snapshot) { snap.ActorTemplateUid = "01234567-89ab-cdef-0123-456789abcdef" })} })), }, { // Each suspend restamps the UID of the template the snapshot was captured under. name: "changing actor.status.snapshots.actor_template_uid is allowed", - oldVal: validInput(withStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{validSnapshot(func(snap *ateapipb.Snapshot) { + oldVal: validInput(withStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{validSnapshot(func(snap *ateapi.Snapshot) { snap.ActorTemplateUid = "01234567-89ab-cdef-0123-456789abcdef" })} })), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{validSnapshot(func(snap *ateapipb.Snapshot) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{validSnapshot(func(snap *ateapi.Snapshot) { snap.ActorTemplateUid = "fedcba98-7654-3210-fedc-ba9876543210" })} })), }, { name: "invalid actor.status.snapshots.actor_template_uid", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{validSnapshot(func(snap *ateapipb.Snapshot) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{validSnapshot(func(snap *ateapi.Snapshot) { snap.ActorTemplateUid = "not-a-uuid" })} })), @@ -556,8 +556,8 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "valid actor.status.snapshots uuid and locality", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{validSnapshot(func(snap *ateapipb.Snapshot) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{validSnapshot(func(snap *ateapi.Snapshot) { snap.Uuid = "snap-1" snap.Locality = "node-1" })} @@ -565,8 +565,8 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "missing actor.status.snapshots.uuid", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{validSnapshot(func(snap *ateapipb.Snapshot) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{validSnapshot(func(snap *ateapi.Snapshot) { snap.Uuid = "" })} })), @@ -574,8 +574,8 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "invalid actor.status.snapshots.uuid", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{validSnapshot(func(snap *ateapipb.Snapshot) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{validSnapshot(func(snap *ateapi.Snapshot) { snap.Uuid = "SNAP 1" })} })), @@ -583,8 +583,8 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "invalid actor.status.snapshots.locality", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{validSnapshot(func(snap *ateapipb.Snapshot) { + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{validSnapshot(func(snap *ateapi.Snapshot) { snap.Locality = "NODE 1" })} })), @@ -592,45 +592,45 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "duplicate actor.status.snapshots generation", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{ - validSnapshot(func(snap *ateapipb.Snapshot) { snap.Generation = 1 }), - validSnapshot(func(snap *ateapipb.Snapshot) { snap.Generation = 1 }), + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{ + validSnapshot(func(snap *ateapi.Snapshot) { snap.Generation = 1 }), + validSnapshot(func(snap *ateapi.Snapshot) { snap.Generation = 1 }), } })), want: field.ErrorList{field.Duplicate(field.NewPath("status", "snapshots").Index(1), nil)}, }, { name: "valid actor.status.snapshots.fidelity", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{validSnapshot(func(snap *ateapipb.Snapshot) { - snap.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{validSnapshot(func(snap *ateapi.Snapshot) { + snap.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES })} })), }, { name: "missing actor.status.snapshots.fidelity", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{validSnapshot(func(snap *ateapipb.Snapshot) { - snap.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{validSnapshot(func(snap *ateapi.Snapshot) { + snap.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED })} })), want: field.ErrorList{field.Required(field.NewPath("status", "snapshots").Index(0).Child("fidelity"), "")}, }, { name: "negative actor.status.snapshots.fidelity", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{validSnapshot(func(snap *ateapipb.Snapshot) { - snap.Fidelity = ateapipb.SnapshotFidelity(-1) + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{validSnapshot(func(snap *ateapi.Snapshot) { + snap.Fidelity = ateapi.SnapshotFidelity(-1) })} })), want: field.ErrorList{field.Invalid(field.NewPath("status", "snapshots").Index(0).Child("fidelity"), nil, "").WithOrigin("minimum")}, }, { name: "invalid actor.status.snapshots.fidelity", oldVal: validInput(), - newVal: validOutput(withStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{validSnapshot(func(snap *ateapipb.Snapshot) { - snap.Fidelity = ateapipb.SnapshotFidelity(4) + newVal: validOutput(withStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{validSnapshot(func(snap *ateapi.Snapshot) { + snap.Fidelity = ateapi.SnapshotFidelity(4) })} })), want: field.ErrorList{field.Invalid(field.NewPath("status", "snapshots").Index(0).Child("fidelity"), nil, "").WithOrigin("maximum")}, @@ -647,26 +647,26 @@ func TestValidateActorUpdate(t *testing.T) { // in an update validates like one added at creation. name: "adding a volume", oldVal: validActor(withActorStatus()), - newVal: validActor(withActorStatus(func(s *ateapipb.ActorStatus) { - s.ExternalVolumes = &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{{Name: "vol-a", VolumeType: "substrate.io/mock"}}} + newVal: validActor(withActorStatus(func(s *ateapi.ActorStatus) { + s.ExternalVolumes = &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{{Name: "vol-a", VolumeType: "substrate.io/mock"}}} })), want: nil, wantWithPreview: map[string]field.ErrorList{"ALL": nil}, }, { name: "adding a volume to an actor with no status", oldVal: validActor(), - newVal: validActor(withActorStatus(func(s *ateapipb.ActorStatus) { - s.ExternalVolumes = &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{{Name: "vol-a", VolumeType: "substrate.io/mock"}}} + newVal: validActor(withActorStatus(func(s *ateapi.ActorStatus) { + s.ExternalVolumes = &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{{Name: "vol-a", VolumeType: "substrate.io/mock"}}} })), want: nil, wantWithPreview: map[string]field.ErrorList{"ALL": nil}, }, { name: "provisioning transition on an existing volume", - oldVal: validInput(withStatus(func(s *ateapipb.ActorStatus) { - s.ExternalVolumes = &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{{Name: "vol-a", VolumeType: "substrate.io/mock"}}} + oldVal: validInput(withStatus(func(s *ateapi.ActorStatus) { + s.ExternalVolumes = &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{{Name: "vol-a", VolumeType: "substrate.io/mock"}}} })), - newVal: validActor(withActorStatus(func(s *ateapipb.ActorStatus) { - s.ExternalVolumes = &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{{ + newVal: validActor(withActorStatus(func(s *ateapi.ActorStatus) { + s.ExternalVolumes = &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{{ Name: "vol-a", VolumeType: "substrate.io/mock", StorageVolumeId: "csi-426d29b7", @@ -678,8 +678,8 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "duplicate external_volumes volume_name", oldVal: validActor(withActorStatus()), - newVal: validActor(withActorStatus(func(s *ateapipb.ActorStatus) { - s.ExternalVolumes = &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{ + newVal: validActor(withActorStatus(func(s *ateapi.ActorStatus) { + s.ExternalVolumes = &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol-a", VolumeType: "substrate.io/mock"}, {Name: "vol-a", VolumeType: "substrate.io/mock"}, }} @@ -691,12 +691,12 @@ func TestValidateActorUpdate(t *testing.T) { }, { name: "too many external_volumes", oldVal: validActor(withActorStatus()), - newVal: validActor(withActorStatus(func(s *ateapipb.ActorStatus) { - vols := make([]*ateapipb.ExternalVolumeStatus, 33) + newVal: validActor(withActorStatus(func(s *ateapi.ActorStatus) { + vols := make([]*ateapi.ExternalVolumeStatus, 33) for i := range vols { - vols[i] = &ateapipb.ExternalVolumeStatus{Name: fmt.Sprintf("vol-%d", i), VolumeType: "substrate.io/mock"} + vols[i] = &ateapi.ExternalVolumeStatus{Name: fmt.Sprintf("vol-%d", i), VolumeType: "substrate.io/mock"} } - s.ExternalVolumes = &ateapipb.ExternalVolumes{Volumes: vols} + s.ExternalVolumes = &ateapi.ExternalVolumes{Volumes: vols} })), want: field.ErrorList{field.TooMany(field.NewPath("status", "external_volumes", "volumes"), 33, 32).WithOrigin("maxItems")}, wantWithPreview: map[string]field.ErrorList{ @@ -715,31 +715,31 @@ func TestValidateActorUpdate(t *testing.T) { func TestValidateGetActorRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.GetActorRequest + req *ateapi.GetActorRequest want field.ErrorList }{{ "valid", - &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}}, + &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}}, nil, }, { "missing actor", - &ateapipb.GetActorRequest{}, + &ateapi.GetActorRequest{}, field.ErrorList{field.Required(field.NewPath("actor"), "")}, }, { "missing actor.atespace", - &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Name: "id1"}}, + &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Name: "id1"}}, field.ErrorList{field.Required(field.NewPath("actor", "atespace"), "")}, }, { "invalid actor.atespace", - &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "NS1", Name: "id1"}}, + &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: "NS1", Name: "id1"}}, field.ErrorList{field.Invalid(field.NewPath("actor", "atespace"), "NS1", "").WithOrigin("format=k8s-short-name")}, }, { "missing actor.name", - &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "ns1"}}, + &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: "ns1"}}, field.ErrorList{field.Required(field.NewPath("actor", "name"), "")}, }, { "invalid actor.name", - &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "ID1"}}, + &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "ID1"}}, field.ErrorList{field.Invalid(field.NewPath("actor", "name"), "ID1", "").WithOrigin("format=k8s-short-name")}, }} for _, tt := range tests { @@ -752,36 +752,36 @@ func TestValidateGetActorRequest(t *testing.T) { func TestValidateListActorsRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.ListActorsRequest + req *ateapi.ListActorsRequest want field.ErrorList }{{ "valid, atespace scoped", - &ateapipb.ListActorsRequest{Atespace: "ns1"}, + &ateapi.ListActorsRequest{Atespace: "ns1"}, nil, }, { // Empty atespace means "all atespaces" (kubectl ate get actors -A). "valid, empty atespace means all atespaces", - &ateapipb.ListActorsRequest{}, + &ateapi.ListActorsRequest{}, nil, }, { "invalid atespace", - &ateapipb.ListActorsRequest{Atespace: "NS1"}, + &ateapi.ListActorsRequest{Atespace: "NS1"}, field.ErrorList{field.Invalid(field.NewPath("atespace"), "NS1", "").WithOrigin("format=k8s-short-name")}, }, { "valid, positive page_size", - &ateapipb.ListActorsRequest{Atespace: "ns1", Options: &ateapipb.ListOptions{PageSize: 10}}, + &ateapi.ListActorsRequest{Atespace: "ns1", Options: &ateapi.ListOptions{PageSize: 10}}, nil, }, { "negative page_size", - &ateapipb.ListActorsRequest{Atespace: "ns1", Options: &ateapipb.ListOptions{PageSize: -1}}, + &ateapi.ListActorsRequest{Atespace: "ns1", Options: &ateapi.ListOptions{PageSize: -1}}, field.ErrorList{field.Invalid(field.NewPath("options", "page_size"), int32(-1), "").WithOrigin("minimum")}, }, { "valid page_token", - &ateapipb.ListActorsRequest{Atespace: "ns1", Options: &ateapipb.ListOptions{PageToken: strings.Repeat("x", 256)}}, + &ateapi.ListActorsRequest{Atespace: "ns1", Options: &ateapi.ListOptions{PageToken: strings.Repeat("x", 256)}}, nil, }, { "too-large page_token", - &ateapipb.ListActorsRequest{Atespace: "ns1", Options: &ateapipb.ListOptions{PageToken: strings.Repeat("x", 257)}}, + &ateapi.ListActorsRequest{Atespace: "ns1", Options: &ateapi.ListOptions{PageToken: strings.Repeat("x", 257)}}, field.ErrorList{field.TooLongCharacters(field.NewPath("options", "page_token"), "", 256).WithOrigin("maxLength")}, }} for _, tt := range tests { @@ -796,8 +796,8 @@ func TestValidateUpdateActorRequest(t *testing.T) { // is scrubbed on input, we don't need to test the status field here, other // than that it is optional. TestValidateActorUpdate covers status // validation and updates. - validReq := func(actor *ateapipb.Actor, mods ...func(actor *ateapipb.UpdateActorRequest)) *ateapipb.UpdateActorRequest { - req := &ateapipb.UpdateActorRequest{ + validReq := func(actor *ateapi.Actor, mods ...func(actor *ateapi.UpdateActorRequest)) *ateapi.UpdateActorRequest { + req := &ateapi.UpdateActorRequest{ Actor: actor, } for _, m := range mods { @@ -805,9 +805,9 @@ func TestValidateUpdateActorRequest(t *testing.T) { } return req } - validActor := func(mods ...func(*ateapipb.Actor)) *ateapipb.Actor { - allMods := []func(*ateapipb.Actor){ - func(a *ateapipb.Actor) { // this needs to go first + validActor := func(mods ...func(*ateapi.Actor)) *ateapi.Actor { + allMods := []func(*ateapi.Actor){ + func(a *ateapi.Actor) { // this needs to go first a.Metadata.Uid = "12345678-1234-1234-1234-123456789abc" a.Metadata.Version = 1 }, @@ -821,7 +821,7 @@ func TestValidateUpdateActorRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.UpdateActorRequest + req *ateapi.UpdateActorRequest want field.ErrorList }{{ "valid", @@ -833,47 +833,47 @@ func TestValidateUpdateActorRequest(t *testing.T) { nil, // ignored on input }, { "missing actor", - &ateapipb.UpdateActorRequest{Actor: nil}, + &ateapi.UpdateActorRequest{Actor: nil}, field.ErrorList{field.Required(field.NewPath("actor"), "")}, }, { "missing actor.metadata", - validReq(validActor(func(a *ateapipb.Actor) { a.Metadata = nil })), + validReq(validActor(func(a *ateapi.Actor) { a.Metadata = nil })), field.ErrorList{field.Required(field.NewPath("actor", "metadata"), "")}, }, { "missing actor.metadata.atespace", - validReq(validActor(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Atespace = "" }))), + validReq(validActor(withMetadata(func(m *ateapi.ResourceMetadata) { m.Atespace = "" }))), field.ErrorList{field.Required(field.NewPath("actor", "metadata", "atespace"), "")}, }, { "invalid actor.metadata.atespace", - validReq(validActor(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Atespace = "NS1" }))), + validReq(validActor(withMetadata(func(m *ateapi.ResourceMetadata) { m.Atespace = "NS1" }))), field.ErrorList{field.Invalid(field.NewPath("actor", "metadata", "atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "missing actor.metadata.name", - validReq(validActor(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Name = "" }))), + validReq(validActor(withMetadata(func(m *ateapi.ResourceMetadata) { m.Name = "" }))), field.ErrorList{field.Required(field.NewPath("actor", "metadata", "name"), "")}, }, { "invalid actor.metadata.name", - validReq(validActor(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Name = "ID1" }))), + validReq(validActor(withMetadata(func(m *ateapi.ResourceMetadata) { m.Name = "ID1" }))), field.ErrorList{field.Invalid(field.NewPath("actor", "metadata", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "missing actor.metadata.uid precondition", - validReq(validActor(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Uid = "" }))), + validReq(validActor(withMetadata(func(m *ateapi.ResourceMetadata) { m.Uid = "" }))), nil, }, { "invalid actor.metadata.uid precondition", - validReq(validActor(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Uid = "not-a-uuid" }))), + validReq(validActor(withMetadata(func(m *ateapi.ResourceMetadata) { m.Uid = "not-a-uuid" }))), field.ErrorList{field.Invalid(field.NewPath("actor", "metadata", "uid"), "not-a-uuid", "").WithOrigin("format=k8s-uuid")}, }, { "missing actor.metadata.version precondition", - validReq(validActor(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Version = 0 }))), + validReq(validActor(withMetadata(func(m *ateapi.ResourceMetadata) { m.Version = 0 }))), nil, }, { "negative actor.metadata.version precondition", - validReq(validActor(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Version = -1 }))), + validReq(validActor(withMetadata(func(m *ateapi.ResourceMetadata) { m.Version = -1 }))), field.ErrorList{field.Invalid(field.NewPath("actor", "metadata", "version"), int64(-1), "").WithOrigin("minimum")}, }, { "missing actor.metadata.version and actor.metadata.uid", - validReq(validActor(withMetadata(func(m *ateapipb.ResourceMetadata) { + validReq(validActor(withMetadata(func(m *ateapi.ResourceMetadata) { m.Uid = "" m.Version = 0 }))), @@ -889,31 +889,31 @@ func TestValidateUpdateActorRequest(t *testing.T) { func TestValidateDeleteActorRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.DeleteActorRequest + req *ateapi.DeleteActorRequest want field.ErrorList }{{ "valid", - &ateapipb.DeleteActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}}, + &ateapi.DeleteActorRequest{Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}}, nil, }, { "missing actor", - &ateapipb.DeleteActorRequest{}, + &ateapi.DeleteActorRequest{}, field.ErrorList{field.Required(field.NewPath("actor"), "")}, }, { "missing actor.atespace", - &ateapipb.DeleteActorRequest{Actor: &ateapipb.ObjectRef{Name: "id1"}}, + &ateapi.DeleteActorRequest{Actor: &ateapi.ObjectRef{Name: "id1"}}, field.ErrorList{field.Required(field.NewPath("actor", "atespace"), "")}, }, { "invalid actor.atespace", - &ateapipb.DeleteActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "NS1", Name: "id1"}}, + &ateapi.DeleteActorRequest{Actor: &ateapi.ObjectRef{Atespace: "NS1", Name: "id1"}}, field.ErrorList{field.Invalid(field.NewPath("actor", "atespace"), "NS1", "").WithOrigin("format=k8s-short-name")}, }, { "missing actor.name", - &ateapipb.DeleteActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "ns1"}}, + &ateapi.DeleteActorRequest{Actor: &ateapi.ObjectRef{Atespace: "ns1"}}, field.ErrorList{field.Required(field.NewPath("actor", "name"), "")}, }, { "invalid actor.name", - &ateapipb.DeleteActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "ID1"}}, + &ateapi.DeleteActorRequest{Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "ID1"}}, field.ErrorList{field.Invalid(field.NewPath("actor", "name"), "ID1", "").WithOrigin("format=k8s-short-name")}, }} for _, tt := range tests { @@ -926,31 +926,31 @@ func TestValidateDeleteActorRequest(t *testing.T) { func TestValidateResumeActorRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.ResumeActorRequest + req *ateapi.ResumeActorRequest want field.ErrorList }{{ "valid", - &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}}, + &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}}, nil, }, { "missing actor", - &ateapipb.ResumeActorRequest{}, + &ateapi.ResumeActorRequest{}, field.ErrorList{field.Required(field.NewPath("actor"), "")}, }, { "missing actor.atespace", - &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Name: "id1"}}, + &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Name: "id1"}}, field.ErrorList{field.Required(field.NewPath("actor", "atespace"), "")}, }, { "invalid actor.atespace", - &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "NS1", Name: "id1"}}, + &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: "NS1", Name: "id1"}}, field.ErrorList{field.Invalid(field.NewPath("actor", "atespace"), "NS1", "").WithOrigin("format=k8s-short-name")}, }, { "missing actor.name", - &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "ns1"}}, + &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: "ns1"}}, field.ErrorList{field.Required(field.NewPath("actor", "name"), "")}, }, { "invalid actor.name", - &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "ID1"}}, + &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "ID1"}}, field.ErrorList{field.Invalid(field.NewPath("actor", "name"), "ID1", "").WithOrigin("format=k8s-short-name")}, }} for _, tt := range tests { @@ -963,65 +963,65 @@ func TestValidateResumeActorRequest(t *testing.T) { func TestValidateSuspendActorRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.SuspendActorRequest + req *ateapi.SuspendActorRequest want field.ErrorList }{{ "valid", - &ateapipb.SuspendActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}}, + &ateapi.SuspendActorRequest{Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}}, nil, }, { "missing actor", - &ateapipb.SuspendActorRequest{}, + &ateapi.SuspendActorRequest{}, field.ErrorList{field.Required(field.NewPath("actor"), "")}, }, { "missing actor.atespace", - &ateapipb.SuspendActorRequest{Actor: &ateapipb.ObjectRef{Name: "id1"}}, + &ateapi.SuspendActorRequest{Actor: &ateapi.ObjectRef{Name: "id1"}}, field.ErrorList{field.Required(field.NewPath("actor", "atespace"), "")}, }, { "invalid actor.atespace", - &ateapipb.SuspendActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "NS1", Name: "id1"}}, + &ateapi.SuspendActorRequest{Actor: &ateapi.ObjectRef{Atespace: "NS1", Name: "id1"}}, field.ErrorList{field.Invalid(field.NewPath("actor", "atespace"), "NS1", "").WithOrigin("format=k8s-short-name")}, }, { "missing actor.name", - &ateapipb.SuspendActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "ns1"}}, + &ateapi.SuspendActorRequest{Actor: &ateapi.ObjectRef{Atespace: "ns1"}}, field.ErrorList{field.Required(field.NewPath("actor", "name"), "")}, }, { "invalid actor.name", - &ateapipb.SuspendActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "ID1"}}, + &ateapi.SuspendActorRequest{Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "ID1"}}, field.ErrorList{field.Invalid(field.NewPath("actor", "name"), "ID1", "").WithOrigin("format=k8s-short-name")}, }, { "synchronous mode", - &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }, nil, }, { "asynchronous mode", - &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }, nil, }, { "mode unspecified", - &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}, - Options: &ateapipb.SuspendOptions{}, + &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, + Options: &ateapi.SuspendOptions{}, }, nil, }, { "mode negative", - &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode(-1)}, + &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode(-1)}, }, field.ErrorList{field.Invalid(field.NewPath("options", "mode"), nil, "").WithOrigin("minimum")}, }, { "mode unknown", - &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode(3)}, + &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode(3)}, }, field.ErrorList{field.Invalid(field.NewPath("options", "mode"), nil, "").WithOrigin("maximum")}, }} @@ -1036,34 +1036,34 @@ func TestValidateMintActorCertificateRequest(t *testing.T) { validUID := "3b9f1e77-2c4d-4a80-91be-6d5c8f0a7e21" tests := []struct { name string - req *ateapipb.MintActorCertificateRequest + req *ateapi.MintActorCertificateRequest want field.ErrorList }{{ "valid", - &ateapipb.MintActorCertificateRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}, + &ateapi.MintActorCertificateRequest{ + Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, ActorUid: validUID, CertificateSigningRequest: []byte("csr"), }, nil, }, { "missing actor", - &ateapipb.MintActorCertificateRequest{ + &ateapi.MintActorCertificateRequest{ ActorUid: validUID, CertificateSigningRequest: []byte("csr"), }, field.ErrorList{field.Required(field.NewPath("actor"), "")}, }, { "missing actor_uid", - &ateapipb.MintActorCertificateRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}, + &ateapi.MintActorCertificateRequest{ + Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, CertificateSigningRequest: []byte("csr"), }, field.ErrorList{field.Required(field.NewPath("actor_uid"), "")}, }, { "missing csr", - &ateapipb.MintActorCertificateRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}, + &ateapi.MintActorCertificateRequest{ + Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, ActorUid: validUID, }, field.ErrorList{field.Required(field.NewPath("certificate_signing_request"), "")}, @@ -1076,10 +1076,10 @@ func TestValidateMintActorCertificateRequest(t *testing.T) { } // validActor returns a minimal Actor which should pass input validation. -func validActor(mods ...func(*ateapipb.Actor)) *ateapipb.Actor { - a := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ns1", Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, +func validActor(mods ...func(*ateapi.Actor)) *ateapi.Actor { + a := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ns1", Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, } for _, m := range mods { m(a) @@ -1089,16 +1089,16 @@ func validActor(mods ...func(*ateapipb.Actor)) *ateapipb.Actor { // withActorMetadata returns a modifier func (see validActor) which sets // the actor's resource metadata to a valid value. -func withActorMetadata(mutate func(*ateapipb.ResourceMetadata)) func(*ateapipb.Actor) { - return func(a *ateapipb.Actor) { mutate(a.Metadata) } +func withActorMetadata(mutate func(*ateapi.ResourceMetadata)) func(*ateapi.Actor) { + return func(a *ateapi.Actor) { mutate(a.Metadata) } } // withActorStatus returns a modifier func (see validActor) which sets the // actor's status to a valid value. -func withActorStatus(mods ...func(*ateapipb.ActorStatus)) func(*ateapipb.Actor) { - return func(a *ateapipb.Actor) { - a.Status = &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, +func withActorStatus(mods ...func(*ateapi.ActorStatus)) func(*ateapi.Actor) { + return func(a *ateapi.Actor) { + a.Status = &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, } for _, m := range mods { m(a.Status) @@ -1108,9 +1108,9 @@ func withActorStatus(mods ...func(*ateapipb.ActorStatus)) func(*ateapipb.Actor) // withActorWorkerSelector returns a modifier func (see validActor) which sets // the actor's worker_selector to a valid value. -func withActorWorkerSelector(labels map[string]string) func(*ateapipb.Actor) { - return func(a *ateapipb.Actor) { - a.WorkerSelector = &ateapipb.Selector{ +func withActorWorkerSelector(labels map[string]string) func(*ateapi.Actor) { + return func(a *ateapi.Actor) { + a.WorkerSelector = &ateapi.Selector{ MatchLabels: labels, } } @@ -1118,22 +1118,22 @@ func withActorWorkerSelector(labels map[string]string) func(*ateapipb.Actor) { // withActorActorTemplate returns a modifier func (see validActor) which sets // the actor's actor_template to a valid value. -func withActorActorTemplate(atespace, name string) func(*ateapipb.Actor) { - return func(a *ateapipb.Actor) { a.ActorTemplate = &ateapipb.ObjectRef{Atespace: atespace, Name: name} } +func withActorActorTemplate(atespace, name string) func(*ateapi.Actor) { + return func(a *ateapi.Actor) { a.ActorTemplate = &ateapi.ObjectRef{Atespace: atespace, Name: name} } } // withActorSourceTag returns a modifier func (see validActor) which sets // the actor's source_tag to a valid value. -func withActorSourceTag(atespace, name string) func(*ateapipb.Actor) { - return func(a *ateapipb.Actor) { a.SourceTag = &ateapipb.ObjectRef{Atespace: atespace, Name: name} } +func withActorSourceTag(atespace, name string) func(*ateapi.Actor) { + return func(a *ateapi.Actor) { a.SourceTag = &ateapi.ObjectRef{Atespace: atespace, Name: name} } } // withActorWorkerAssignment returns a modifier func (see validActor) which sets // the actor's worker_assignment to a valid value. -func withActorWorkerAssignment(mods ...func(*ateapipb.WorkerAssignment)) func(*ateapipb.ActorStatus) { - return func(s *ateapipb.ActorStatus) { - s.WorkerAssignment = &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: "worker"}, +func withActorWorkerAssignment(mods ...func(*ateapi.WorkerAssignment)) func(*ateapi.ActorStatus) { + return func(s *ateapi.ActorStatus) { + s.WorkerAssignment = &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: "worker"}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "pod", @@ -1148,9 +1148,9 @@ func withActorWorkerAssignment(mods ...func(*ateapipb.WorkerAssignment)) func(*a } func TestValidateMintActorJWTRequest(t *testing.T) { - withExpiration := func(seconds int64) *ateapipb.MintActorJwtRequest { - return &ateapipb.MintActorJwtRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}, + withExpiration := func(seconds int64) *ateapi.MintActorJwtRequest { + return &ateapi.MintActorJwtRequest{ + Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, Audiences: []string{"https://example.com"}, ExpirationSeconds: seconds, } @@ -1158,7 +1158,7 @@ func TestValidateMintActorJWTRequest(t *testing.T) { path := field.NewPath("expiration_seconds") tests := []struct { name string - req *ateapipb.MintActorJwtRequest + req *ateapi.MintActorJwtRequest want field.ErrorList }{ {name: "minimum expiration", req: withExpiration(300)}, diff --git a/cmd/ateapi/internal/apivalidation/atespace.go b/cmd/ateapi/internal/apivalidation/atespace.go index 1e4126e9e6..22073126be 100644 --- a/cmd/ateapi/internal/apivalidation/atespace.go +++ b/cmd/ateapi/internal/apivalidation/atespace.go @@ -17,29 +17,29 @@ package apivalidation import ( "context" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "k8s.io/apimachinery/pkg/util/validation/field" ) -func ValidateCreateAtespaceRequest(ctx context.Context, req *ateapipb.CreateAtespaceRequest) field.ErrorList { +func ValidateCreateAtespaceRequest(ctx context.Context, req *ateapi.CreateAtespaceRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_CreateAtespaceRequest(ctx, op, nil, req, nil) } -func ValidateGetAtespaceRequest(ctx context.Context, req *ateapipb.GetAtespaceRequest) field.ErrorList { +func ValidateGetAtespaceRequest(ctx context.Context, req *ateapi.GetAtespaceRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_GetAtespaceRequest(ctx, op, nil, req, nil) } -func ValidateListAtespacesRequest(ctx context.Context, req *ateapipb.ListAtespacesRequest) field.ErrorList { +func ValidateListAtespacesRequest(ctx context.Context, req *ateapi.ListAtespacesRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_ListAtespacesRequest(ctx, op, nil, req, nil) } -func ValidateDeleteAtespaceRequest(ctx context.Context, req *ateapipb.DeleteAtespaceRequest) field.ErrorList { +func ValidateDeleteAtespaceRequest(ctx context.Context, req *ateapi.DeleteAtespaceRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_DeleteAtespaceRequest(ctx, op, nil, req, nil) diff --git a/cmd/ateapi/internal/apivalidation/atespace_test.go b/cmd/ateapi/internal/apivalidation/atespace_test.go index 2a338fe436..931f30a741 100644 --- a/cmd/ateapi/internal/apivalidation/atespace_test.go +++ b/cmd/ateapi/internal/apivalidation/atespace_test.go @@ -19,14 +19,14 @@ import ( "strings" "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "k8s.io/apimachinery/pkg/util/validation/field" ) func TestValidateCreateAtespaceRequest(t *testing.T) { // This test verifies validation of user input for creation. - validReq := func(atespace *ateapipb.Atespace, mods ...func(atespace *ateapipb.CreateAtespaceRequest)) *ateapipb.CreateAtespaceRequest { - req := &ateapipb.CreateAtespaceRequest{ + validReq := func(atespace *ateapi.Atespace, mods ...func(atespace *ateapi.CreateAtespaceRequest)) *ateapi.CreateAtespaceRequest { + req := &ateapi.CreateAtespaceRequest{ Atespace: atespace, } for _, m := range mods { @@ -38,7 +38,7 @@ func TestValidateCreateAtespaceRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.CreateAtespaceRequest + req *ateapi.CreateAtespaceRequest want field.ErrorList }{{ "valid", @@ -46,23 +46,23 @@ func TestValidateCreateAtespaceRequest(t *testing.T) { nil, }, { "missing atespace", - &ateapipb.CreateAtespaceRequest{Atespace: nil}, + &ateapi.CreateAtespaceRequest{Atespace: nil}, field.ErrorList{field.Required(field.NewPath("atespace"), "")}, }, { "missing atespace.metadata", - validReq(validAtespace(func(a *ateapipb.Atespace) { a.Metadata = nil })), + validReq(validAtespace(func(a *ateapi.Atespace) { a.Metadata = nil })), field.ErrorList{field.Required(field.NewPath("atespace", "metadata"), "")}, }, { "atespace.metadata.atespace must be empty", - validReq(validAtespace(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Atespace = "as" }))), + validReq(validAtespace(withMetadata(func(m *ateapi.ResourceMetadata) { m.Atespace = "as" }))), field.ErrorList{field.Forbidden(field.NewPath("atespace", "metadata", "atespace"), "")}, }, { "missing atespace.metadata.name", - validReq(validAtespace(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Name = "" }))), + validReq(validAtespace(withMetadata(func(m *ateapi.ResourceMetadata) { m.Name = "" }))), field.ErrorList{field.Required(field.NewPath("atespace", "metadata", "name"), "")}, }, { "invalid metadata.name", - validReq(validAtespace(withMetadata(func(m *ateapipb.ResourceMetadata) { m.Name = "invalid value" }))), + validReq(validAtespace(withMetadata(func(m *ateapi.ResourceMetadata) { m.Name = "invalid value" }))), field.ErrorList{field.Invalid(field.NewPath("atespace", "metadata", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }} for _, tt := range tests { @@ -74,9 +74,9 @@ func TestValidateCreateAtespaceRequest(t *testing.T) { func TestValidateGetAtespaceRequest(t *testing.T) { // This test verifies validation of user input for get. - validReq := func(mods ...func(atespace *ateapipb.GetAtespaceRequest)) *ateapipb.GetAtespaceRequest { - req := &ateapipb.GetAtespaceRequest{ - Atespace: &ateapipb.ObjectRef{Name: "team1"}, + validReq := func(mods ...func(atespace *ateapi.GetAtespaceRequest)) *ateapi.GetAtespaceRequest { + req := &ateapi.GetAtespaceRequest{ + Atespace: &ateapi.ObjectRef{Name: "team1"}, } for _, m := range mods { m(req) @@ -86,7 +86,7 @@ func TestValidateGetAtespaceRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.GetAtespaceRequest + req *ateapi.GetAtespaceRequest want field.ErrorList }{{ "valid", @@ -94,19 +94,19 @@ func TestValidateGetAtespaceRequest(t *testing.T) { nil, }, { "missing atespace", - &ateapipb.GetAtespaceRequest{}, + &ateapi.GetAtespaceRequest{}, field.ErrorList{field.Required(field.NewPath("atespace"), "")}, }, { "atespace.atespace must be empty", - validReq(func(r *ateapipb.GetAtespaceRequest) { r.Atespace.Atespace = "as" }), + validReq(func(r *ateapi.GetAtespaceRequest) { r.Atespace.Atespace = "as" }), field.ErrorList{field.Forbidden(field.NewPath("atespace", "atespace"), "")}, }, { "missing atespace.name", - validReq(func(r *ateapipb.GetAtespaceRequest) { r.Atespace.Name = "" }), + validReq(func(r *ateapi.GetAtespaceRequest) { r.Atespace.Name = "" }), field.ErrorList{field.Required(field.NewPath("atespace", "name"), "")}, }, { "invalid atespace.name", - validReq(func(r *ateapipb.GetAtespaceRequest) { r.Atespace.Name = "invalid value" }), + validReq(func(r *ateapi.GetAtespaceRequest) { r.Atespace.Name = "invalid value" }), field.ErrorList{field.Invalid(field.NewPath("atespace", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }} for _, tt := range tests { @@ -118,8 +118,8 @@ func TestValidateGetAtespaceRequest(t *testing.T) { func TestValidateListAtespacesRequest(t *testing.T) { // This test verifies validation of user input for list. - validReq := func(mods ...func(atespace *ateapipb.ListAtespacesRequest)) *ateapipb.ListAtespacesRequest { - req := &ateapipb.ListAtespacesRequest{ /* default values */ } + validReq := func(mods ...func(atespace *ateapi.ListAtespacesRequest)) *ateapi.ListAtespacesRequest { + req := &ateapi.ListAtespacesRequest{ /* default values */ } for _, m := range mods { m(req) } @@ -128,7 +128,7 @@ func TestValidateListAtespacesRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.ListAtespacesRequest + req *ateapi.ListAtespacesRequest want field.ErrorList }{{ "valid, no page_size", @@ -136,22 +136,22 @@ func TestValidateListAtespacesRequest(t *testing.T) { nil, }, { "valid, positive page_size", - validReq(func(r *ateapipb.ListAtespacesRequest) { r.Options = &ateapipb.ListOptions{PageSize: 10} }), + validReq(func(r *ateapi.ListAtespacesRequest) { r.Options = &ateapi.ListOptions{PageSize: 10} }), nil, }, { "negative page_size", - validReq(func(r *ateapipb.ListAtespacesRequest) { r.Options = &ateapipb.ListOptions{PageSize: -1} }), + validReq(func(r *ateapi.ListAtespacesRequest) { r.Options = &ateapi.ListOptions{PageSize: -1} }), field.ErrorList{field.Invalid(field.NewPath("options", "page_size"), int32(-1), "").WithOrigin("minimum")}, }, { "valid page_token", - validReq(func(r *ateapipb.ListAtespacesRequest) { - r.Options = &ateapipb.ListOptions{PageToken: strings.Repeat("x", 256)} + validReq(func(r *ateapi.ListAtespacesRequest) { + r.Options = &ateapi.ListOptions{PageToken: strings.Repeat("x", 256)} }), nil, }, { "too-large page_token", - validReq(func(r *ateapipb.ListAtespacesRequest) { - r.Options = &ateapipb.ListOptions{PageToken: strings.Repeat("x", 257)} + validReq(func(r *ateapi.ListAtespacesRequest) { + r.Options = &ateapi.ListOptions{PageToken: strings.Repeat("x", 257)} }), field.ErrorList{field.TooLongCharacters(field.NewPath("options", "page_token"), "", 256).WithOrigin("maxLength")}, }} @@ -164,9 +164,9 @@ func TestValidateListAtespacesRequest(t *testing.T) { func TestValidateDeleteAtespaceRequest(t *testing.T) { // This test verifies validation of user input for delete. - validReq := func(mods ...func(atespace *ateapipb.DeleteAtespaceRequest)) *ateapipb.DeleteAtespaceRequest { - req := &ateapipb.DeleteAtespaceRequest{ - Atespace: &ateapipb.ObjectRef{Name: "team1"}, + validReq := func(mods ...func(atespace *ateapi.DeleteAtespaceRequest)) *ateapi.DeleteAtespaceRequest { + req := &ateapi.DeleteAtespaceRequest{ + Atespace: &ateapi.ObjectRef{Name: "team1"}, } for _, m := range mods { m(req) @@ -176,7 +176,7 @@ func TestValidateDeleteAtespaceRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.DeleteAtespaceRequest + req *ateapi.DeleteAtespaceRequest want field.ErrorList }{{ "valid", @@ -184,19 +184,19 @@ func TestValidateDeleteAtespaceRequest(t *testing.T) { nil, }, { "missing atespace", - &ateapipb.DeleteAtespaceRequest{Atespace: nil}, + &ateapi.DeleteAtespaceRequest{Atespace: nil}, field.ErrorList{field.Required(field.NewPath("atespace"), "")}, }, { "atespace.atespace must be empty", - validReq(func(r *ateapipb.DeleteAtespaceRequest) { r.Atespace.Atespace = "as" }), + validReq(func(r *ateapi.DeleteAtespaceRequest) { r.Atespace.Atespace = "as" }), field.ErrorList{field.Forbidden(field.NewPath("atespace", "atespace"), "")}, }, { "missing atespace.name", - validReq(func(r *ateapipb.DeleteAtespaceRequest) { r.Atespace.Name = "" }), + validReq(func(r *ateapi.DeleteAtespaceRequest) { r.Atespace.Name = "" }), field.ErrorList{field.Required(field.NewPath("atespace", "name"), "")}, }, { "invalid atespace.name", - validReq(func(r *ateapipb.DeleteAtespaceRequest) { r.Atespace.Name = "invalid value" }), + validReq(func(r *ateapi.DeleteAtespaceRequest) { r.Atespace.Name = "invalid value" }), field.ErrorList{field.Invalid(field.NewPath("atespace", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }} for _, tt := range tests { @@ -207,9 +207,9 @@ func TestValidateDeleteAtespaceRequest(t *testing.T) { } // validAtespace returns a minimal Atespace which should pass input validation. -func validAtespace(mods ...func(*ateapipb.Atespace)) *ateapipb.Atespace { - a := &ateapipb.Atespace{ - Metadata: &ateapipb.ResourceMetadata{Name: "team1"}, +func validAtespace(mods ...func(*ateapi.Atespace)) *ateapi.Atespace { + a := &ateapi.Atespace{ + Metadata: &ateapi.ResourceMetadata{Name: "team1"}, } for _, m := range mods { m(a) @@ -219,6 +219,6 @@ func validAtespace(mods ...func(*ateapipb.Atespace)) *ateapipb.Atespace { // withAtespaceMetadata returns a modifier func (see validAtespace) which sets // the atespace's resource metadata to a valid value. -func withAtespaceMetadata(mutate func(*ateapipb.ResourceMetadata)) func(*ateapipb.Atespace) { - return func(a *ateapipb.Atespace) { mutate(a.Metadata) } +func withAtespaceMetadata(mutate func(*ateapi.ResourceMetadata)) func(*ateapi.Atespace) { + return func(a *ateapi.Atespace) { mutate(a.Metadata) } } diff --git a/cmd/ateapi/internal/apivalidation/common.go b/cmd/ateapi/internal/apivalidation/common.go index 8ebf87cbca..a538a51559 100644 --- a/cmd/ateapi/internal/apivalidation/common.go +++ b/cmd/ateapi/internal/apivalidation/common.go @@ -20,9 +20,9 @@ import ( "net/netip" "github.com/spiffe/go-spiffe/v2/spiffeid" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "k8s.io/apimachinery/pkg/api/operation" "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" @@ -71,7 +71,7 @@ func optionsFor(ctx context.Context) map[string]bool { // not precede create_time. Both fields are scrubbed from input, so a // violation here is a server stamping bug surfaced by the final-object // validation pass, not a client error. -func ValidateCustom_ResourceMetadata(_ context.Context, _ operation.Operation, fldPath *field.Path, obj, _ *ateapipb.ResourceMetadata) field.ErrorList { +func ValidateCustom_ResourceMetadata(_ context.Context, _ operation.Operation, fldPath *field.Path, obj, _ *ateapi.ResourceMetadata) field.ErrorList { var errs field.ErrorList createTimeValid := false if ct := obj.GetCreateTime(); ct != nil { diff --git a/cmd/ateapi/internal/apivalidation/doc.go b/cmd/ateapi/internal/apivalidation/doc.go index 393bfea63a..4b755d741c 100644 --- a/cmd/ateapi/internal/apivalidation/doc.go +++ b/cmd/ateapi/internal/apivalidation/doc.go @@ -16,7 +16,7 @@ // work. // +k8s:validation-gen=TypesWithSuffix=Request -// +k8s:validation-gen-input=go.ate.dev/substrate/pkg/proto/ateapipb +// +k8s:validation-gen-input=go.ate.dev/substrate/api/ateapi/v1 // +k8s:validation-gen-scheme-registry=nil // +k8s:validation-gen-deep-equal-func=ateDeepEqual diff --git a/cmd/ateapi/internal/apivalidation/egress_policy.go b/cmd/ateapi/internal/apivalidation/egress_policy.go index 4fa367ede0..fefd33f0c6 100644 --- a/cmd/ateapi/internal/apivalidation/egress_policy.go +++ b/cmd/ateapi/internal/apivalidation/egress_policy.go @@ -20,47 +20,47 @@ import ( "net/url" "strings" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/egresspolicy" - "go.ate.dev/substrate/pkg/proto/ateapipb" "k8s.io/apimachinery/pkg/api/operation" "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" ) -func ValidateCreateActorEgressPolicyRequest(ctx context.Context, req *ateapipb.CreateActorEgressPolicyRequest) field.ErrorList { +func ValidateCreateActorEgressPolicyRequest(ctx context.Context, req *ateapi.CreateActorEgressPolicyRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_CreateActorEgressPolicyRequest(ctx, op, nil, req, nil) } -func ValidateGetActorEgressPolicyRequest(ctx context.Context, req *ateapipb.GetActorEgressPolicyRequest) field.ErrorList { +func ValidateGetActorEgressPolicyRequest(ctx context.Context, req *ateapi.GetActorEgressPolicyRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_GetActorEgressPolicyRequest(ctx, op, nil, req, nil) } -func ValidateUpdateActorEgressPolicyRequest(ctx context.Context, req *ateapipb.UpdateActorEgressPolicyRequest) field.ErrorList { +func ValidateUpdateActorEgressPolicyRequest(ctx context.Context, req *ateapi.UpdateActorEgressPolicyRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_UpdateActorEgressPolicyRequest(ctx, op, nil, req, nil) } -func ValidateDeleteActorEgressPolicyRequest(ctx context.Context, req *ateapipb.DeleteActorEgressPolicyRequest) field.ErrorList { +func ValidateDeleteActorEgressPolicyRequest(ctx context.Context, req *ateapi.DeleteActorEgressPolicyRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_DeleteActorEgressPolicyRequest(ctx, op, nil, req, nil) } -func ValidateEgressPolicyUpdate(ctx context.Context, p *field.Path, newVal, oldVal *ateapipb.EgressPolicy) field.ErrorList { +func ValidateEgressPolicyUpdate(ctx context.Context, p *field.Path, newVal, oldVal *ateapi.EgressPolicy) field.ErrorList { op := MakeUpdateOp(ctx) return Validate_EgressPolicy(ctx, op, p, newVal, oldVal) } -func ValidateCustom_CreateActorEgressPolicyRequest(_ context.Context, _ operation.Operation, p *field.Path, req, _ *ateapipb.CreateActorEgressPolicyRequest) field.ErrorList { +func ValidateCustom_CreateActorEgressPolicyRequest(_ context.Context, _ operation.Operation, p *field.Path, req, _ *ateapi.CreateActorEgressPolicyRequest) field.ErrorList { return validateEgressPolicyParentAtespace(req.GetActor(), req.GetEgressPolicy(), p) } -func ValidateCustom_UpdateActorEgressPolicyRequest(_ context.Context, _ operation.Operation, p *field.Path, req, _ *ateapipb.UpdateActorEgressPolicyRequest) field.ErrorList { +func ValidateCustom_UpdateActorEgressPolicyRequest(_ context.Context, _ operation.Operation, p *field.Path, req, _ *ateapi.UpdateActorEgressPolicyRequest) field.ErrorList { return validateEgressPolicyParentAtespace(req.GetActor(), req.GetEgressPolicy(), p) } -func validateEgressPolicyParentAtespace(actor *ateapipb.ObjectRef, policy *ateapipb.EgressPolicy, p *field.Path) field.ErrorList { +func validateEgressPolicyParentAtespace(actor *ateapi.ObjectRef, policy *ateapi.EgressPolicy, p *field.Path) field.ErrorList { if actor == nil || actor.Atespace == "" { return nil // regular DV will handle it } @@ -77,7 +77,7 @@ func validateEgressPolicyParentAtespace(actor *ateapipb.ObjectRef, policy *ateap return nil } -func ValidateCustom_EgressPolicy_Metadata(_ context.Context, _ operation.Operation, root *field.Path, meta, _ *ateapipb.ResourceMetadata) field.ErrorList { +func ValidateCustom_EgressPolicy_Metadata(_ context.Context, _ operation.Operation, root *field.Path, meta, _ *ateapi.ResourceMetadata) field.ErrorList { return validateSingletonName(root.Child("name"), meta.GetName()) } @@ -93,7 +93,7 @@ func ValidateCustom_DeleteActorEgressPolicyRequest_Name(_ context.Context, _ ope // and a port, whatever their protocols: the gateway would have no way to pick // one. Defaults are applied before validation, so an http rule left on 80 // and an https rule left on 443 never tie. -func ValidateCustom_EgressPolicy_Rules(_ context.Context, _ operation.Operation, p *field.Path, rules, _ []*ateapipb.EgressRule) field.ErrorList { +func ValidateCustom_EgressPolicy_Rules(_ context.Context, _ operation.Operation, p *field.Path, rules, _ []*ateapi.EgressRule) field.ErrorList { type key struct { pattern string port portKey @@ -126,13 +126,13 @@ func ValidateCustom_EgressPolicy_Rules(_ context.Context, _ operation.Operation, return errs } -func ValidateCustom_EgressPolicyTemplate_Rules(ctx context.Context, op operation.Operation, p *field.Path, rules, oldRules []*ateapipb.EgressRule) field.ErrorList { +func ValidateCustom_EgressPolicyTemplate_Rules(ctx context.Context, op operation.Operation, p *field.Path, rules, oldRules []*ateapi.EgressRule) field.ErrorList { return ValidateCustom_EgressPolicy_Rules(ctx, op, p, rules, oldRules) } // ruleMatchFields is what a rule matches on: the union member, its hostnames, // and its ports. Everything is empty for a rule that sets no member. -func ruleMatchFields(rule *ateapipb.EgressRule) (member string, hostnames []string, ports *ateapipb.Ports) { +func ruleMatchFields(rule *ateapi.EgressRule) (member string, hostnames []string, ports *ateapi.Ports) { switch { case rule.GetHttp() != nil: return "http", rule.GetHttp().GetHostnames(), rule.GetHttp().GetPorts() @@ -151,7 +151,7 @@ type portKey struct { all bool } -func portKeysOf(ports *ateapipb.Ports) []portKey { +func portKeysOf(ports *ateapi.Ports) []portKey { if ports.GetAll() != nil { return []portKey{{all: true}} } @@ -181,7 +181,7 @@ func ValidateCustom_TlsPassthroughRule_Hostnames(_ context.Context, _ operation. return validateHostnamePatterns(patterns, p) } -func ValidateCustom_HttpRuleEffects(_ context.Context, _ operation.Operation, p *field.Path, effects, _ *ateapipb.HttpRuleEffects) field.ErrorList { +func ValidateCustom_HttpRuleEffects(_ context.Context, _ operation.Operation, p *field.Path, effects, _ *ateapi.HttpRuleEffects) field.ErrorList { var errs field.ErrorList if len(effects.GetReplaceHeaders()) == 0 { errs = append(errs, field.Required(p, "at least one effect must be specified")) @@ -189,7 +189,7 @@ func ValidateCustom_HttpRuleEffects(_ context.Context, _ operation.Operation, p return errs } -func ValidateCustom_HttpRuleEffects_ReplaceHeaders(_ context.Context, _ operation.Operation, p *field.Path, injections, _ []*ateapipb.CredentialHeader) field.ErrorList { +func ValidateCustom_HttpRuleEffects_ReplaceHeaders(_ context.Context, _ operation.Operation, p *field.Path, injections, _ []*ateapi.CredentialHeader) field.ErrorList { var errs field.ErrorList seenHeaders := map[string]bool{} for i, inj := range injections { diff --git a/cmd/ateapi/internal/apivalidation/egress_policy_test.go b/cmd/ateapi/internal/apivalidation/egress_policy_test.go index d6f0fa3701..508c6ce564 100644 --- a/cmd/ateapi/internal/apivalidation/egress_policy_test.go +++ b/cmd/ateapi/internal/apivalidation/egress_policy_test.go @@ -20,21 +20,21 @@ import ( "strings" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/defaults" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" "k8s.io/apimachinery/pkg/util/validation/field" ) -func validEgressPolicy() *ateapipb.EgressPolicy { - return &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "default"}, - Rules: []*ateapipb.EgressRule{{ - Http: &ateapipb.HttpRule{ +func validEgressPolicy() *ateapi.EgressPolicy { + return &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "default"}, + Rules: []*ateapi.EgressRule{{ + Http: &ateapi.HttpRule{ Hostnames: []string{"api.example.com"}, - Effects: &ateapipb.HttpRuleEffects{ - ReplaceHeaders: []*ateapipb.CredentialHeader{{ + Effects: &ateapi.HttpRuleEffects{ + ReplaceHeaders: []*ateapi.CredentialHeader{{ Header: "Authorization", Prefix: "Bearer ", CredentialUri: "ate-secret://kubernetes.io/provider/ns/name", @@ -47,32 +47,32 @@ func validEgressPolicy() *ateapipb.EgressPolicy { // actorJWTHeader is an Authorization header replaced with a 900-second actor // JWT for audiences. -func actorJWTHeader(audiences ...string) *ateapipb.CredentialHeader { - return &ateapipb.CredentialHeader{ +func actorJWTHeader(audiences ...string) *ateapi.CredentialHeader { + return &ateapi.CredentialHeader{ Header: "Authorization", Prefix: "Bearer ", - ActorJwt: &ateapipb.ActorJwtSource{Audiences: audiences, ExpirationSeconds: 900}, + ActorJwt: &ateapi.ActorJwtSource{Audiences: audiences, ExpirationSeconds: 900}, } } func TestValidateCreateActorEgressPolicyRequest(t *testing.T) { - validReq := func() *ateapipb.CreateActorEgressPolicyRequest { - return &ateapipb.CreateActorEgressPolicyRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor"}, + validReq := func() *ateapi.CreateActorEgressPolicyRequest { + return &ateapi.CreateActorEgressPolicyRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor"}, EgressPolicy: validEgressPolicy(), } } tests := []struct { name string - req *ateapipb.CreateActorEgressPolicyRequest + req *ateapi.CreateActorEgressPolicyRequest want field.ErrorList }{{ name: "valid", req: validReq(), }, { name: "missing actor", - req: func() *ateapipb.CreateActorEgressPolicyRequest { + req: func() *ateapi.CreateActorEgressPolicyRequest { r := validReq() r.Actor = nil return r @@ -82,7 +82,7 @@ func TestValidateCreateActorEgressPolicyRequest(t *testing.T) { }, }, { name: "missing actor atespace", - req: func() *ateapipb.CreateActorEgressPolicyRequest { + req: func() *ateapi.CreateActorEgressPolicyRequest { r := validReq() r.Actor.Atespace = "" return r @@ -92,7 +92,7 @@ func TestValidateCreateActorEgressPolicyRequest(t *testing.T) { }, }, { name: "invalid actor atespace", - req: func() *ateapipb.CreateActorEgressPolicyRequest { + req: func() *ateapi.CreateActorEgressPolicyRequest { r := validReq() r.Actor.Atespace = "invalid value" return r @@ -103,7 +103,7 @@ func TestValidateCreateActorEgressPolicyRequest(t *testing.T) { }, }, { name: "missing actor name", - req: func() *ateapipb.CreateActorEgressPolicyRequest { + req: func() *ateapi.CreateActorEgressPolicyRequest { r := validReq() r.Actor.Name = "" return r @@ -113,7 +113,7 @@ func TestValidateCreateActorEgressPolicyRequest(t *testing.T) { }, }, { name: "invalid actor name", - req: func() *ateapipb.CreateActorEgressPolicyRequest { + req: func() *ateapi.CreateActorEgressPolicyRequest { r := validReq() r.Actor.Name = "invalid value" return r @@ -123,7 +123,7 @@ func TestValidateCreateActorEgressPolicyRequest(t *testing.T) { }, }, { name: "missing policy", - req: func() *ateapipb.CreateActorEgressPolicyRequest { + req: func() *ateapi.CreateActorEgressPolicyRequest { r := validReq() r.EgressPolicy = nil return r @@ -133,7 +133,7 @@ func TestValidateCreateActorEgressPolicyRequest(t *testing.T) { }, }, { name: "missing metadata", - req: func() *ateapipb.CreateActorEgressPolicyRequest { + req: func() *ateapi.CreateActorEgressPolicyRequest { r := validReq() r.EgressPolicy.Metadata = nil return r @@ -143,7 +143,7 @@ func TestValidateCreateActorEgressPolicyRequest(t *testing.T) { }, }, { name: "missing policy atespace", - req: func() *ateapipb.CreateActorEgressPolicyRequest { + req: func() *ateapi.CreateActorEgressPolicyRequest { r := validReq() r.EgressPolicy.Metadata.Atespace = "" return r @@ -153,7 +153,7 @@ func TestValidateCreateActorEgressPolicyRequest(t *testing.T) { }, }, { name: "missing default name", - req: func() *ateapipb.CreateActorEgressPolicyRequest { + req: func() *ateapi.CreateActorEgressPolicyRequest { r := validReq() r.EgressPolicy.Metadata.Name = "" return r @@ -163,7 +163,7 @@ func TestValidateCreateActorEgressPolicyRequest(t *testing.T) { }, }, { name: "wrong policy name", - req: func() *ateapipb.CreateActorEgressPolicyRequest { + req: func() *ateapi.CreateActorEgressPolicyRequest { r := validReq() r.EgressPolicy.Metadata.Name = "other" return r @@ -173,7 +173,7 @@ func TestValidateCreateActorEgressPolicyRequest(t *testing.T) { }, }, { name: "mismatched policy atespace", - req: func() *ateapipb.CreateActorEgressPolicyRequest { + req: func() *ateapi.CreateActorEgressPolicyRequest { r := validReq() r.EgressPolicy.Metadata.Atespace = "other" return r @@ -190,28 +190,28 @@ func TestValidateCreateActorEgressPolicyRequest(t *testing.T) { } func TestValidateGetActorEgressPolicyRequest(t *testing.T) { - validReq := func() *ateapipb.GetActorEgressPolicyRequest { - return &ateapipb.GetActorEgressPolicyRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor"}, + validReq := func() *ateapi.GetActorEgressPolicyRequest { + return &ateapi.GetActorEgressPolicyRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor"}, Name: resources.SingletonName, } } tests := []struct { name string - req *ateapipb.GetActorEgressPolicyRequest + req *ateapi.GetActorEgressPolicyRequest want field.ErrorList }{{ name: "valid", req: validReq(), }, { name: "missing actor", - req: &ateapipb.GetActorEgressPolicyRequest{Name: resources.SingletonName}, + req: &ateapi.GetActorEgressPolicyRequest{Name: resources.SingletonName}, want: field.ErrorList{ field.Required(field.NewPath("actor"), ""), }, }, { name: "missing atespace", - req: func() *ateapipb.GetActorEgressPolicyRequest { + req: func() *ateapi.GetActorEgressPolicyRequest { r := validReq() r.Actor.Atespace = "" return r @@ -221,7 +221,7 @@ func TestValidateGetActorEgressPolicyRequest(t *testing.T) { }, }, { name: "invalid atespace", - req: func() *ateapipb.GetActorEgressPolicyRequest { + req: func() *ateapi.GetActorEgressPolicyRequest { r := validReq() r.Actor.Atespace = "invalid value" return r @@ -231,7 +231,7 @@ func TestValidateGetActorEgressPolicyRequest(t *testing.T) { }, }, { name: "missing name", - req: func() *ateapipb.GetActorEgressPolicyRequest { + req: func() *ateapi.GetActorEgressPolicyRequest { r := validReq() r.Actor.Name = "" return r @@ -241,7 +241,7 @@ func TestValidateGetActorEgressPolicyRequest(t *testing.T) { }, }, { name: "invalid name", - req: func() *ateapipb.GetActorEgressPolicyRequest { + req: func() *ateapi.GetActorEgressPolicyRequest { r := validReq() r.Actor.Name = "invalid value" return r @@ -251,7 +251,7 @@ func TestValidateGetActorEgressPolicyRequest(t *testing.T) { }, }, { name: "missing singleton name", - req: func() *ateapipb.GetActorEgressPolicyRequest { + req: func() *ateapi.GetActorEgressPolicyRequest { r := validReq() r.Name = "" return r @@ -261,7 +261,7 @@ func TestValidateGetActorEgressPolicyRequest(t *testing.T) { }, }, { name: "wrong singleton name", - req: func() *ateapipb.GetActorEgressPolicyRequest { + req: func() *ateapi.GetActorEgressPolicyRequest { r := validReq() r.Name = "other" return r @@ -278,22 +278,22 @@ func TestValidateGetActorEgressPolicyRequest(t *testing.T) { } func TestValidateUpdateActorEgressPolicyRequest(t *testing.T) { - validReq := func() *ateapipb.UpdateActorEgressPolicyRequest { - return &ateapipb.UpdateActorEgressPolicyRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor"}, + validReq := func() *ateapi.UpdateActorEgressPolicyRequest { + return &ateapi.UpdateActorEgressPolicyRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor"}, EgressPolicy: validEgressPolicy(), } } tests := []struct { name string - req *ateapipb.UpdateActorEgressPolicyRequest + req *ateapi.UpdateActorEgressPolicyRequest want field.ErrorList }{{ name: "valid", req: validReq(), }, { name: "missing actor", - req: func() *ateapipb.UpdateActorEgressPolicyRequest { + req: func() *ateapi.UpdateActorEgressPolicyRequest { r := validReq() r.Actor = nil return r @@ -303,7 +303,7 @@ func TestValidateUpdateActorEgressPolicyRequest(t *testing.T) { }, }, { name: "missing policy", - req: func() *ateapipb.UpdateActorEgressPolicyRequest { + req: func() *ateapi.UpdateActorEgressPolicyRequest { r := validReq() r.EgressPolicy = nil return r @@ -313,7 +313,7 @@ func TestValidateUpdateActorEgressPolicyRequest(t *testing.T) { }, }, { name: "mismatched atespace", - req: func() *ateapipb.UpdateActorEgressPolicyRequest { + req: func() *ateapi.UpdateActorEgressPolicyRequest { r := validReq() r.EgressPolicy.Metadata.Atespace = "other" return r @@ -323,7 +323,7 @@ func TestValidateUpdateActorEgressPolicyRequest(t *testing.T) { }, }, { name: "invalid rule", - req: func() *ateapipb.UpdateActorEgressPolicyRequest { + req: func() *ateapi.UpdateActorEgressPolicyRequest { r := validReq() r.EgressPolicy.Rules[0].Http.Hostnames = nil return r @@ -340,28 +340,28 @@ func TestValidateUpdateActorEgressPolicyRequest(t *testing.T) { } func TestValidateDeleteActorEgressPolicyRequest(t *testing.T) { - validReq := func() *ateapipb.DeleteActorEgressPolicyRequest { - return &ateapipb.DeleteActorEgressPolicyRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor"}, + validReq := func() *ateapi.DeleteActorEgressPolicyRequest { + return &ateapi.DeleteActorEgressPolicyRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor"}, Name: resources.SingletonName, } } tests := []struct { name string - req *ateapipb.DeleteActorEgressPolicyRequest + req *ateapi.DeleteActorEgressPolicyRequest want field.ErrorList }{{ name: "valid", req: validReq(), }, { name: "missing actor", - req: &ateapipb.DeleteActorEgressPolicyRequest{Name: resources.SingletonName}, + req: &ateapi.DeleteActorEgressPolicyRequest{Name: resources.SingletonName}, want: field.ErrorList{ field.Required(field.NewPath("actor"), ""), }, }, { name: "missing atespace", - req: func() *ateapipb.DeleteActorEgressPolicyRequest { + req: func() *ateapi.DeleteActorEgressPolicyRequest { r := validReq() r.Actor.Atespace = "" return r @@ -371,7 +371,7 @@ func TestValidateDeleteActorEgressPolicyRequest(t *testing.T) { }, }, { name: "invalid atespace", - req: func() *ateapipb.DeleteActorEgressPolicyRequest { + req: func() *ateapi.DeleteActorEgressPolicyRequest { r := validReq() r.Actor.Atespace = "invalid value" return r @@ -381,7 +381,7 @@ func TestValidateDeleteActorEgressPolicyRequest(t *testing.T) { }, }, { name: "missing name", - req: func() *ateapipb.DeleteActorEgressPolicyRequest { + req: func() *ateapi.DeleteActorEgressPolicyRequest { r := validReq() r.Actor.Name = "" return r @@ -391,7 +391,7 @@ func TestValidateDeleteActorEgressPolicyRequest(t *testing.T) { }, }, { name: "invalid name", - req: func() *ateapipb.DeleteActorEgressPolicyRequest { + req: func() *ateapi.DeleteActorEgressPolicyRequest { r := validReq() r.Actor.Name = "invalid value" return r @@ -401,7 +401,7 @@ func TestValidateDeleteActorEgressPolicyRequest(t *testing.T) { }, }, { name: "missing singleton name", - req: func() *ateapipb.DeleteActorEgressPolicyRequest { + req: func() *ateapi.DeleteActorEgressPolicyRequest { r := validReq() r.Name = "" return r @@ -411,7 +411,7 @@ func TestValidateDeleteActorEgressPolicyRequest(t *testing.T) { }, }, { name: "wrong singleton name", - req: func() *ateapipb.DeleteActorEgressPolicyRequest { + req: func() *ateapi.DeleteActorEgressPolicyRequest { r := validReq() r.Name = "other" return r @@ -436,39 +436,39 @@ func TestValidateEgressPolicyRules(t *testing.T) { ports := httpRule.Child("ports") staticHeader := httpRule.Child("effects", "replace_headers").Index(0) const badPattern = `must be a DNS hostname, optionally with a complete leftmost-label wildcard, or "*"` - validReq := func() *ateapipb.CreateActorEgressPolicyRequest { - return &ateapipb.CreateActorEgressPolicyRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor"}, + validReq := func() *ateapi.CreateActorEgressPolicyRequest { + return &ateapi.CreateActorEgressPolicyRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor"}, EgressPolicy: validEgressPolicy(), } } - withoutEffects := func(p *ateapipb.EgressPolicy) { p.Rules[0].Http.Effects = nil } - trivialHTTPRule := func(hostname string) *ateapipb.EgressRule { - return &ateapipb.EgressRule{Http: &ateapipb.HttpRule{Hostnames: []string{hostname}}} + withoutEffects := func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects = nil } + trivialHTTPRule := func(hostname string) *ateapi.EgressRule { + return &ateapi.EgressRule{Http: &ateapi.HttpRule{Hostnames: []string{hostname}}} } - httpsRule := func(ports *ateapipb.Ports, patterns ...string) *ateapipb.EgressRule { - return &ateapipb.EgressRule{Https: &ateapipb.HttpsRule{Hostnames: patterns, Ports: ports}} + httpsRule := func(ports *ateapi.Ports, patterns ...string) *ateapi.EgressRule { + return &ateapi.EgressRule{Https: &ateapi.HttpsRule{Hostnames: patterns, Ports: ports}} } - passthroughRule := func(ports *ateapipb.Ports, patterns ...string) *ateapipb.EgressRule { - return &ateapipb.EgressRule{TlsPassthrough: &ateapipb.TlsPassthroughRule{Hostnames: patterns, Ports: ports}} + passthroughRule := func(ports *ateapi.Ports, patterns ...string) *ateapi.EgressRule { + return &ateapi.EgressRule{TlsPassthrough: &ateapi.TlsPassthroughRule{Hostnames: patterns, Ports: ports}} } - portNumbers := func(numbers ...int32) *ateapipb.Ports { return &ateapipb.Ports{Numbers: numbers} } - allPorts := func() *ateapipb.Ports { return &ateapipb.Ports{All: &ateapipb.AllPorts{}} } + portNumbers := func(numbers ...int32) *ateapi.Ports { return &ateapi.Ports{Numbers: numbers} } + allPorts := func() *ateapi.Ports { return &ateapi.Ports{All: &ateapi.AllPorts{}} } tests := []struct { name string - mutate func(*ateapipb.EgressPolicy) + mutate func(*ateapi.EgressPolicy) want field.ErrorList }{{ name: "valid", }, { name: "no rules", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules = nil }, }, { name: "many rules", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules = nil for i := range 256 { p.Rules = append(p.Rules, trivialHTTPRule(fmt.Sprintf("api%d.example.com", i))) @@ -476,7 +476,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "too many rules", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules = nil for i := range 257 { p.Rules = append(p.Rules, trivialHTTPRule(fmt.Sprintf("api%d.example.com", i))) @@ -487,7 +487,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "nil rule", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0] = nil }, want: field.ErrorList{ @@ -495,33 +495,33 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "no protocol", - mutate: func(p *ateapipb.EgressPolicy) { - p.Rules[0] = &ateapipb.EgressRule{} + mutate: func(p *ateapi.EgressPolicy) { + p.Rules[0] = &ateapi.EgressRule{} }, want: field.ErrorList{ field.Invalid(rule, nil, "one of").WithOrigin("union"), }, }, { name: "two protocols", - mutate: func(p *ateapipb.EgressPolicy) { - p.Rules[0].Https = &ateapipb.HttpsRule{Hostnames: []string{"api.example.com"}} + mutate: func(p *ateapi.EgressPolicy) { + p.Rules[0].Https = &ateapi.HttpsRule{Hostnames: []string{"api.example.com"}} }, want: field.ErrorList{ field.Invalid(rule, nil, "one of").WithOrigin("union"), }, }, { name: "https rule", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0] = httpsRule(portNumbers(443, 8443), "api.example.com", "*.example.org") }, }, { name: "tls passthrough rule", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0] = passthroughRule(portNumbers(443), "api.example.com", "*") }, }, { name: "tls passthrough rule without ports", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0] = passthroughRule(nil, "api.example.com") }, want: field.ErrorList{ @@ -529,7 +529,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "empty pattern list", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Hostnames = nil withoutEffects(p) }, @@ -538,7 +538,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "long pattern list", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { var pats []string for i := range 256 { pats = append(pats, fmt.Sprintf("api%d.example.com", i)) @@ -548,7 +548,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "too-long pattern list", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { var pats []string for i := range 257 { pats = append(pats, fmt.Sprintf("api%d.example.com", i)) @@ -561,7 +561,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "missing pattern", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Hostnames[0] = "" withoutEffects(p) }, @@ -570,7 +570,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "duplicate pattern", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Hostnames = append(p.Rules[0].Http.Hostnames, "api.example.com") }, want: field.ErrorList{ @@ -578,7 +578,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "invalid pattern", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Hostnames[0] = "https://example.com" }, want: field.ErrorList{ @@ -586,7 +586,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "uppercase pattern", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Hostnames[0] = "API.EXAMPLE.COM" }, want: field.ErrorList{ @@ -594,7 +594,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "pattern with trailing dot", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Hostnames[0] = "api.example.com." }, want: field.ErrorList{ @@ -602,7 +602,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "IP literal pattern", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Hostnames[0] = "192.0.2.1" }, want: field.ErrorList{ @@ -610,7 +610,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "pattern with port", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Hostnames[0] = "example.com:443" }, want: field.ErrorList{ @@ -618,23 +618,23 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "wildcard without effects", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Hostnames[0] = "*.example.com" withoutEffects(p) }, }, { name: "wildcard with effects", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Hostnames[0] = "*.example.com" }, }, { name: "star pattern", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Hostnames[0] = "*" }, }, { name: "invalid wildcard", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Hostnames[0] = "api.*.example.com" }, want: field.ErrorList{ @@ -642,7 +642,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "invalid sni pattern", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0] = passthroughRule(portNumbers(443), "*example.com") }, want: field.ErrorList{ @@ -650,41 +650,41 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "ports", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Ports = portNumbers(80, 8080) }, }, { name: "any port", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Ports = allPorts() }, }, { name: "all and numbers together", - mutate: func(p *ateapipb.EgressPolicy) { - p.Rules[0].Http.Ports = &ateapipb.Ports{All: &ateapipb.AllPorts{}, Numbers: []int32{80}} + mutate: func(p *ateapi.EgressPolicy) { + p.Rules[0].Http.Ports = &ateapi.Ports{All: &ateapi.AllPorts{}, Numbers: []int32{80}} }, want: field.ErrorList{ field.Invalid(ports, nil, "one of").WithOrigin("union"), }, }, { name: "empty ports", - mutate: func(p *ateapipb.EgressPolicy) { - p.Rules[0].Http.Ports = &ateapipb.Ports{} + mutate: func(p *ateapi.EgressPolicy) { + p.Rules[0].Http.Ports = &ateapi.Ports{} }, want: field.ErrorList{ field.Invalid(ports, nil, "one of").WithOrigin("union"), }, }, { name: "empty numbers", - mutate: func(p *ateapipb.EgressPolicy) { - p.Rules[0].Http.Ports = &ateapipb.Ports{Numbers: []int32{}} + mutate: func(p *ateapi.EgressPolicy) { + p.Rules[0].Http.Ports = &ateapi.Ports{Numbers: []int32{}} }, want: field.ErrorList{ field.Invalid(ports, nil, "one of").WithOrigin("union"), }, }, { name: "port zero", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Ports = portNumbers(0) }, want: field.ErrorList{ @@ -692,7 +692,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "port out of range", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Ports = portNumbers(65536) }, want: field.ErrorList{ @@ -700,7 +700,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "duplicate port", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Ports = portNumbers(80, 80) }, want: field.ErrorList{ @@ -708,7 +708,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "too many ports", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { var many []int32 for i := range 17 { many = append(many, int32(8000+i)) @@ -720,7 +720,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "negative https port", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0] = httpsRule(portNumbers(-1), "api.example.com") }, want: field.ErrorList{ @@ -728,20 +728,20 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "tls passthrough with empty ports", - mutate: func(p *ateapipb.EgressPolicy) { - p.Rules[0] = passthroughRule(&ateapipb.Ports{}, "*") + mutate: func(p *ateapi.EgressPolicy) { + p.Rules[0] = passthroughRule(&ateapi.Ports{}, "*") }, want: field.ErrorList{ field.Invalid(rule.Child("tls_passthrough", "ports"), nil, "one of").WithOrigin("union"), }, }, { name: "same pattern on different ports", - mutate: func(p *ateapipb.EgressPolicy) { - p.Rules = append(p.Rules, &ateapipb.EgressRule{Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}, Ports: portNumbers(8080)}}) + mutate: func(p *ateapi.EgressPolicy) { + p.Rules = append(p.Rules, &ateapi.EgressRule{Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}, Ports: portNumbers(8080)}}) }, }, { name: "same pattern on the default port ties", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules = append(p.Rules, trivialHTTPRule("api.example.com")) }, want: field.ErrorList{ @@ -749,12 +749,12 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "http and https on their default ports do not tie", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules = append(p.Rules, httpsRule(nil, "api.example.com")) }, }, { name: "http and https on any port tie", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Ports = allPorts() p.Rules = append(p.Rules, httpsRule(allPorts(), "api.example.com")) }, @@ -763,9 +763,9 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "http and tls passthrough on every port tie", - mutate: func(p *ateapipb.EgressPolicy) { - p.Rules = []*ateapipb.EgressRule{ - {Http: &ateapipb.HttpRule{Hostnames: []string{"*"}, Ports: allPorts()}}, + mutate: func(p *ateapi.EgressPolicy) { + p.Rules = []*ateapi.EgressRule{ + {Http: &ateapi.HttpRule{Hostnames: []string{"*"}, Ports: allPorts()}}, passthroughRule(allPorts(), "*"), } }, @@ -774,12 +774,12 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "http on its default port and tls passthrough on every port", - mutate: func(p *ateapipb.EgressPolicy) { - p.Rules = []*ateapipb.EgressRule{trivialHTTPRule("*"), passthroughRule(allPorts(), "*")} + mutate: func(p *ateapi.EgressPolicy) { + p.Rules = []*ateapi.EgressRule{trivialHTTPRule("*"), passthroughRule(allPorts(), "*")} }, }, { name: "https and tls passthrough on the same port tie", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules = append(p.Rules, httpsRule(nil, "*.example.com"), passthroughRule(portNumbers(443), "*.example.com")) }, want: field.ErrorList{ @@ -787,7 +787,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "missing static header", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects.ReplaceHeaders[0].Header = "" }, want: field.ErrorList{ @@ -795,7 +795,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "invalid static header", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects.ReplaceHeaders[0].Header = "bad header" }, want: field.ErrorList{ @@ -803,10 +803,10 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "duplicate header", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects.ReplaceHeaders = append( p.Rules[0].Http.Effects.ReplaceHeaders, - &ateapipb.CredentialHeader{Header: "authorization", CredentialUri: "ate-secret://example.com/provider/secret"}, + &ateapi.CredentialHeader{Header: "authorization", CredentialUri: "ate-secret://example.com/provider/secret"}, ) }, want: field.ErrorList{ @@ -814,17 +814,17 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "same header in later rule", - mutate: func(p *ateapipb.EgressPolicy) { - later := proto.Clone(p.Rules[0]).(*ateapipb.EgressRule) + mutate: func(p *ateapi.EgressPolicy) { + later := proto.Clone(p.Rules[0]).(*ateapi.EgressRule) later.Http.Hostnames = []string{"other.example.com"} p.Rules = append(p.Rules, later) }, }, { name: "many headers", - mutate: func(p *ateapipb.EgressPolicy) { - var injections []*ateapipb.CredentialHeader + mutate: func(p *ateapi.EgressPolicy) { + var injections []*ateapi.CredentialHeader for i := range 16 { - injections = append(injections, &ateapipb.CredentialHeader{ + injections = append(injections, &ateapi.CredentialHeader{ Header: fmt.Sprintf("X-Header-%d", i), CredentialUri: "ate-secret://example.com/provider/secret", }) @@ -833,10 +833,10 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "too many headers", - mutate: func(p *ateapipb.EgressPolicy) { - var injections []*ateapipb.CredentialHeader + mutate: func(p *ateapi.EgressPolicy) { + var injections []*ateapi.CredentialHeader for i := range 17 { - injections = append(injections, &ateapipb.CredentialHeader{ + injections = append(injections, &ateapi.CredentialHeader{ Header: fmt.Sprintf("X-Header-%d", i), CredentialUri: "ate-secret://example.com/provider/secret", }) @@ -848,7 +848,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "invalid prefix", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects.ReplaceHeaders[0].Prefix = "Bearer\r" }, want: field.ErrorList{ @@ -856,7 +856,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "no credential source", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects.ReplaceHeaders[0].CredentialUri = "" }, want: field.ErrorList{ @@ -864,7 +864,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "invalid credential URI", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects.ReplaceHeaders[0].CredentialUri = "https://example.com/secret" }, want: field.ErrorList{ @@ -872,35 +872,35 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "actor JWT on an http rule", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects.ReplaceHeaders[0] = actorJWTHeader("https://api.example.com") }, }, { name: "actor JWT on an https rule", - mutate: func(p *ateapipb.EgressPolicy) { - p.Rules[0] = &ateapipb.EgressRule{Https: &ateapipb.HttpsRule{ + mutate: func(p *ateapi.EgressPolicy) { + p.Rules[0] = &ateapi.EgressRule{Https: &ateapi.HttpsRule{ Hostnames: []string{"api.example.com"}, - Effects: &ateapipb.HttpRuleEffects{ReplaceHeaders: []*ateapipb.CredentialHeader{actorJWTHeader("https://api.example.com")}}, + Effects: &ateapi.HttpRuleEffects{ReplaceHeaders: []*ateapi.CredentialHeader{actorJWTHeader("https://api.example.com")}}, }} }, }, { name: "actor JWT next to a credential URI", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { jwt := actorJWTHeader("https://api.example.com") jwt.Header = "X-Actor-Token" p.Rules[0].Http.Effects.ReplaceHeaders = append(p.Rules[0].Http.Effects.ReplaceHeaders, jwt) }, }, { name: "credential URI and actor JWT in one header", - mutate: func(p *ateapipb.EgressPolicy) { - p.Rules[0].Http.Effects.ReplaceHeaders[0].ActorJwt = &ateapipb.ActorJwtSource{Audiences: []string{"https://api.example.com"}, ExpirationSeconds: 900} + mutate: func(p *ateapi.EgressPolicy) { + p.Rules[0].Http.Effects.ReplaceHeaders[0].ActorJwt = &ateapi.ActorJwtSource{Audiences: []string{"https://api.example.com"}, ExpirationSeconds: 900} }, want: field.ErrorList{ field.Invalid(staticHeader, nil, "one of").WithOrigin("union"), }, }, { name: "actor JWT without audiences", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects.ReplaceHeaders[0] = actorJWTHeader() }, want: field.ErrorList{ @@ -908,7 +908,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "actor JWT with an empty audience", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects.ReplaceHeaders[0] = actorJWTHeader("") }, want: field.ErrorList{ @@ -916,7 +916,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "actor JWT with a long audience", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects.ReplaceHeaders[0] = actorJWTHeader(strings.Repeat("a", 513)) }, want: field.ErrorList{ @@ -924,7 +924,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "actor JWT with a repeated audience", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects.ReplaceHeaders[0] = actorJWTHeader("a", "a") }, want: field.ErrorList{ @@ -932,7 +932,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "actor JWT with too many audiences", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { var audiences []string for i := range 17 { audiences = append(audiences, fmt.Sprintf("aud-%d", i)) @@ -944,7 +944,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "actor JWT without a lifetime", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects.ReplaceHeaders[0] = actorJWTHeader("a") p.Rules[0].Http.Effects.ReplaceHeaders[0].ActorJwt.ExpirationSeconds = 0 }, @@ -953,15 +953,15 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "actor JWT lifetime at its bounds", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { short, long := actorJWTHeader("a"), actorJWTHeader("a") short.ActorJwt.ExpirationSeconds = 300 long.Header, long.ActorJwt.ExpirationSeconds = "X-Actor-Token", 3600 - p.Rules[0].Http.Effects.ReplaceHeaders = []*ateapipb.CredentialHeader{short, long} + p.Rules[0].Http.Effects.ReplaceHeaders = []*ateapi.CredentialHeader{short, long} }, }, { name: "actor JWT lifetime too short", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects.ReplaceHeaders[0] = actorJWTHeader("a") p.Rules[0].Http.Effects.ReplaceHeaders[0].ActorJwt.ExpirationSeconds = 299 }, @@ -970,7 +970,7 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "actor JWT lifetime too long", - mutate: func(p *ateapipb.EgressPolicy) { + mutate: func(p *ateapi.EgressPolicy) { p.Rules[0].Http.Effects.ReplaceHeaders[0] = actorJWTHeader("a") p.Rules[0].Http.Effects.ReplaceHeaders[0].ActorJwt.ExpirationSeconds = 3601 }, @@ -979,16 +979,16 @@ func TestValidateEgressPolicyRules(t *testing.T) { }, }, { name: "empty effects", - mutate: func(p *ateapipb.EgressPolicy) { - p.Rules[0].Http.Effects = &ateapipb.HttpRuleEffects{} + mutate: func(p *ateapi.EgressPolicy) { + p.Rules[0].Http.Effects = &ateapi.HttpRuleEffects{} }, want: field.ErrorList{ field.Required(httpRule.Child("effects"), "at least one effect must be specified"), }, }, { name: "effects on an https rule", - mutate: func(p *ateapipb.EgressPolicy) { - p.Rules[0] = &ateapipb.EgressRule{Https: &ateapipb.HttpsRule{Hostnames: []string{"api.example.com"}, Effects: &ateapipb.HttpRuleEffects{}}} + mutate: func(p *ateapi.EgressPolicy) { + p.Rules[0] = &ateapi.EgressRule{Https: &ateapi.HttpsRule{Hostnames: []string{"api.example.com"}, Effects: &ateapi.HttpRuleEffects{}}} }, want: field.ErrorList{ field.Required(rule.Child("https", "effects"), "at least one effect must be specified"), diff --git a/cmd/ateapi/internal/apivalidation/tag.go b/cmd/ateapi/internal/apivalidation/tag.go index 125e8cf54e..c7847c9814 100644 --- a/cmd/ateapi/internal/apivalidation/tag.go +++ b/cmd/ateapi/internal/apivalidation/tag.go @@ -17,28 +17,28 @@ package apivalidation import ( "context" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "k8s.io/apimachinery/pkg/api/operation" "k8s.io/apimachinery/pkg/api/validate" "k8s.io/apimachinery/pkg/util/validation/field" ) -func ValidateCreateTagRequest(ctx context.Context, req *ateapipb.CreateTagRequest) field.ErrorList { +func ValidateCreateTagRequest(ctx context.Context, req *ateapi.CreateTagRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_CreateTagRequest(ctx, op, nil, req, nil) } -func ValidateGetTagRequest(ctx context.Context, req *ateapipb.GetTagRequest) field.ErrorList { +func ValidateGetTagRequest(ctx context.Context, req *ateapi.GetTagRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_GetTagRequest(ctx, op, nil, req, nil) } -func ValidateListTagsRequest(ctx context.Context, req *ateapipb.ListTagsRequest) field.ErrorList { +func ValidateListTagsRequest(ctx context.Context, req *ateapi.ListTagsRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_ListTagsRequest(ctx, op, nil, req, nil) } -func ValidateUpdateTagRequest(ctx context.Context, req *ateapipb.UpdateTagRequest) field.ErrorList { +func ValidateUpdateTagRequest(ctx context.Context, req *ateapi.UpdateTagRequest) field.ErrorList { // We model this as a create rather than an update because updates assume // the existence of a "current" value, which we do not have yet. This is // validating the request itself. The result will be validated later, after @@ -47,17 +47,17 @@ func ValidateUpdateTagRequest(ctx context.Context, req *ateapipb.UpdateTagReques return Validate_UpdateTagRequest(ctx, op, nil, req, nil) } -func ValidateDeleteTagRequest(ctx context.Context, req *ateapipb.DeleteTagRequest) field.ErrorList { +func ValidateDeleteTagRequest(ctx context.Context, req *ateapi.DeleteTagRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_DeleteTagRequest(ctx, op, nil, req, nil) } -func ValidateTagUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapipb.Tag) field.ErrorList { +func ValidateTagUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapi.Tag) field.ErrorList { op := MakeUpdateOp(ctx) return Validate_Tag(ctx, op, fldPath, newVal, oldVal) } -func ValidateCustom_CreateTagRequest(_ context.Context, _ operation.Operation, p *field.Path, req, _ *ateapipb.CreateTagRequest) field.ErrorList { +func ValidateCustom_CreateTagRequest(_ context.Context, _ operation.Operation, p *field.Path, req, _ *ateapi.CreateTagRequest) field.ErrorList { tag := req.GetTag() sourceActorAtespace := tag.GetSourceActor().GetAtespace() tagAtespace := tag.GetMetadata().GetAtespace() @@ -73,7 +73,7 @@ func ValidateCustom_CreateTagRequest(_ context.Context, _ operation.Operation, p } // This exists only because nested subfield tags are not supported yet. -func ValidateCustom_UpdateTagRequest_Tag(ctx context.Context, op operation.Operation, fldPath *field.Path, tag, _ *ateapipb.Tag) field.ErrorList { +func ValidateCustom_UpdateTagRequest_Tag(ctx context.Context, op operation.Operation, fldPath *field.Path, tag, _ *ateapi.Tag) field.ErrorList { if tag == nil || tag.Metadata == nil { return nil // handled by DV } diff --git a/cmd/ateapi/internal/apivalidation/tag_test.go b/cmd/ateapi/internal/apivalidation/tag_test.go index 9bc5892863..f7c36ac7f9 100644 --- a/cmd/ateapi/internal/apivalidation/tag_test.go +++ b/cmd/ateapi/internal/apivalidation/tag_test.go @@ -19,17 +19,17 @@ import ( "strings" "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "k8s.io/apimachinery/pkg/util/validation/field" ) func TestValidateCreateTagRequest(t *testing.T) { ctx := context.Background() - validTag := func(opts ...func(*ateapipb.Tag)) *ateapipb.Tag { - tag := &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ns1", Name: "tag1"}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - SourceActor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}, + validTag := func(opts ...func(*ateapi.Tag)) *ateapi.Tag { + tag := &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ns1", Name: "tag1"}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + SourceActor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, } for _, opt := range opts { opt(tag) @@ -38,12 +38,12 @@ func TestValidateCreateTagRequest(t *testing.T) { } tests := []struct { name string - req *ateapipb.CreateTagRequest + req *ateapi.CreateTagRequest wantError field.ErrorList }{ { name: "valid", - req: &ateapipb.CreateTagRequest{Tag: validTag()}, + req: &ateapi.CreateTagRequest{Tag: validTag()}, wantError: nil, }, { @@ -51,9 +51,9 @@ func TestValidateCreateTagRequest(t *testing.T) { // client that echoes back a tag it read is not to be tripped up by // one either. name: "valid with status", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { - tag.Status = &ateapipb.TagStatus{ + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { + tag.Status = &ateapi.TagStatus{ Snapshot: validSnapshot(), ActorTemplateUid: someActorUID, } @@ -66,8 +66,8 @@ func TestValidateCreateTagRequest(t *testing.T) { // create: the source Actor's atespace is checked against it, not // used as a default. name: "empty tag.metadata.atespace", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata.Atespace = "" }), + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata.Atespace = "" }), }, wantError: field.ErrorList{field.Required(field.NewPath("tag", "metadata", "atespace"), "")}, }, @@ -75,8 +75,8 @@ func TestValidateCreateTagRequest(t *testing.T) { // Malformed, so it is both rejected on its own terms and unable to // match the source actor's. name: "invalid tag.metadata.atespace", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata.Atespace = "NS1" }), + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata.Atespace = "NS1" }), }, wantError: field.ErrorList{ field.Invalid(field.NewPath("tag", "metadata", "atespace"), nil, ""), @@ -85,8 +85,8 @@ func TestValidateCreateTagRequest(t *testing.T) { }, { name: "missing tag.source_actor", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.SourceActor = nil }), + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.SourceActor = nil }), }, wantError: field.ErrorList{field.Required(field.NewPath("tag", "source_actor"), "")}, }, @@ -94,8 +94,8 @@ func TestValidateCreateTagRequest(t *testing.T) { // Only source_actor is reported: tag.metadata.atespace cannot be // held against a source that has none to compare it to. name: "missing tag.source_actor.atespace", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.SourceActor.Atespace = "" }), + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.SourceActor.Atespace = "" }), }, wantError: field.ErrorList{field.Required(field.NewPath("tag", "source_actor", "atespace"), "")}, }, @@ -103,8 +103,8 @@ func TestValidateCreateTagRequest(t *testing.T) { // A malformed source atespace is also one the tag's own atespace // cannot match, so both are reported. name: "invalid tag.source_actor.atespace", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.SourceActor.Atespace = "NS1" }), + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.SourceActor.Atespace = "NS1" }), }, wantError: field.ErrorList{ field.Invalid(field.NewPath("tag", "metadata", "atespace"), nil, ""), @@ -113,41 +113,41 @@ func TestValidateCreateTagRequest(t *testing.T) { }, { name: "missing tag.source_actor.name", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.SourceActor.Name = "" }), + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.SourceActor.Name = "" }), }, wantError: field.ErrorList{field.Required(field.NewPath("tag", "source_actor", "name"), "")}, }, { name: "invalid tag.source_actor.name", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.SourceActor.Name = "ID1" }), + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.SourceActor.Name = "ID1" }), }, wantError: field.ErrorList{field.Invalid(field.NewPath("tag", "source_actor", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "missing tag", - req: &ateapipb.CreateTagRequest{}, + req: &ateapi.CreateTagRequest{}, wantError: field.ErrorList{field.Required(field.NewPath("tag"), "")}, }, { name: "missing tag.metadata", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata = nil }), + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata = nil }), }, wantError: field.ErrorList{field.Required(field.NewPath("tag", "metadata"), "")}, }, { name: "missing tag.metadata.name", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata.Name = "" }), + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata.Name = "" }), }, wantError: field.ErrorList{field.Required(field.NewPath("tag", "metadata", "name"), "")}, }, { name: "invalid tag.metadata.name", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata.Name = "TAG1" }), + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata.Name = "TAG1" }), }, wantError: field.ErrorList{field.Invalid(field.NewPath("tag", "metadata", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }, @@ -155,31 +155,31 @@ func TestValidateCreateTagRequest(t *testing.T) { // A tag somewhere else than its source Actor could not be resolved // back to it. name: "tag.metadata.atespace is not the source actor's", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata.Atespace = "ns2" }), + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata.Atespace = "ns2" }), }, wantError: field.ErrorList{field.Invalid(field.NewPath("tag", "metadata", "atespace"), nil, "")}, }, { name: "unset tag.scope", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { - tag.Scope = ateapipb.TagScope_TAG_SCOPE_UNSPECIFIED + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { + tag.Scope = ateapi.TagScope_TAG_SCOPE_UNSPECIFIED }), }, wantError: field.ErrorList{field.Required(field.NewPath("tag", "scope"), "")}, }, { name: "tag.scope above the enum", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Scope = ateapipb.TagScope(7) }), + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Scope = ateapi.TagScope(7) }), }, wantError: field.ErrorList{field.Invalid(field.NewPath("tag", "scope"), nil, "").WithOrigin("maximum")}, }, { name: "negative tag.scope", - req: &ateapipb.CreateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Scope = ateapipb.TagScope(-1) }), + req: &ateapi.CreateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Scope = ateapi.TagScope(-1) }), }, wantError: field.ErrorList{field.Invalid(field.NewPath("tag", "scope"), nil, "").WithOrigin("minimum")}, }, @@ -195,11 +195,11 @@ func TestValidateUpdateTagRequest(t *testing.T) { ctx := context.Background() // validUID is a well-formed uid to pass validation. const validUID = "2a5f8c1e-9b3d-4f7a-8e6c-1d0b4a7f2e93" - validTag := func(opts ...func(*ateapipb.Tag)) *ateapipb.Tag { - tag := &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ns1", Name: "tag1", Uid: validUID, Version: 7}, - Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED, - SourceActor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}, + validTag := func(opts ...func(*ateapi.Tag)) *ateapi.Tag { + tag := &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ns1", Name: "tag1", Uid: validUID, Version: 7}, + Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED, + SourceActor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, } for _, opt := range opts { opt(tag) @@ -208,51 +208,51 @@ func TestValidateUpdateTagRequest(t *testing.T) { } tests := []struct { name string - req *ateapipb.UpdateTagRequest + req *ateapi.UpdateTagRequest wantError field.ErrorList }{ { name: "valid", - req: &ateapipb.UpdateTagRequest{Tag: validTag()}, + req: &ateapi.UpdateTagRequest{Tag: validTag()}, wantError: nil, }, { name: "missing tag", - req: &ateapipb.UpdateTagRequest{}, + req: &ateapi.UpdateTagRequest{}, wantError: field.ErrorList{field.Required(field.NewPath("tag"), "")}, }, { name: "missing tag.metadata", - req: &ateapipb.UpdateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata = nil }), + req: &ateapi.UpdateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata = nil }), }, wantError: field.ErrorList{field.Required(field.NewPath("tag", "metadata"), "")}, }, { name: "missing tag.metadata.atespace", - req: &ateapipb.UpdateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata.Atespace = "" }), + req: &ateapi.UpdateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata.Atespace = "" }), }, wantError: field.ErrorList{field.Required(field.NewPath("tag", "metadata", "atespace"), "")}, }, { name: "invalid tag.metadata.atespace", - req: &ateapipb.UpdateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata.Atespace = "NS1" }), + req: &ateapi.UpdateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata.Atespace = "NS1" }), }, wantError: field.ErrorList{field.Invalid(field.NewPath("tag", "metadata", "atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "missing tag.metadata.name", - req: &ateapipb.UpdateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata.Name = "" }), + req: &ateapi.UpdateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata.Name = "" }), }, wantError: field.ErrorList{field.Required(field.NewPath("tag", "metadata", "name"), "")}, }, { name: "invalid tag.metadata.name", - req: &ateapipb.UpdateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata.Name = "TAG1" }), + req: &ateapi.UpdateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata.Name = "TAG1" }), }, wantError: field.ErrorList{field.Invalid(field.NewPath("tag", "metadata", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }, @@ -261,29 +261,29 @@ func TestValidateUpdateTagRequest(t *testing.T) { // an update carrying neither is rejected as a blind write once it // reaches the store. See TestUpdateTag_BlindWrite. name: "missing tag.metadata.uid precondition", - req: &ateapipb.UpdateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata.Uid = "" }), + req: &ateapi.UpdateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata.Uid = "" }), }, wantError: nil, }, { name: "invalid tag.metadata.uid precondition", - req: &ateapipb.UpdateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata.Uid = "not-a-uuid" }), + req: &ateapi.UpdateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata.Uid = "not-a-uuid" }), }, wantError: field.ErrorList{field.Invalid(field.NewPath("tag", "metadata", "uid"), nil, "").WithOrigin("format=k8s-uuid")}, }, { name: "missing tag.metadata.version precondition", - req: &ateapipb.UpdateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata.Version = 0 }), + req: &ateapi.UpdateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata.Version = 0 }), }, wantError: nil, }, { name: "negative tag.metadata.version precondition", - req: &ateapipb.UpdateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { tag.Metadata.Version = -1 }), + req: &ateapi.UpdateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.Metadata.Version = -1 }), }, wantError: field.ErrorList{field.Invalid(field.NewPath("tag", "metadata", "version"), nil, "").WithOrigin("minimum")}, }, @@ -292,10 +292,10 @@ func TestValidateUpdateTagRequest(t *testing.T) { // checked against the stored tag instead, so a source or a scope // the request gets wrong is caught there. name: "tag body is not checked against the request", - req: &ateapipb.UpdateTagRequest{ - Tag: validTag(func(tag *ateapipb.Tag) { + req: &ateapi.UpdateTagRequest{ + Tag: validTag(func(tag *ateapi.Tag) { tag.SourceActor = nil - tag.Scope = ateapipb.TagScope_TAG_SCOPE_UNSPECIFIED + tag.Scope = ateapi.TagScope_TAG_SCOPE_UNSPECIFIED }), }, wantError: nil, @@ -314,11 +314,11 @@ func TestValidateUpdateTagRequest(t *testing.T) { func TestValidateTagUpdateResult(t *testing.T) { ctx := context.Background() tagPath := field.NewPath("tag") - storedTag := func(opts ...func(*ateapipb.Tag)) *ateapipb.Tag { - tag := &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ns1", Name: "tag1", Uid: "2a5f8c1e-9b3d-4f7a-8e6c-1d0b4a7f2e93", Version: 7}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - SourceActor: &ateapipb.ObjectRef{Atespace: "ns1", Name: "id1"}, + storedTag := func(opts ...func(*ateapi.Tag)) *ateapi.Tag { + tag := &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ns1", Name: "tag1", Uid: "2a5f8c1e-9b3d-4f7a-8e6c-1d0b4a7f2e93", Version: 7}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + SourceActor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, } for _, opt := range opts { opt(tag) @@ -327,7 +327,7 @@ func TestValidateTagUpdateResult(t *testing.T) { } tests := []struct { name string - newVal *ateapipb.Tag + newVal *ateapi.Tag wantError field.ErrorList }{ { @@ -337,34 +337,34 @@ func TestValidateTagUpdateResult(t *testing.T) { }, { name: "publishing is allowed", - newVal: storedTag(func(tag *ateapipb.Tag) { - tag.Scope = ateapipb.TagScope_TAG_SCOPE_PUBLISHED + newVal: storedTag(func(tag *ateapi.Tag) { + tag.Scope = ateapi.TagScope_TAG_SCOPE_PUBLISHED }), wantError: nil, }, { name: "unset tag.scope", - newVal: storedTag(func(tag *ateapipb.Tag) { - tag.Scope = ateapipb.TagScope_TAG_SCOPE_UNSPECIFIED + newVal: storedTag(func(tag *ateapi.Tag) { + tag.Scope = ateapi.TagScope_TAG_SCOPE_UNSPECIFIED }), wantError: field.ErrorList{field.Required(tagPath.Child("scope"), "")}, }, { name: "tag.scope above the enum", - newVal: storedTag(func(tag *ateapipb.Tag) { tag.Scope = ateapipb.TagScope(7) }), + newVal: storedTag(func(tag *ateapi.Tag) { tag.Scope = ateapi.TagScope(7) }), wantError: field.ErrorList{field.Invalid(tagPath.Child("scope"), nil, "").WithOrigin("maximum")}, }, { name: "negative tag.scope", - newVal: storedTag(func(tag *ateapipb.Tag) { tag.Scope = ateapipb.TagScope(-1) }), + newVal: storedTag(func(tag *ateapi.Tag) { tag.Scope = ateapi.TagScope(-1) }), wantError: field.ErrorList{field.Invalid(tagPath.Child("scope"), nil, "").WithOrigin("minimum")}, }, { // A tag never moves between snapshots, so it never moves between // sources either. name: "repointed tag.source_actor", - newVal: storedTag(func(tag *ateapipb.Tag) { - tag.SourceActor = &ateapipb.ObjectRef{Atespace: "ns1", Name: "id2"} + newVal: storedTag(func(tag *ateapi.Tag) { + tag.SourceActor = &ateapi.ObjectRef{Atespace: "ns1", Name: "id2"} }), wantError: field.ErrorList{field.Invalid(tagPath.Child("source_actor"), nil, "").WithOrigin("immutable")}, }, @@ -372,7 +372,7 @@ func TestValidateTagUpdateResult(t *testing.T) { // An update is a whole-object replace, so a client that drops the // source it read back would clear it. name: "missing tag.source_actor", - newVal: storedTag(func(tag *ateapipb.Tag) { tag.SourceActor = nil }), + newVal: storedTag(func(tag *ateapi.Tag) { tag.SourceActor = nil }), wantError: field.ErrorList{ field.Invalid(tagPath.Child("source_actor"), nil, "").WithOrigin("immutable"), field.Required(tagPath.Child("source_actor"), ""), @@ -382,17 +382,17 @@ func TestValidateTagUpdateResult(t *testing.T) { // The tag is addressed through its atespace and name; moving it // would strand every reference to it. name: "renamed tag", - newVal: storedTag(func(tag *ateapipb.Tag) { tag.Metadata.Name = "tag2" }), + newVal: storedTag(func(tag *ateapi.Tag) { tag.Metadata.Name = "tag2" }), wantError: field.ErrorList{field.Invalid(tagPath.Child("metadata", "name"), nil, "").WithOrigin("immutable")}, }, { name: "tag moved to another atespace", - newVal: storedTag(func(tag *ateapipb.Tag) { tag.Metadata.Atespace = "ns2" }), + newVal: storedTag(func(tag *ateapi.Tag) { tag.Metadata.Atespace = "ns2" }), wantError: field.ErrorList{field.Invalid(tagPath.Child("metadata", "atespace"), nil, "").WithOrigin("immutable")}, }, { name: "cleared tag.metadata.atespace", - newVal: storedTag(func(tag *ateapipb.Tag) { tag.Metadata.Atespace = "" }), + newVal: storedTag(func(tag *ateapi.Tag) { tag.Metadata.Atespace = "" }), wantError: field.ErrorList{ field.Required(tagPath.Child("metadata", "atespace"), ""), field.Invalid(tagPath.Child("metadata", "atespace"), nil, "").WithOrigin("immutable"), @@ -400,7 +400,7 @@ func TestValidateTagUpdateResult(t *testing.T) { }, { name: "missing tag.metadata", - newVal: storedTag(func(tag *ateapipb.Tag) { tag.Metadata = nil }), + newVal: storedTag(func(tag *ateapi.Tag) { tag.Metadata = nil }), wantError: field.ErrorList{field.Required(tagPath.Child("metadata"), "")}, }, } @@ -415,44 +415,44 @@ func TestValidateListTagsRequest(t *testing.T) { ctx := context.Background() tests := []struct { name string - req *ateapipb.ListTagsRequest + req *ateapi.ListTagsRequest wantError field.ErrorList }{ { name: "valid, atespace scoped", - req: &ateapipb.ListTagsRequest{Atespace: "ns1"}, + req: &ateapi.ListTagsRequest{Atespace: "ns1"}, wantError: nil, }, { // Empty atespace means "all atespaces" // (kubectl ate get tags -A). name: "valid, empty atespace means all atespaces", - req: &ateapipb.ListTagsRequest{}, + req: &ateapi.ListTagsRequest{}, wantError: nil, }, { name: "invalid atespace", - req: &ateapipb.ListTagsRequest{Atespace: "NS1"}, + req: &ateapi.ListTagsRequest{Atespace: "NS1"}, wantError: field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "valid, positive page_size", - req: &ateapipb.ListTagsRequest{Atespace: "ns1", Options: &ateapipb.ListOptions{PageSize: 10}}, + req: &ateapi.ListTagsRequest{Atespace: "ns1", Options: &ateapi.ListOptions{PageSize: 10}}, wantError: nil, }, { name: "negative page_size", - req: &ateapipb.ListTagsRequest{Atespace: "ns1", Options: &ateapipb.ListOptions{PageSize: -1}}, + req: &ateapi.ListTagsRequest{Atespace: "ns1", Options: &ateapi.ListOptions{PageSize: -1}}, wantError: field.ErrorList{field.Invalid(field.NewPath("options", "page_size"), nil, "").WithOrigin("minimum")}, }, { name: "valid page_token", - req: &ateapipb.ListTagsRequest{Atespace: "ns1", Options: &ateapipb.ListOptions{PageToken: strings.Repeat("x", 256)}}, + req: &ateapi.ListTagsRequest{Atespace: "ns1", Options: &ateapi.ListOptions{PageToken: strings.Repeat("x", 256)}}, wantError: nil, }, { name: "too-large page_token", - req: &ateapipb.ListTagsRequest{Atespace: "ns1", Options: &ateapipb.ListOptions{PageToken: strings.Repeat("x", 257)}}, + req: &ateapi.ListTagsRequest{Atespace: "ns1", Options: &ateapi.ListOptions{PageToken: strings.Repeat("x", 257)}}, wantError: field.ErrorList{field.TooLongCharacters(field.NewPath("options", "page_token"), "", 256).WithOrigin("maxLength")}, }, } @@ -467,37 +467,37 @@ func TestValidateGetTagRequest(t *testing.T) { ctx := context.Background() tests := []struct { name string - req *ateapipb.GetTagRequest + req *ateapi.GetTagRequest wantError field.ErrorList }{ { name: "valid", - req: &ateapipb.GetTagRequest{Tag: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tag1"}}, + req: &ateapi.GetTagRequest{Tag: &ateapi.ObjectRef{Atespace: "ns1", Name: "tag1"}}, wantError: nil, }, { name: "missing tag", - req: &ateapipb.GetTagRequest{}, + req: &ateapi.GetTagRequest{}, wantError: field.ErrorList{field.Required(field.NewPath("tag"), "")}, }, { name: "missing tag.atespace", - req: &ateapipb.GetTagRequest{Tag: &ateapipb.ObjectRef{Name: "tag1"}}, + req: &ateapi.GetTagRequest{Tag: &ateapi.ObjectRef{Name: "tag1"}}, wantError: field.ErrorList{field.Required(field.NewPath("tag", "atespace"), "")}, }, { name: "invalid tag.atespace", - req: &ateapipb.GetTagRequest{Tag: &ateapipb.ObjectRef{Atespace: "NS1", Name: "tag1"}}, + req: &ateapi.GetTagRequest{Tag: &ateapi.ObjectRef{Atespace: "NS1", Name: "tag1"}}, wantError: field.ErrorList{field.Invalid(field.NewPath("tag", "atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "missing tag.name", - req: &ateapipb.GetTagRequest{Tag: &ateapipb.ObjectRef{Atespace: "ns1"}}, + req: &ateapi.GetTagRequest{Tag: &ateapi.ObjectRef{Atespace: "ns1"}}, wantError: field.ErrorList{field.Required(field.NewPath("tag", "name"), "")}, }, { name: "invalid tag.name", - req: &ateapipb.GetTagRequest{Tag: &ateapipb.ObjectRef{Atespace: "ns1", Name: "TAG1"}}, + req: &ateapi.GetTagRequest{Tag: &ateapi.ObjectRef{Atespace: "ns1", Name: "TAG1"}}, wantError: field.ErrorList{field.Invalid(field.NewPath("tag", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }, } @@ -512,37 +512,37 @@ func TestValidateDeleteTagRequest(t *testing.T) { ctx := context.Background() tests := []struct { name string - req *ateapipb.DeleteTagRequest + req *ateapi.DeleteTagRequest wantError field.ErrorList }{ { name: "valid", - req: &ateapipb.DeleteTagRequest{Tag: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tag1"}}, + req: &ateapi.DeleteTagRequest{Tag: &ateapi.ObjectRef{Atespace: "ns1", Name: "tag1"}}, wantError: nil, }, { name: "missing tag", - req: &ateapipb.DeleteTagRequest{}, + req: &ateapi.DeleteTagRequest{}, wantError: field.ErrorList{field.Required(field.NewPath("tag"), "")}, }, { name: "missing tag.atespace", - req: &ateapipb.DeleteTagRequest{Tag: &ateapipb.ObjectRef{Name: "tag1"}}, + req: &ateapi.DeleteTagRequest{Tag: &ateapi.ObjectRef{Name: "tag1"}}, wantError: field.ErrorList{field.Required(field.NewPath("tag", "atespace"), "")}, }, { name: "invalid tag.atespace", - req: &ateapipb.DeleteTagRequest{Tag: &ateapipb.ObjectRef{Atespace: "NS1", Name: "tag1"}}, + req: &ateapi.DeleteTagRequest{Tag: &ateapi.ObjectRef{Atespace: "NS1", Name: "tag1"}}, wantError: field.ErrorList{field.Invalid(field.NewPath("tag", "atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "missing tag.name", - req: &ateapipb.DeleteTagRequest{Tag: &ateapipb.ObjectRef{Atespace: "ns1"}}, + req: &ateapi.DeleteTagRequest{Tag: &ateapi.ObjectRef{Atespace: "ns1"}}, wantError: field.ErrorList{field.Required(field.NewPath("tag", "name"), "")}, }, { name: "invalid tag.name", - req: &ateapipb.DeleteTagRequest{Tag: &ateapipb.ObjectRef{Atespace: "ns1", Name: "TAG1"}}, + req: &ateapi.DeleteTagRequest{Tag: &ateapi.ObjectRef{Atespace: "ns1", Name: "TAG1"}}, wantError: field.ErrorList{field.Invalid(field.NewPath("tag", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }, } diff --git a/cmd/ateapi/internal/apivalidation/validation_test.go b/cmd/ateapi/internal/apivalidation/validation_test.go index af45ffb11e..43b315af58 100644 --- a/cmd/ateapi/internal/apivalidation/validation_test.go +++ b/cmd/ateapi/internal/apivalidation/validation_test.go @@ -21,16 +21,16 @@ import ( "strings" "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" "k8s.io/apimachinery/pkg/api/operation" "k8s.io/apimachinery/pkg/util/validation/field" ) -func validResourceMetadata(mutate ...func(*ateapipb.ResourceMetadata)) *ateapipb.ResourceMetadata { +func validResourceMetadata(mutate ...func(*ateapi.ResourceMetadata)) *ateapi.ResourceMetadata { // This is valid with as many fields populated as possible. - rm := &ateapipb.ResourceMetadata{ + rm := &ateapi.ResourceMetadata{ Atespace: "as", Name: "nm", Uid: "01234567-89ab-cdef-0123-456789abcdef", @@ -50,68 +50,68 @@ func TestValidateResourceMetadataCreate(t *testing.T) { // Focus this test on fields other than atespace and name. tests := []struct { name string - obj *ateapipb.ResourceMetadata + obj *ateapi.ResourceMetadata want field.ErrorList }{{ name: "valid", obj: valid(), }, { name: "valid atespace: empty", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "" }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "" }), }, { name: "missing name", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "" }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "" }), want: field.ErrorList{field.Required(field.NewPath("name"), "")}, }, { name: "unspecified uid", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Uid = "" }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.Uid = "" }), want: nil, }, { name: "invalid uid: close but not valid", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Uid = "aaaaaaaa-bbbbcccc-dddd-eeeeeeeeeeee" }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.Uid = "aaaaaaaa-bbbbcccc-dddd-eeeeeeeeeeee" }), want: field.ErrorList{field.Invalid(field.NewPath("uid"), nil, "").WithOrigin("format=k8s-uuid")}, }, { name: "invalid uid: not even close", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Uid = "not a uid" }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.Uid = "not a uid" }), want: field.ErrorList{field.Invalid(field.NewPath("uid"), nil, "").WithOrigin("format=k8s-uuid")}, }, { name: "unspecified version", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Version = 0 }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.Version = 0 }), want: nil, }, { name: "valid version: large", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Version = math.MaxInt64 }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.Version = math.MaxInt64 }), }, { name: "invalid version: negative", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Version = -1 }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.Version = -1 }), want: field.ErrorList{field.Invalid(field.NewPath("version"), nil, "").WithOrigin("minimum")}, }, { name: "unspecified createTime", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.CreateTime = nil }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.CreateTime = nil }), want: nil, }, { name: "unspecified updateTime", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.UpdateTime = nil }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.UpdateTime = nil }), want: nil, }, { name: "invalid createTime: seconds out of range", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.CreateTime = ×tamppb.Timestamp{Seconds: 253402300800} }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.CreateTime = ×tamppb.Timestamp{Seconds: 253402300800} }), want: field.ErrorList{field.Invalid(field.NewPath("create_time"), nil, "")}, }, { name: "invalid updateTime: negative nanos", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.UpdateTime = ×tamppb.Timestamp{Seconds: 5309, Nanos: -1} }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.UpdateTime = ×tamppb.Timestamp{Seconds: 5309, Nanos: -1} }), want: field.ErrorList{field.Invalid(field.NewPath("update_time"), nil, "")}, }, { name: "invalid updateTime: precedes createTime", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.UpdateTime = ×tamppb.Timestamp{Seconds: 866} }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.UpdateTime = ×tamppb.Timestamp{Seconds: 866} }), want: field.ErrorList{field.Invalid(field.NewPath("update_time"), nil, "")}, }, { name: "valid updateTime: equals createTime", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.UpdateTime = ×tamppb.Timestamp{Seconds: 867} }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.UpdateTime = ×tamppb.Timestamp{Seconds: 867} }), want: nil, }, { name: "valid updateTime: set without createTime", - obj: valid(func(rm *ateapipb.ResourceMetadata) { rm.CreateTime = nil }), + obj: valid(func(rm *ateapi.ResourceMetadata) { rm.CreateTime = nil }), want: nil, }} for _, tt := range tests { @@ -129,8 +129,8 @@ func TestValidateResourceMetadataUpdate(t *testing.T) { // Focus this test on fields other than atespace and name. tests := []struct { name string - oldObj *ateapipb.ResourceMetadata // should always be valid - newObj *ateapipb.ResourceMetadata + oldObj *ateapi.ResourceMetadata // should always be valid + newObj *ateapi.ResourceMetadata want field.ErrorList }{{ name: "valid", @@ -138,68 +138,68 @@ func TestValidateResourceMetadataUpdate(t *testing.T) { newObj: valid(), }, { name: "atespace: empty -> non-empty", - oldObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "" }), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "present" }), + oldObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "" }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "present" }), want: field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("immutable")}, }, { name: "atespace: non-empty -> empty", - oldObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "present" }), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "" }), + oldObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "present" }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "" }), want: field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("immutable")}, }, { name: "atespace: changed", - oldObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "value-1" }), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "value-2" }), + oldObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "value-1" }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "value-2" }), want: field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("immutable")}, }, { name: "name: unset", oldObj: valid(), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "" }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "" }), want: field.ErrorList{ field.Required(field.NewPath("name"), ""), field.Invalid(field.NewPath("name"), nil, "").WithOrigin("immutable"), }, }, { name: "name: changed", - oldObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "value-1" }), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "value-2" }), + oldObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "value-1" }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "value-2" }), want: field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("immutable")}, }, { name: "uid: unset", oldObj: valid(), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Uid = "" }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Uid = "" }), want: field.ErrorList{field.Invalid(field.NewPath("uid"), nil, "").WithOrigin("immutable")}, }, { name: "uid: changed to valid", - oldObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Uid = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" }), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Uid = "11111111-2222-3333-4444-555555555555" }), + oldObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Uid = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Uid = "11111111-2222-3333-4444-555555555555" }), want: field.ErrorList{field.Invalid(field.NewPath("uid"), nil, "").WithOrigin("immutable")}, }, { name: "uid: changed to invalid", - oldObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Uid = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" }), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Uid = "not a uid" }), + oldObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Uid = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Uid = "not a uid" }), want: field.ErrorList{field.Invalid(field.NewPath("uid"), nil, "").WithOrigin("immutable")}, }, { name: "version: unset", oldObj: valid(), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Version = 0 }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Version = 0 }), want: field.ErrorList{field.Invalid(field.NewPath("version"), nil, "").WithOrigin("update")}, }, { name: "version: changed to valid", - oldObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Version = 123 }), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Version = 456 }), + oldObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Version = 123 }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Version = 456 }), want: nil, }, { name: "version: changed non-monotonically", - oldObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Version = 456 }), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Version = 123 }), + oldObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Version = 456 }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Version = 123 }), want: field.ErrorList{ field.Invalid(field.NewPath("version"), nil, "").WithOrigin("monotonic"), }, }, { name: "version: changed to invalid", - oldObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Version = 456 }), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.Version = -1 }), + oldObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Version = 456 }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.Version = -1 }), want: field.ErrorList{ field.Invalid(field.NewPath("version"), nil, "").WithOrigin("monotonic"), field.Invalid(field.NewPath("version"), nil, "").WithOrigin("minimum"), @@ -207,27 +207,27 @@ func TestValidateResourceMetadataUpdate(t *testing.T) { }, { name: "create_time: unset", oldObj: valid(), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.CreateTime = nil }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.CreateTime = nil }), want: field.ErrorList{field.Invalid(field.NewPath("create_time"), nil, "").WithOrigin("immutable")}, }, { name: "create_time: changed", - oldObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.CreateTime.Seconds = 123 }), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.CreateTime.Seconds = 456 }), + oldObj: valid(func(rm *ateapi.ResourceMetadata) { rm.CreateTime.Seconds = 123 }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.CreateTime.Seconds = 456 }), want: field.ErrorList{field.Invalid(field.NewPath("create_time"), nil, "").WithOrigin("immutable")}, }, { name: "update_time: unset", oldObj: valid(), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.UpdateTime = nil }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.UpdateTime = nil }), want: field.ErrorList{field.Invalid(field.NewPath("update_time"), nil, "").WithOrigin("update")}, }, { name: "update_time: changed to valid", - oldObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.UpdateTime.Seconds = 1000 }), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.UpdateTime.Seconds = 6000 }), + oldObj: valid(func(rm *ateapi.ResourceMetadata) { rm.UpdateTime.Seconds = 1000 }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.UpdateTime.Seconds = 6000 }), want: nil, }, { name: "update_time: changed to precede create_time", oldObj: valid(), - newObj: valid(func(rm *ateapipb.ResourceMetadata) { rm.UpdateTime.Seconds = 866 }), + newObj: valid(func(rm *ateapi.ResourceMetadata) { rm.UpdateTime.Seconds = 866 }), want: field.ErrorList{field.Invalid(field.NewPath("update_time"), nil, "")}, }} for _, tt := range tests { @@ -245,7 +245,7 @@ func TestValidateResourceMetadataNameAndAtespaceFormat(t *testing.T) { // Focus this test on exhaustive testing of the name and atespace fields. tests := []struct { name string - obj *ateapipb.ResourceMetadata + obj *ateapi.ResourceMetadata want field.ErrorList }{{ "valid", @@ -253,179 +253,179 @@ func TestValidateResourceMetadataNameAndAtespaceFormat(t *testing.T) { nil, }, { "valid atespace: alphabetic", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "myatespace" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "myatespace" }), nil, }, { "valid atespace: dashes", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my-ate-space" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my-ate-space" }), nil, }, { "valid atespace: repeat dashes", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my---ate---space" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my---ate---space" }), nil, }, { "valid atespace: alphanumeric", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my-123-atespace" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my-123-atespace" }), nil, }, { "valid atespace: leading numeric", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "123-atespace" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "123-atespace" }), nil, }, { "valid atespace: trailing numeric", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my-123" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my-123" }), nil, }, { "valid atespace: fully numeric", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "123" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "123" }), nil, }, { "valid atespace: long", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = strings.Repeat("x", 63) }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = strings.Repeat("x", 63) }), nil, }, { "invalid atespace: uppercase", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "MYATESPACE" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "MYATESPACE" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: leading dash", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "-atespace" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "-atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: trailing dash", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my-" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my-" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: dots", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my.atespace" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my.atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: underscores", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my_atespace" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my_atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: bang", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my!atespace" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my!atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: at", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my@atespace" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my@atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: pound", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my#atespace" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my#atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: dollar", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my$atespace" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my$atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: percent", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my%%atespace" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my%%atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: caret", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my^atespace" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my^atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: ampersand", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my&atespace" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my&atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: star", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = "my*atespace" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = "my*atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: too long", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Atespace = strings.Repeat("x", 64) }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Atespace = strings.Repeat("x", 64) }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "valid name: alphabetic", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "myname" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "myname" }), nil, }, { "valid name: dashes", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my-na-me" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my-na-me" }), nil, }, { "valid name: repeat dashes", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my---na---me" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my---na---me" }), nil, }, { "valid name: alphanumeric", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my-123-name" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my-123-name" }), nil, }, { "invalid name: leading numeric", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "123-name" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "123-name" }), nil, }, { "invalid name: trailing numeric", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my-123" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my-123" }), nil, }, { "invalid name: fully numeric", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "123" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "123" }), nil, }, { "valid name: long", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = strings.Repeat("x", 63) }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = strings.Repeat("x", 63) }), nil, }, { "invalid name: uppercase", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "MYNAME" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "MYNAME" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: leading dash", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "-name" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "-name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: trailing dash", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my-" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my-" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: dots", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my.name" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my.name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: underscores", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my_name" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my_name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: bang", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my!name" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my!name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: at", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my@name" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my@name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: pound", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my#name" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my#name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: dollar", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my$name" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my$name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: percent", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my%%name" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my%%name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: caret", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my^name" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my^name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: ampersand", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my&name" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my&name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: star", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = "my*name" }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = "my*name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: too long", - valid(func(rm *ateapipb.ResourceMetadata) { rm.Name = strings.Repeat("x", 64) }), + valid(func(rm *ateapi.ResourceMetadata) { rm.Name = strings.Repeat("x", 64) }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }} for _, tt := range tests { @@ -439,8 +439,8 @@ func TestValidateResourceMetadataNameAndAtespaceFormat(t *testing.T) { } func TestValidateObjectRef(t *testing.T) { - valid := func(mutate func(*ateapipb.ObjectRef)) *ateapipb.ObjectRef { - r := &ateapipb.ObjectRef{ + valid := func(mutate func(*ateapi.ObjectRef)) *ateapi.ObjectRef { + r := &ateapi.ObjectRef{ Atespace: "as", Name: "nm", } @@ -452,7 +452,7 @@ func TestValidateObjectRef(t *testing.T) { tests := []struct { name string - ref *ateapipb.ObjectRef + ref *ateapi.ObjectRef want field.ErrorList }{{ "valid", @@ -460,187 +460,187 @@ func TestValidateObjectRef(t *testing.T) { nil, }, { "valid atespace: empty", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "" }), nil, }, { "valid atespace: alphabetic", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "myatespace" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "myatespace" }), nil, }, { "valid atespace: dashes", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my-ate-space" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my-ate-space" }), nil, }, { "valid atespace: repeat dashes", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my---ate---space" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my---ate---space" }), nil, }, { "valid atespace: alphanumeric", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my-123-atespace" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my-123-atespace" }), nil, }, { "valid atespace: leading numeric", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "123-atespace" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "123-atespace" }), nil, }, { "valid atespace: trailing numeric", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my-123" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my-123" }), nil, }, { "valid atespace: fully numeric", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "123" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "123" }), nil, }, { "valid atespace: long", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = strings.Repeat("x", 63) }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = strings.Repeat("x", 63) }), nil, }, { "invalid atespace: uppercase", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "MYATESPACE" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "MYATESPACE" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: leading dash", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "-atespace" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "-atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: trailing dash", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my-" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my-" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: dots", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my.atespace" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my.atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: underscores", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my_atespace" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my_atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: bang", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my!atespace" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my!atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: at", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my@atespace" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my@atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: pound", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my#atespace" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my#atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: dollar", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my$atespace" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my$atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: percent", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my%%atespace" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my%%atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: caret", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my^atespace" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my^atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: ampersand", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my&atespace" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my&atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: star", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = "my*atespace" }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = "my*atespace" }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid atespace: too long", - valid(func(r *ateapipb.ObjectRef) { r.Atespace = strings.Repeat("x", 64) }), + valid(func(r *ateapi.ObjectRef) { r.Atespace = strings.Repeat("x", 64) }), field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "missing name", - valid(func(r *ateapipb.ObjectRef) { r.Name = "" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "" }), field.ErrorList{field.Required(field.NewPath("name"), "")}, }, { "valid name: alphabetic", - valid(func(r *ateapipb.ObjectRef) { r.Name = "myname" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "myname" }), nil, }, { "valid name: dashes", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my-na-me" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my-na-me" }), nil, }, { "valid name: repeat dashes", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my---na---me" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my---na---me" }), nil, }, { "valid name: alphanumeric", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my-123-name" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my-123-name" }), nil, }, { "invalid name: leading numeric", - valid(func(r *ateapipb.ObjectRef) { r.Name = "123-name" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "123-name" }), nil, }, { "invalid name: trailing numeric", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my-123" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my-123" }), nil, }, { "invalid name: fully numeric", - valid(func(r *ateapipb.ObjectRef) { r.Name = "123" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "123" }), nil, }, { "valid name: long", - valid(func(r *ateapipb.ObjectRef) { r.Name = strings.Repeat("x", 63) }), + valid(func(r *ateapi.ObjectRef) { r.Name = strings.Repeat("x", 63) }), nil, }, { "invalid name: uppercase", - valid(func(r *ateapipb.ObjectRef) { r.Name = "MYNAME" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "MYNAME" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: leading dash", - valid(func(r *ateapipb.ObjectRef) { r.Name = "-name" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "-name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: trailing dash", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my-" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my-" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: dots", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my.name" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my.name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: underscores", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my_name" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my_name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: bang", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my!name" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my!name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: at", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my@name" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my@name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: pound", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my#name" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my#name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: dollar", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my$name" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my$name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: percent", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my%%name" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my%%name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: caret", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my^name" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my^name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: ampersand", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my&name" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my&name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: star", - valid(func(r *ateapipb.ObjectRef) { r.Name = "my*name" }), + valid(func(r *ateapi.ObjectRef) { r.Name = "my*name" }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid name: too long", - valid(func(r *ateapipb.ObjectRef) { r.Name = strings.Repeat("x", 64) }), + valid(func(r *ateapi.ObjectRef) { r.Name = strings.Repeat("x", 64) }), field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }} for _, tt := range tests { @@ -652,21 +652,21 @@ func TestValidateObjectRef(t *testing.T) { } } -func validSystemInfoVolumeSource(mutate ...func(*ateapipb.SystemInfoVolumeSource)) *ateapipb.SystemInfoVolumeSource { +func validSystemInfoVolumeSource(mutate ...func(*ateapi.SystemInfoVolumeSource)) *ateapi.SystemInfoVolumeSource { // This is valid with as many fields populated as possible. - s := &ateapipb.SystemInfoVolumeSource{ - DataSources: []*ateapipb.SystemInfoDataSource{{ - ActorMetadata: &ateapipb.ActorMetadataDataSource{ - Items: []*ateapipb.ActorMetadataItem{{ - Field: ateapipb.ActorMetadataField_ACTOR_METADATA_FIELD_NAME, + s := &ateapi.SystemInfoVolumeSource{ + DataSources: []*ateapi.SystemInfoDataSource{{ + ActorMetadata: &ateapi.ActorMetadataDataSource{ + Items: []*ateapi.ActorMetadataItem{{ + Field: ateapi.ActorMetadataField_ACTOR_METADATA_FIELD_NAME, Path: "actor-name", }, { - Field: ateapipb.ActorMetadataField_ACTOR_METADATA_FIELD_UID, + Field: ateapi.ActorMetadataField_ACTOR_METADATA_FIELD_UID, Path: "actor-uid", }}, }, }, { - TrustBundle: &ateapipb.TrustBundleDataSource{ + TrustBundle: &ateapi.TrustBundleDataSource{ Names: []string{"egress-mitm.ate.dev"}, Path: "trust-bundle.pem", }, @@ -685,34 +685,34 @@ func TestValidateSystemInfoVolumeSource(t *testing.T) { tests := []struct { name string - obj *ateapipb.SystemInfoVolumeSource + obj *ateapi.SystemInfoVolumeSource want field.ErrorList }{{ name: "valid", obj: valid(), }, { name: "valid: no data sources", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { s.DataSources = nil }), + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { s.DataSources = nil }), }, { name: "too many data sources", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { for len(s.DataSources) <= 8 { - s.DataSources = append(s.DataSources, &ateapipb.SystemInfoDataSource{ - TrustBundle: &ateapipb.TrustBundleDataSource{Names: []string{"egress-mitm.ate.dev"}, Path: "tb.pem"}, + s.DataSources = append(s.DataSources, &ateapi.SystemInfoDataSource{ + TrustBundle: &ateapi.TrustBundleDataSource{Names: []string{"egress-mitm.ate.dev"}, Path: "tb.pem"}, }) } }), want: field.ErrorList{field.TooMany(dsPath, 9, 8).WithOrigin("maxItems")}, }, { name: "no union member set", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { s.DataSources[0].ActorMetadata = nil }), want: field.ErrorList{field.Invalid(dsPath.Index(0), nil, "").WithOrigin("union")}, }, { name: "both union members set", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { - s.DataSources[0].TrustBundle = &ateapipb.TrustBundleDataSource{ + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { + s.DataSources[0].TrustBundle = &ateapi.TrustBundleDataSource{ Names: []string{"egress-mitm.ate.dev"}, Path: "tb2.pem", } @@ -720,77 +720,77 @@ func TestValidateSystemInfoVolumeSource(t *testing.T) { want: field.ErrorList{field.Invalid(dsPath.Index(0), nil, "").WithOrigin("union")}, }, { name: "empty items", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { s.DataSources[0].ActorMetadata.Items = nil }), want: field.ErrorList{field.Required(itemsPath, "")}, }, { name: "duplicate projected field", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { - s.DataSources[0].ActorMetadata.Items[1].Field = ateapipb.ActorMetadataField_ACTOR_METADATA_FIELD_NAME + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { + s.DataSources[0].ActorMetadata.Items[1].Field = ateapi.ActorMetadataField_ACTOR_METADATA_FIELD_NAME }), want: field.ErrorList{field.Duplicate(itemsPath.Index(1), nil)}, }, { name: "unspecified item field", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { - s.DataSources[0].ActorMetadata.Items[0].Field = ateapipb.ActorMetadataField_ACTOR_METADATA_FIELD_UNSPECIFIED + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { + s.DataSources[0].ActorMetadata.Items[0].Field = ateapi.ActorMetadataField_ACTOR_METADATA_FIELD_UNSPECIFIED }), want: field.ErrorList{field.Required(itemsPath.Index(0).Child("field"), "")}, }, { name: "item field outside the enum", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { - s.DataSources[0].ActorMetadata.Items[0].Field = ateapipb.ActorMetadataField(99) + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { + s.DataSources[0].ActorMetadata.Items[0].Field = ateapi.ActorMetadataField(99) }), want: field.ErrorList{field.Invalid(itemsPath.Index(0).Child("field"), nil, "").WithOrigin("maximum")}, }, { name: "negative item field", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { - s.DataSources[0].ActorMetadata.Items[0].Field = ateapipb.ActorMetadataField(-1) + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { + s.DataSources[0].ActorMetadata.Items[0].Field = ateapi.ActorMetadataField(-1) }), want: field.ErrorList{field.Invalid(itemsPath.Index(0).Child("field"), nil, "").WithOrigin("minimum")}, }, { name: "empty item path", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { s.DataSources[0].ActorMetadata.Items[0].Path = "" }), want: field.ErrorList{field.Required(itemsPath.Index(0).Child("path"), "")}, }, { name: "item path too long", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { s.DataSources[0].ActorMetadata.Items[0].Path = strings.Repeat("p", 256) }), want: field.ErrorList{field.TooLong(itemsPath.Index(0).Child("path"), nil, 255).WithOrigin("maxLength")}, }, { name: "item path traversal", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { s.DataSources[0].ActorMetadata.Items[0].Path = "../../traversal-escape" }), want: field.ErrorList{field.Invalid(itemsPath.Index(0).Child("path"), nil, "")}, }, { name: "trust bundle path traversal", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { s.DataSources[1].TrustBundle.Path = "../escape" }), want: field.ErrorList{field.Invalid(dsPath.Index(1).Child("trust_bundle", "path"), nil, "")}, }, { name: "duplicate path within items", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { s.DataSources[0].ActorMetadata.Items[1].Path = "actor-name" }), want: field.ErrorList{field.Duplicate(itemsPath.Index(1).Child("path"), nil)}, }, { name: "duplicate path across data sources", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { s.DataSources[1].TrustBundle.Path = "actor-uid" }), want: field.ErrorList{field.Duplicate(dsPath.Index(1).Child("trust_bundle", "path"), nil)}, }, { name: "second actor_metadata entry", - obj: valid(func(s *ateapipb.SystemInfoVolumeSource) { - s.DataSources = append(s.DataSources, &ateapipb.SystemInfoDataSource{ - ActorMetadata: &ateapipb.ActorMetadataDataSource{ - Items: []*ateapipb.ActorMetadataItem{{ - Field: ateapipb.ActorMetadataField_ACTOR_METADATA_FIELD_NAME, + obj: valid(func(s *ateapi.SystemInfoVolumeSource) { + s.DataSources = append(s.DataSources, &ateapi.SystemInfoDataSource{ + ActorMetadata: &ateapi.ActorMetadataDataSource{ + Items: []*ateapi.ActorMetadataItem{{ + Field: ateapi.ActorMetadataField_ACTOR_METADATA_FIELD_NAME, Path: "actor-name-2", }}, }, @@ -808,8 +808,8 @@ func TestValidateSystemInfoVolumeSource(t *testing.T) { } func TestValidateTrustBundleDataSource(t *testing.T) { - valid := func(mutate ...func(*ateapipb.TrustBundleDataSource)) *ateapipb.TrustBundleDataSource { - tb := &ateapipb.TrustBundleDataSource{ + valid := func(mutate ...func(*ateapi.TrustBundleDataSource)) *ateapi.TrustBundleDataSource { + tb := &ateapi.TrustBundleDataSource{ Names: []string{"egress-mitm.ate.dev"}, Path: "trust-bundle.pem", } @@ -821,45 +821,45 @@ func TestValidateTrustBundleDataSource(t *testing.T) { tests := []struct { name string - obj *ateapipb.TrustBundleDataSource + obj *ateapi.TrustBundleDataSource want field.ErrorList }{{ name: "valid", obj: valid(), }, { name: "valid: multiple names", - obj: valid(func(tb *ateapipb.TrustBundleDataSource) { + obj: valid(func(tb *ateapi.TrustBundleDataSource) { tb.Names = []string{"egress-mitm.ate.dev", "system-roots.ate.dev"} }), }, { name: "no names", - obj: valid(func(tb *ateapipb.TrustBundleDataSource) { tb.Names = nil }), + obj: valid(func(tb *ateapi.TrustBundleDataSource) { tb.Names = nil }), want: field.ErrorList{field.Required(field.NewPath("names"), "")}, }, { name: "too many names", - obj: valid(func(tb *ateapipb.TrustBundleDataSource) { + obj: valid(func(tb *ateapi.TrustBundleDataSource) { tb.Names = []string{"a", "b", "c", "d", "e", "f", "g", "h", "i"} }), want: field.ErrorList{field.TooMany(field.NewPath("names"), 9, 8).WithOrigin("maxItems")}, }, { name: "empty name", - obj: valid(func(tb *ateapipb.TrustBundleDataSource) { tb.Names = []string{""} }), + obj: valid(func(tb *ateapi.TrustBundleDataSource) { tb.Names = []string{""} }), want: field.ErrorList{field.TooShort(field.NewPath("names").Index(0), "", 1).WithOrigin("minLength")}, }, { name: "name too long", - obj: valid(func(tb *ateapipb.TrustBundleDataSource) { tb.Names = []string{strings.Repeat("n", 254)} }), + obj: valid(func(tb *ateapi.TrustBundleDataSource) { tb.Names = []string{strings.Repeat("n", 254)} }), want: field.ErrorList{field.TooLong(field.NewPath("names").Index(0), nil, 253).WithOrigin("maxLength")}, }, { name: "empty path", - obj: valid(func(tb *ateapipb.TrustBundleDataSource) { tb.Path = "" }), + obj: valid(func(tb *ateapi.TrustBundleDataSource) { tb.Path = "" }), want: field.ErrorList{field.Required(field.NewPath("path"), "")}, }, { name: "path too long", - obj: valid(func(tb *ateapipb.TrustBundleDataSource) { tb.Path = strings.Repeat("p", 256) }), + obj: valid(func(tb *ateapi.TrustBundleDataSource) { tb.Path = strings.Repeat("p", 256) }), want: field.ErrorList{field.TooLong(field.NewPath("path"), nil, 255).WithOrigin("maxLength")}, }, { name: "path traversal", - obj: valid(func(tb *ateapipb.TrustBundleDataSource) { tb.Path = "../escape" }), + obj: valid(func(tb *ateapi.TrustBundleDataSource) { tb.Path = "../escape" }), want: field.ErrorList{field.Invalid(field.NewPath("path"), nil, "")}, }} for _, tt := range tests { @@ -871,8 +871,8 @@ func TestValidateTrustBundleDataSource(t *testing.T) { } } -func validExternalVolume(mutate ...func(*ateapipb.ExternalVolumeStatus)) *ateapipb.ExternalVolumeStatus { - v := &ateapipb.ExternalVolumeStatus{ +func validExternalVolume(mutate ...func(*ateapi.ExternalVolumeStatus)) *ateapi.ExternalVolumeStatus { + v := &ateapi.ExternalVolumeStatus{ Name: "my-vol", StorageVolumeId: "valid-storage-id", VolumeType: "mock", @@ -888,57 +888,57 @@ func TestValidateExternalVolume(t *testing.T) { tests := []struct { name string - obj *ateapipb.ExternalVolumeStatus + obj *ateapi.ExternalVolumeStatus want field.ErrorList }{{ name: "valid external volume", obj: valid(), }, { name: "missing volume name", - obj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.Name = "" }), + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.Name = "" }), want: field.ErrorList{field.Required(field.NewPath("name"), "")}, }, { name: "invalid volume name", - obj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.Name = "NOT A VOLUME" }), + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.Name = "NOT A VOLUME" }), want: field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "valid external volume with empty storage volume id", - obj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.StorageVolumeId = "" }), + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.StorageVolumeId = "" }), }, { name: "invalid storage volume id with null U+0000", - obj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.StorageVolumeId = "vol\x00id" }), + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.StorageVolumeId = "vol\x00id" }), want: field.ErrorList{field.Invalid(field.NewPath("storage_volume_id"), nil, "")}, }, { name: "storage volume id too long", - obj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.StorageVolumeId = strings.Repeat("x", 257) }), + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.StorageVolumeId = strings.Repeat("x", 257) }), want: field.ErrorList{field.TooLong(field.NewPath("storage_volume_id"), nil, 256).WithOrigin("maxLength")}, }, { name: "missing volume type", - obj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.VolumeType = "" }), + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.VolumeType = "" }), want: field.ErrorList{field.Required(field.NewPath("volume_type"), "")}, }, { name: "invalid volume type with uppercase", - obj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.VolumeType = "MockPlugin" }), + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.VolumeType = "MockPlugin" }), want: field.ErrorList{field.Invalid(field.NewPath("volume_type"), nil, "")}, }, { name: "valid volume type with 253 characters", - obj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.VolumeType = strings.Repeat("a", 253) }), + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.VolumeType = strings.Repeat("a", 253) }), }, { name: "invalid volume type exceeding 253 characters", - obj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.VolumeType = strings.Repeat("a", 254) }), + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.VolumeType = strings.Repeat("a", 254) }), want: field.ErrorList{ field.Invalid(field.NewPath("volume_type"), nil, ""), field.TooLong(field.NewPath("volume_type"), nil, 253).WithOrigin("maxLength"), }, }, { name: "valid volume with substrate.io prefixed volume type", - obj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.VolumeType = "substrate.io/mock" }), + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.VolumeType = "substrate.io/mock" }), }, { name: "storage volume id at the bound", - obj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.StorageVolumeId = strings.Repeat("x", 256) }), + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.StorageVolumeId = strings.Repeat("x", 256) }), }, { name: "volume_context with many entries, as a CSI driver may return", - obj: valid(func(v *ateapipb.ExternalVolumeStatus) { + obj: valid(func(v *ateapi.ExternalVolumeStatus) { ctxMap := make(map[string]string, 100) for i := range 100 { ctxMap[fmt.Sprintf("key-%03d", i)] = "v" @@ -947,12 +947,12 @@ func TestValidateExternalVolume(t *testing.T) { }), }, { name: "volume_context with one long value, as a CSI driver may return", - obj: valid(func(v *ateapipb.ExternalVolumeStatus) { + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.VolumeContext = map[string]string{"attachment": strings.Repeat("v", 4000)} }), }, { name: "volume_context over the size bound", - obj: valid(func(v *ateapipb.ExternalVolumeStatus) { + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.VolumeContext = map[string]string{"attachment": strings.Repeat("v", 40*1024)} }), want: field.ErrorList{field.TooLong(field.NewPath("volume_context"), nil, 40*1024)}, @@ -970,8 +970,8 @@ func TestValidateExternalVolume_Update(t *testing.T) { tests := []struct { name string - oldObj *ateapipb.ExternalVolumeStatus - newObj *ateapipb.ExternalVolumeStatus + oldObj *ateapi.ExternalVolumeStatus + newObj *ateapi.ExternalVolumeStatus want field.ErrorList }{{ name: "unchanged volume is valid", @@ -979,32 +979,32 @@ func TestValidateExternalVolume_Update(t *testing.T) { newObj: valid(), }, { name: "name changed is invalid", - oldObj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.Name = "vol1" }), - newObj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.Name = "vol2" }), + oldObj: valid(func(v *ateapi.ExternalVolumeStatus) { v.Name = "vol1" }), + newObj: valid(func(v *ateapi.ExternalVolumeStatus) { v.Name = "vol2" }), want: field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("update")}, }, { name: "storage_volume_id transition from empty to non-empty is valid", - oldObj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.StorageVolumeId = "" }), - newObj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.StorageVolumeId = "vol-id-1" }), + oldObj: valid(func(v *ateapi.ExternalVolumeStatus) { v.StorageVolumeId = "" }), + newObj: valid(func(v *ateapi.ExternalVolumeStatus) { v.StorageVolumeId = "vol-id-1" }), }, { name: "storage_volume_id changed once set is invalid", - oldObj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.StorageVolumeId = "vol-id-1" }), - newObj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.StorageVolumeId = "vol-id-2" }), + oldObj: valid(func(v *ateapi.ExternalVolumeStatus) { v.StorageVolumeId = "vol-id-1" }), + newObj: valid(func(v *ateapi.ExternalVolumeStatus) { v.StorageVolumeId = "vol-id-2" }), want: field.ErrorList{field.Invalid(field.NewPath("storage_volume_id"), nil, "").WithOrigin("update")}, }, { name: "storage_volume_id unset once set is invalid", - oldObj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.StorageVolumeId = "vol-id-1" }), - newObj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.StorageVolumeId = "" }), + oldObj: valid(func(v *ateapi.ExternalVolumeStatus) { v.StorageVolumeId = "vol-id-1" }), + newObj: valid(func(v *ateapi.ExternalVolumeStatus) { v.StorageVolumeId = "" }), want: field.ErrorList{field.Invalid(field.NewPath("storage_volume_id"), nil, "").WithOrigin("update")}, }, { name: "volume_type changed is invalid", - oldObj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.VolumeType = "mock" }), - newObj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.VolumeType = "pd.csi.storage.gke.io" }), + oldObj: valid(func(v *ateapi.ExternalVolumeStatus) { v.VolumeType = "mock" }), + newObj: valid(func(v *ateapi.ExternalVolumeStatus) { v.VolumeType = "pd.csi.storage.gke.io" }), want: field.ErrorList{field.Invalid(field.NewPath("volume_type"), nil, "").WithOrigin("update")}, }, { name: "volume_context changed is valid", - oldObj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.VolumeContext = nil }), - newObj: valid(func(v *ateapipb.ExternalVolumeStatus) { v.VolumeContext = map[string]string{"foo": "bar"} }), + oldObj: valid(func(v *ateapi.ExternalVolumeStatus) { v.VolumeContext = nil }), + newObj: valid(func(v *ateapi.ExternalVolumeStatus) { v.VolumeContext = map[string]string{"foo": "bar"} }), }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1015,8 +1015,8 @@ func TestValidateExternalVolume_Update(t *testing.T) { } func TestValidateDeleteOptions(t *testing.T) { - valid := func(mutate ...func(*ateapipb.DeleteOptions)) *ateapipb.DeleteOptions { - tb := &ateapipb.DeleteOptions{} + valid := func(mutate ...func(*ateapi.DeleteOptions)) *ateapi.DeleteOptions { + tb := &ateapi.DeleteOptions{} for _, m := range mutate { m(tb) } @@ -1025,26 +1025,26 @@ func TestValidateDeleteOptions(t *testing.T) { tests := []struct { name string - obj *ateapipb.DeleteOptions + obj *ateapi.DeleteOptions want field.ErrorList }{{ name: "valid", obj: valid(), // all optional fields }, { name: "valid version", - obj: valid(func(do *ateapipb.DeleteOptions) { do.Version = 1 }), + obj: valid(func(do *ateapi.DeleteOptions) { do.Version = 1 }), want: nil, }, { name: "invalid version", - obj: valid(func(do *ateapipb.DeleteOptions) { do.Version = -1 }), + obj: valid(func(do *ateapi.DeleteOptions) { do.Version = -1 }), want: field.ErrorList{field.Invalid(field.NewPath("version"), nil, "").WithOrigin("minimum")}, }, { name: "valid uid", - obj: valid(func(do *ateapipb.DeleteOptions) { do.Uid = "11111111-2222-3333-4444-555555555555" }), + obj: valid(func(do *ateapi.DeleteOptions) { do.Uid = "11111111-2222-3333-4444-555555555555" }), want: nil, }, { name: "invalid uid", - obj: valid(func(do *ateapipb.DeleteOptions) { do.Uid = "not a uid" }), + obj: valid(func(do *ateapi.DeleteOptions) { do.Uid = "not a uid" }), want: field.ErrorList{field.Invalid(field.NewPath("uid"), nil, "").WithOrigin("format=k8s-uuid")}, }} for _, tt := range tests { @@ -1056,8 +1056,8 @@ func TestValidateDeleteOptions(t *testing.T) { } } -func validObjectSnapshot(mutate ...func(*ateapipb.ObjectSnapshot)) *ateapipb.ObjectSnapshot { - s := &ateapipb.ObjectSnapshot{ +func validObjectSnapshot(mutate ...func(*ateapi.ObjectSnapshot)) *ateapi.ObjectSnapshot { + s := &ateapi.ObjectSnapshot{ SnapshotUri: "gs://private/atespaces/as/actors/" + someActorUID + "/snapshots/snap-1", } for _, m := range mutate { @@ -1066,9 +1066,9 @@ func validObjectSnapshot(mutate ...func(*ateapipb.ObjectSnapshot)) *ateapipb.Obj return s } -func validSnapshotStorage(mutate ...func(*ateapipb.SnapshotStorage)) *ateapipb.SnapshotStorage { - ss := &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, +func validSnapshotStorage(mutate ...func(*ateapi.SnapshotStorage)) *ateapi.SnapshotStorage { + ss := &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, Object: validObjectSnapshot(), } for _, m := range mutate { @@ -1077,12 +1077,12 @@ func validSnapshotStorage(mutate ...func(*ateapipb.SnapshotStorage)) *ateapipb.S return ss } -func validSnapshot(mutate ...func(*ateapipb.Snapshot)) *ateapipb.Snapshot { - s := &ateapipb.Snapshot{ +func validSnapshot(mutate ...func(*ateapi.Snapshot)) *ateapi.Snapshot { + s := &ateapi.Snapshot{ Uuid: "snap-1", Generation: 1, - Owner: ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + Owner: ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, Locality: "node-1", DurableSnapshot: validSnapshotStorage(), } @@ -1094,15 +1094,15 @@ func validSnapshot(mutate ...func(*ateapipb.Snapshot)) *ateapipb.Snapshot { // badSnapshot violates Snapshot's rules at once, so a caller can assert that a // containing type reaches every field of it. -func badSnapshot(mutate ...func(*ateapipb.Snapshot)) *ateapipb.Snapshot { - breakIt := func(s *ateapipb.Snapshot) { - s.Fidelity = ateapipb.SnapshotFidelity(4) - s.DurableSnapshot = &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: ""}, +func badSnapshot(mutate ...func(*ateapi.Snapshot)) *ateapi.Snapshot { + breakIt := func(s *ateapi.Snapshot) { + s.Fidelity = ateapi.SnapshotFidelity(4) + s.DurableSnapshot = &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, + Object: &ateapi.ObjectSnapshot{SnapshotUri: ""}, } } - return validSnapshot(append([]func(*ateapipb.Snapshot){breakIt}, mutate...)...) + return validSnapshot(append([]func(*ateapi.Snapshot){breakIt}, mutate...)...) } func TestValidateSnapshot(t *testing.T) { @@ -1119,7 +1119,7 @@ func TestValidateSnapshot(t *testing.T) { tests := []struct { name string - obj *ateapipb.Snapshot + obj *ateapi.Snapshot want field.ErrorList }{ { @@ -1128,110 +1128,110 @@ func TestValidateSnapshot(t *testing.T) { }, { name: "valid optional fields unset", - obj: valid(func(s *ateapipb.Snapshot) { + obj: valid(func(s *ateapi.Snapshot) { s.Locality = "" }), }, { name: "missing uuid", - obj: valid(func(s *ateapipb.Snapshot) { s.Uuid = "" }), + obj: valid(func(s *ateapi.Snapshot) { s.Uuid = "" }), want: field.ErrorList{field.Required(uuidPath, "")}, }, { name: "invalid uuid", - obj: valid(func(s *ateapipb.Snapshot) { s.Uuid = "SNAP 1" }), + obj: valid(func(s *ateapi.Snapshot) { s.Uuid = "SNAP 1" }), want: field.ErrorList{field.Invalid(uuidPath, nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "invalid locality", - obj: valid(func(s *ateapipb.Snapshot) { s.Locality = "NODE 1" }), + obj: valid(func(s *ateapi.Snapshot) { s.Locality = "NODE 1" }), want: field.ErrorList{field.Invalid(localityPath, nil, "").WithOrigin("format=k8s-long-name")}, }, { name: "missing generation", - obj: valid(func(s *ateapipb.Snapshot) { s.Generation = 0 }), + obj: valid(func(s *ateapi.Snapshot) { s.Generation = 0 }), want: field.ErrorList{field.Required(genPath, "")}, }, { name: "negative generation", - obj: valid(func(s *ateapipb.Snapshot) { s.Generation = -1 }), + obj: valid(func(s *ateapi.Snapshot) { s.Generation = -1 }), want: field.ErrorList{field.Invalid(genPath, nil, "").WithOrigin("minimum")}, }, { name: "missing owner", - obj: valid(func(s *ateapipb.Snapshot) { s.Owner = ateapipb.SnapshotOwner_SNAPSHOT_OWNER_UNSPECIFIED }), + obj: valid(func(s *ateapi.Snapshot) { s.Owner = ateapi.SnapshotOwner_SNAPSHOT_OWNER_UNSPECIFIED }), want: field.ErrorList{field.Required(ownerPath, "")}, }, { name: "owner above the enum", - obj: valid(func(s *ateapipb.Snapshot) { s.Owner = ateapipb.SnapshotOwner(3) }), + obj: valid(func(s *ateapi.Snapshot) { s.Owner = ateapi.SnapshotOwner(3) }), want: field.ErrorList{field.Invalid(ownerPath, nil, "").WithOrigin("maximum")}, }, { name: "valid fidelity: volumes", - obj: valid(func(s *ateapipb.Snapshot) { - s.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES + obj: valid(func(s *ateapi.Snapshot) { + s.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES }), }, { name: "missing fidelity", - obj: valid(func(s *ateapipb.Snapshot) { - s.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED + obj: valid(func(s *ateapi.Snapshot) { + s.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED }), want: field.ErrorList{field.Required(fidelityPath, "")}, }, { name: "valid without durable_snapshot", - obj: valid(func(s *ateapipb.Snapshot) { s.DurableSnapshot = nil }), + obj: valid(func(s *ateapi.Snapshot) { s.DurableSnapshot = nil }), }, { name: "missing durable_snapshot.status", - obj: valid(func(s *ateapipb.Snapshot) { - s.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_UNSPECIFIED + obj: valid(func(s *ateapi.Snapshot) { + s.DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_UNSPECIFIED }), want: field.ErrorList{field.Required(statusPath, "")}, }, { name: "negative durable_snapshot.status", - obj: valid(func(s *ateapipb.Snapshot) { - s.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus(-1) + obj: valid(func(s *ateapi.Snapshot) { + s.DurableSnapshot.Status = ateapi.SnapshotStorageStatus(-1) }), want: field.ErrorList{field.Invalid(statusPath, nil, "").WithOrigin("minimum")}, }, { name: "durable_snapshot.status above the enum", - obj: valid(func(s *ateapipb.Snapshot) { - s.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus(3) + obj: valid(func(s *ateapi.Snapshot) { + s.DurableSnapshot.Status = ateapi.SnapshotStorageStatus(3) }), want: field.ErrorList{field.Invalid(statusPath, nil, "").WithOrigin("maximum")}, }, { name: "missing durable_snapshot.object", - obj: valid(func(s *ateapipb.Snapshot) { + obj: valid(func(s *ateapi.Snapshot) { s.DurableSnapshot.Object = nil }), want: field.ErrorList{field.Required(objectPath, "")}, }, { name: "missing snapshot_uri", - obj: valid(func(s *ateapipb.Snapshot) { s.DurableSnapshot.Object.SnapshotUri = "" }), + obj: valid(func(s *ateapi.Snapshot) { s.DurableSnapshot.Object.SnapshotUri = "" }), want: field.ErrorList{field.Required(uriPath, "")}, }, { name: "snapshot_uri too long", - obj: valid(func(s *ateapipb.Snapshot) { + obj: valid(func(s *ateapi.Snapshot) { s.DurableSnapshot.Object.SnapshotUri = "gs://" + strings.Repeat("x", 2044) }), want: field.ErrorList{field.TooLong(uriPath, nil, 2048).WithOrigin("maxLength")}, }, { name: "fidelity above the enum", - obj: valid(func(s *ateapipb.Snapshot) { s.Fidelity = ateapipb.SnapshotFidelity(4) }), + obj: valid(func(s *ateapi.Snapshot) { s.Fidelity = ateapi.SnapshotFidelity(4) }), want: field.ErrorList{field.Invalid(fidelityPath, nil, "").WithOrigin("maximum")}, }, { name: "negative fidelity", - obj: valid(func(s *ateapipb.Snapshot) { s.Fidelity = ateapipb.SnapshotFidelity(-1) }), + obj: valid(func(s *ateapi.Snapshot) { s.Fidelity = ateapi.SnapshotFidelity(-1) }), want: field.ErrorList{field.Invalid(fidelityPath, nil, "").WithOrigin("minimum")}, }, { @@ -1258,8 +1258,8 @@ func TestValidateSnapshotUpdate(t *testing.T) { tests := []struct { name string - oldObj *ateapipb.Snapshot - newObj *ateapipb.Snapshot + oldObj *ateapi.Snapshot + newObj *ateapi.Snapshot want field.ErrorList }{ { @@ -1278,28 +1278,28 @@ func TestValidateSnapshotUpdate(t *testing.T) { { name: "fidelity changed to a valid value", oldObj: valid(), - newObj: valid(func(s *ateapipb.Snapshot) { - s.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES + newObj: valid(func(s *ateapi.Snapshot) { + s.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES }), }, { name: "fidelity cleared", oldObj: valid(), - newObj: valid(func(s *ateapipb.Snapshot) { - s.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED + newObj: valid(func(s *ateapi.Snapshot) { + s.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED }), want: field.ErrorList{field.Required(fidelityPath, "")}, }, { name: "fidelity changed to a value outside the enum", oldObj: valid(), - newObj: valid(func(s *ateapipb.Snapshot) { s.Fidelity = ateapipb.SnapshotFidelity(4) }), + newObj: valid(func(s *ateapi.Snapshot) { s.Fidelity = ateapi.SnapshotFidelity(4) }), want: field.ErrorList{field.Invalid(fidelityPath, nil, "").WithOrigin("maximum")}, }, { name: "snapshot_uri cleared", oldObj: valid(), - newObj: valid(func(s *ateapipb.Snapshot) { s.DurableSnapshot.Object.SnapshotUri = "" }), + newObj: valid(func(s *ateapi.Snapshot) { s.DurableSnapshot.Object.SnapshotUri = "" }), want: field.ErrorList{field.Required(uriPath, "")}, }, { @@ -1307,14 +1307,14 @@ func TestValidateSnapshotUpdate(t *testing.T) { // can still be repaired, one field at a time. name: "fidelity repaired", oldObj: badSnapshot(), - newObj: badSnapshot(func(s *ateapipb.Snapshot) { - s.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + newObj: badSnapshot(func(s *ateapi.Snapshot) { + s.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY }), }, { name: "snapshot_uri changed to a value that is too long", oldObj: valid(), - newObj: valid(func(s *ateapipb.Snapshot) { + newObj: valid(func(s *ateapi.Snapshot) { s.DurableSnapshot.Object.SnapshotUri = "gs://" + strings.Repeat("x", 2044) }), want: field.ErrorList{field.TooLong(uriPath, nil, 2048).WithOrigin("maxLength")}, @@ -1322,7 +1322,7 @@ func TestValidateSnapshotUpdate(t *testing.T) { { name: "snapshot_uri repaired", oldObj: badSnapshot(), - newObj: badSnapshot(func(s *ateapipb.Snapshot) { s.DurableSnapshot.Object.SnapshotUri = validObjectSnapshot().SnapshotUri }), + newObj: badSnapshot(func(s *ateapi.Snapshot) { s.DurableSnapshot.Object.SnapshotUri = validObjectSnapshot().SnapshotUri }), }, { name: "every field repaired", @@ -1356,8 +1356,8 @@ func TestValidateNestedSnapshot(t *testing.T) { // write, as an update against the stored one. op := MakeUpdateOp(context.Background()) oldVal := validActor(withActorStatus()) - newVal := validActor(withActorStatus(func(s *ateapipb.ActorStatus) { - s.Snapshots = []*ateapipb.Snapshot{badSnapshot()} + newVal := validActor(withActorStatus(func(s *ateapi.ActorStatus) { + s.Snapshots = []*ateapi.Snapshot{badSnapshot()} })) return Validate_Actor(ctx, op, nil, newVal, oldVal) }, @@ -1367,7 +1367,7 @@ func TestValidateNestedSnapshot(t *testing.T) { path: field.NewPath("status", "snapshot"), validate: func(ctx context.Context) field.ErrorList { op := MakeCreateOp(context.Background()) - obj := validTag(func(tag *ateapipb.Tag) { + obj := validTag(func(tag *ateapi.Tag) { tag.Status.Snapshot = badSnapshot() }) return Validate_Tag(ctx, op, nil, obj, nil) @@ -1385,15 +1385,15 @@ func TestValidateNestedSnapshot(t *testing.T) { } } -func validTag(mutate ...func(*ateapipb.Tag)) *ateapipb.Tag { - tag := &ateapipb.Tag{ +func validTag(mutate ...func(*ateapi.Tag)) *ateapi.Tag { + tag := &ateapi.Tag{ Metadata: validResourceMetadata(), - Status: &ateapipb.TagStatus{ - Snapshot: validSnapshot(func(s *ateapipb.Snapshot) { s.Owner = ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG }), + Status: &ateapi.TagStatus{ + Snapshot: validSnapshot(func(s *ateapi.Snapshot) { s.Owner = ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG }), ActorTemplateUid: someActorUID, }, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - SourceActor: &ateapipb.ObjectRef{Atespace: "as", Name: "nm"}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + SourceActor: &ateapi.ObjectRef{Atespace: "as", Name: "nm"}, } for _, m := range mutate { m(tag) @@ -1410,7 +1410,7 @@ func TestValidateTag(t *testing.T) { tests := []struct { name string - obj *ateapipb.Tag + obj *ateapi.Tag want field.ErrorList }{ { @@ -1419,76 +1419,76 @@ func TestValidateTag(t *testing.T) { }, { name: "valid scope: published", - obj: valid(func(tag *ateapipb.Tag) { - tag.Scope = ateapipb.TagScope_TAG_SCOPE_PUBLISHED + obj: valid(func(tag *ateapi.Tag) { + tag.Scope = ateapi.TagScope_TAG_SCOPE_PUBLISHED }), }, { name: "missing status", - obj: valid(func(tag *ateapipb.Tag) { tag.Status = nil }), + obj: valid(func(tag *ateapi.Tag) { tag.Status = nil }), }, { name: "missing metadata", - obj: valid(func(tag *ateapipb.Tag) { tag.Metadata = nil }), + obj: valid(func(tag *ateapi.Tag) { tag.Metadata = nil }), want: field.ErrorList{field.Required(metadataPath, "")}, }, { // A tag is addressed through the atespace that owns it, so unlike a // global-scoped resource it always has to name one. name: "missing metadata.atespace", - obj: valid(func(tag *ateapipb.Tag) { tag.Metadata.Atespace = "" }), + obj: valid(func(tag *ateapi.Tag) { tag.Metadata.Atespace = "" }), want: field.ErrorList{field.Required(metadataPath.Child("atespace"), "")}, }, { name: "invalid nested metadata.name", - obj: valid(func(tag *ateapipb.Tag) { tag.Metadata.Name = "" }), + obj: valid(func(tag *ateapi.Tag) { tag.Metadata.Name = "" }), want: field.ErrorList{field.Required(metadataPath.Child("name"), "")}, }, { name: "unspecified scope", - obj: valid(func(tag *ateapipb.Tag) { - tag.Scope = ateapipb.TagScope_TAG_SCOPE_UNSPECIFIED + obj: valid(func(tag *ateapi.Tag) { + tag.Scope = ateapi.TagScope_TAG_SCOPE_UNSPECIFIED }), want: field.ErrorList{field.Required(scopePath, "")}, }, { name: "scope above the enum", - obj: valid(func(tag *ateapipb.Tag) { tag.Scope = ateapipb.TagScope(3) }), + obj: valid(func(tag *ateapi.Tag) { tag.Scope = ateapi.TagScope(3) }), want: field.ErrorList{field.Invalid(scopePath, nil, "").WithOrigin("maximum")}, }, { name: "negative scope", - obj: valid(func(tag *ateapipb.Tag) { tag.Scope = ateapipb.TagScope(-1) }), + obj: valid(func(tag *ateapi.Tag) { tag.Scope = ateapi.TagScope(-1) }), want: field.ErrorList{field.Invalid(scopePath, nil, "").WithOrigin("minimum")}, }, { name: "missing source_actor", - obj: valid(func(tag *ateapipb.Tag) { tag.SourceActor = nil }), + obj: valid(func(tag *ateapi.Tag) { tag.SourceActor = nil }), want: field.ErrorList{field.Required(sourceActorPath, "")}, }, { name: "missing source_actor.atespace", - obj: valid(func(tag *ateapipb.Tag) { tag.SourceActor.Atespace = "" }), + obj: valid(func(tag *ateapi.Tag) { tag.SourceActor.Atespace = "" }), want: field.ErrorList{field.Required(sourceActorPath.Child("atespace"), "")}, }, { name: "missing status.actor_template_uid", - obj: valid(func(tag *ateapipb.Tag) { tag.Status.ActorTemplateUid = "" }), + obj: valid(func(tag *ateapi.Tag) { tag.Status.ActorTemplateUid = "" }), want: field.ErrorList{field.Required(statusPath.Child("actor_template_uid"), "")}, }, { name: "malformed status.actor_template_uid", - obj: valid(func(tag *ateapipb.Tag) { tag.Status.ActorTemplateUid = "not-a-uuid" }), + obj: valid(func(tag *ateapi.Tag) { tag.Status.ActorTemplateUid = "not-a-uuid" }), want: field.ErrorList{field.Invalid(statusPath.Child("actor_template_uid"), nil, "").WithOrigin("format=k8s-uuid")}, }, { // A reserved tag has no snapshot until the tag workflow records it. name: "missing status.snapshot", - obj: valid(func(tag *ateapipb.Tag) { tag.Status.Snapshot = nil }), + obj: valid(func(tag *ateapi.Tag) { tag.Status.Snapshot = nil }), }, { name: "missing status.snapshot.durable_snapshot", - obj: valid(func(tag *ateapipb.Tag) { tag.Status.Snapshot.DurableSnapshot = nil }), + obj: valid(func(tag *ateapi.Tag) { tag.Status.Snapshot.DurableSnapshot = nil }), want: field.ErrorList{field.Required(statusPath.Child("snapshot", "durable_snapshot"), "")}, }, } @@ -1505,8 +1505,8 @@ func TestValidateTagUpdate(t *testing.T) { tests := []struct { name string - oldObj *ateapipb.Tag // should always be valid - newObj *ateapipb.Tag + oldObj *ateapi.Tag // should always be valid + newObj *ateapi.Tag want field.ErrorList }{ { @@ -1519,20 +1519,20 @@ func TestValidateTagUpdate(t *testing.T) { // every reference to it. name: "metadata.atespace changed", oldObj: valid(), - newObj: valid(func(tag *ateapipb.Tag) { tag.Metadata.Atespace = "other" }), + newObj: valid(func(tag *ateapi.Tag) { tag.Metadata.Atespace = "other" }), want: field.ErrorList{field.Invalid(field.NewPath("metadata", "atespace"), nil, "").WithOrigin("immutable")}, }, { name: "source_actor changed", oldObj: valid(), - newObj: valid(func(tag *ateapipb.Tag) { tag.SourceActor.Name = "other" }), + newObj: valid(func(tag *ateapi.Tag) { tag.SourceActor.Name = "other" }), want: field.ErrorList{field.Invalid(field.NewPath("source_actor"), nil, "").WithOrigin("immutable")}, }, { name: "scope changed", oldObj: valid(), - newObj: valid(func(tag *ateapipb.Tag) { - tag.Scope = ateapipb.TagScope_TAG_SCOPE_PUBLISHED + newObj: valid(func(tag *ateapi.Tag) { + tag.Scope = ateapi.TagScope_TAG_SCOPE_PUBLISHED }), }, } @@ -1550,7 +1550,7 @@ func TestValidateTagUpdate(t *testing.T) { // drift; tag_test.go covers what the handlers make of it. func TestValidateTagRequestPayloads(t *testing.T) { validTag := validTag - validRef := func() *ateapipb.ObjectRef { return &ateapipb.ObjectRef{Atespace: "as", Name: "nm"} } + validRef := func() *ateapi.ObjectRef { return &ateapi.ObjectRef{Atespace: "as", Name: "nm"} } tagPath := field.NewPath("tag") tests := []struct { @@ -1561,14 +1561,14 @@ func TestValidateTagRequestPayloads(t *testing.T) { { name: "create: valid", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.CreateTagRequest{Tag: validTag()} + req := &ateapi.CreateTagRequest{Tag: validTag()} return Validate_CreateTagRequest(ctx, op, nil, req, nil) }, }, { name: "create: missing tag", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.CreateTagRequest{} + req := &ateapi.CreateTagRequest{} return Validate_CreateTagRequest(ctx, op, nil, req, nil) }, want: field.ErrorList{field.Required(tagPath, "")}, @@ -1578,7 +1578,7 @@ func TestValidateTagRequestPayloads(t *testing.T) { validate: func(ctx context.Context, op operation.Operation) field.ErrorList { tag := validTag() tag.Status.Snapshot = badSnapshot() - req := &ateapipb.CreateTagRequest{Tag: tag} + req := &ateapi.CreateTagRequest{Tag: tag} return Validate_CreateTagRequest(ctx, op, nil, req, nil) }, want: field.ErrorList{ @@ -1589,14 +1589,14 @@ func TestValidateTagRequestPayloads(t *testing.T) { { name: "update: valid", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.UpdateTagRequest{Tag: validTag()} + req := &ateapi.UpdateTagRequest{Tag: validTag()} return Validate_UpdateTagRequest(ctx, op, nil, req, nil) }, }, { name: "update: missing tag", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.UpdateTagRequest{} + req := &ateapi.UpdateTagRequest{} return Validate_UpdateTagRequest(ctx, op, nil, req, nil) }, want: field.ErrorList{field.Required(tagPath, "")}, @@ -1608,21 +1608,21 @@ func TestValidateTagRequestPayloads(t *testing.T) { validate: func(ctx context.Context, op operation.Operation) field.ErrorList { tag := validTag() tag.Status.Snapshot = badSnapshot() - req := &ateapipb.UpdateTagRequest{Tag: tag} + req := &ateapi.UpdateTagRequest{Tag: tag} return Validate_UpdateTagRequest(ctx, op, nil, req, nil) }, }, { name: "get: valid", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.GetTagRequest{Tag: validRef()} + req := &ateapi.GetTagRequest{Tag: validRef()} return Validate_GetTagRequest(ctx, op, nil, req, nil) }, }, { name: "get: missing tag", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.GetTagRequest{} + req := &ateapi.GetTagRequest{} return Validate_GetTagRequest(ctx, op, nil, req, nil) }, want: field.ErrorList{field.Required(tagPath, "")}, @@ -1632,7 +1632,7 @@ func TestValidateTagRequestPayloads(t *testing.T) { // naming only a name does not name a tag. name: "get: missing tag.atespace", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.GetTagRequest{Tag: &ateapipb.ObjectRef{Name: "nm"}} + req := &ateapi.GetTagRequest{Tag: &ateapi.ObjectRef{Name: "nm"}} return Validate_GetTagRequest(ctx, op, nil, req, nil) }, want: field.ErrorList{field.Required(tagPath.Child("atespace"), "")}, @@ -1640,7 +1640,7 @@ func TestValidateTagRequestPayloads(t *testing.T) { { name: "get: invalid tag.name", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.GetTagRequest{Tag: &ateapipb.ObjectRef{Atespace: "as", Name: "NM"}} + req := &ateapi.GetTagRequest{Tag: &ateapi.ObjectRef{Atespace: "as", Name: "NM"}} return Validate_GetTagRequest(ctx, op, nil, req, nil) }, want: field.ErrorList{field.Invalid(tagPath.Child("name"), nil, "").WithOrigin("format=k8s-short-name")}, @@ -1648,14 +1648,14 @@ func TestValidateTagRequestPayloads(t *testing.T) { { name: "delete: valid", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.DeleteTagRequest{Tag: validRef()} + req := &ateapi.DeleteTagRequest{Tag: validRef()} return Validate_DeleteTagRequest(ctx, op, nil, req, nil) }, }, { name: "delete: missing tag", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.DeleteTagRequest{} + req := &ateapi.DeleteTagRequest{} return Validate_DeleteTagRequest(ctx, op, nil, req, nil) }, want: field.ErrorList{field.Required(tagPath, "")}, @@ -1663,7 +1663,7 @@ func TestValidateTagRequestPayloads(t *testing.T) { { name: "delete: missing tag.atespace", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.DeleteTagRequest{Tag: &ateapipb.ObjectRef{Name: "nm"}} + req := &ateapi.DeleteTagRequest{Tag: &ateapi.ObjectRef{Name: "nm"}} return Validate_DeleteTagRequest(ctx, op, nil, req, nil) }, want: field.ErrorList{field.Required(tagPath.Child("atespace"), "")}, @@ -1673,14 +1673,14 @@ func TestValidateTagRequestPayloads(t *testing.T) { // how a client asks for every atespace at once. name: "list: empty request", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.ListTagsRequest{} + req := &ateapi.ListTagsRequest{} return Validate_ListTagsRequest(ctx, op, nil, req, nil) }, }, { name: "list: invalid atespace", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.ListTagsRequest{Atespace: "AS"} + req := &ateapi.ListTagsRequest{Atespace: "AS"} return Validate_ListTagsRequest(ctx, op, nil, req, nil) }, want: field.ErrorList{field.Invalid(field.NewPath("atespace"), nil, "").WithOrigin("format=k8s-short-name")}, @@ -1688,7 +1688,7 @@ func TestValidateTagRequestPayloads(t *testing.T) { { name: "list: negative page_size", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.ListTagsRequest{Options: &ateapipb.ListOptions{PageSize: -1}} + req := &ateapi.ListTagsRequest{Options: &ateapi.ListOptions{PageSize: -1}} return Validate_ListTagsRequest(ctx, op, nil, req, nil) }, want: field.ErrorList{field.Invalid(field.NewPath("options", "page_size"), nil, "").WithOrigin("minimum")}, @@ -1696,7 +1696,7 @@ func TestValidateTagRequestPayloads(t *testing.T) { { name: "list: over-long page_token", validate: func(ctx context.Context, op operation.Operation) field.ErrorList { - req := &ateapipb.ListTagsRequest{Options: &ateapipb.ListOptions{PageToken: strings.Repeat("t", 257)}} + req := &ateapi.ListTagsRequest{Options: &ateapi.ListOptions{PageToken: strings.Repeat("t", 257)}} return Validate_ListTagsRequest(ctx, op, nil, req, nil) }, want: field.ErrorList{field.TooLong(field.NewPath("options", "page_token"), nil, 256).WithOrigin("maxLength")}, @@ -1710,9 +1710,9 @@ func TestValidateTagRequestPayloads(t *testing.T) { } } -func validGoldenSnapshotStatus(mutate ...func(*ateapipb.GoldenSnapshotStatus)) *ateapipb.GoldenSnapshotStatus { - s := &ateapipb.GoldenSnapshotStatus{ - GoldenTag: &ateapipb.ObjectRef{Atespace: "team-a", Name: "01234567-89ab-cdef-0123-456789abcdef"}, +func validGoldenSnapshotStatus(mutate ...func(*ateapi.GoldenSnapshotStatus)) *ateapi.GoldenSnapshotStatus { + s := &ateapi.GoldenSnapshotStatus{ + GoldenTag: &ateapi.ObjectRef{Atespace: "team-a", Name: "01234567-89ab-cdef-0123-456789abcdef"}, SnapshotTime: ×tamppb.Timestamp{Seconds: 867}, } for _, m := range mutate { @@ -1727,7 +1727,7 @@ func TestValidateGoldenSnapshotStatus(t *testing.T) { tests := []struct { name string - obj *ateapipb.GoldenSnapshotStatus + obj *ateapi.GoldenSnapshotStatus want field.ErrorList }{ { @@ -1736,31 +1736,31 @@ func TestValidateGoldenSnapshotStatus(t *testing.T) { }, { name: "valid empty", - obj: &ateapipb.GoldenSnapshotStatus{}, + obj: &ateapi.GoldenSnapshotStatus{}, }, { name: "valid failed", - obj: &ateapipb.GoldenSnapshotStatus{ + obj: &ateapi.GoldenSnapshotStatus{ SnapshotTime: ×tamppb.Timestamp{Seconds: 867}, ErrorMessage: "GoldenActorCrashed: golden actor crashed before its snapshot was taken", }, }, { name: "error_message at the bound", - obj: valid(func(s *ateapipb.GoldenSnapshotStatus) { + obj: valid(func(s *ateapi.GoldenSnapshotStatus) { s.ErrorMessage = strings.Repeat("x", 4096) }), }, { name: "error_message too long", - obj: valid(func(s *ateapipb.GoldenSnapshotStatus) { + obj: valid(func(s *ateapi.GoldenSnapshotStatus) { s.ErrorMessage = strings.Repeat("x", 4097) }), want: field.ErrorList{field.TooLong(msgPath, nil, 4096).WithOrigin("maxLength")}, }, { name: "golden_tag missing atespace", - obj: valid(func(s *ateapipb.GoldenSnapshotStatus) { + obj: valid(func(s *ateapi.GoldenSnapshotStatus) { s.GoldenTag.Atespace = "" }), want: field.ErrorList{field.Required(field.NewPath("golden_tag", "atespace"), "")}, @@ -1779,8 +1779,8 @@ func TestValidateGoldenSnapshotStatusUpdate(t *testing.T) { tests := []struct { name string - oldObj *ateapipb.GoldenSnapshotStatus // should always be valid - newObj *ateapipb.GoldenSnapshotStatus + oldObj *ateapi.GoldenSnapshotStatus // should always be valid + newObj *ateapi.GoldenSnapshotStatus want field.ErrorList }{ { @@ -1793,26 +1793,26 @@ func TestValidateGoldenSnapshotStatusUpdate(t *testing.T) { // deadline must stay mutable. name: "snapshot_time changed", oldObj: valid(), - newObj: valid(func(s *ateapipb.GoldenSnapshotStatus) { + newObj: valid(func(s *ateapi.GoldenSnapshotStatus) { s.SnapshotTime = ×tamppb.Timestamp{Seconds: 5309} }), }, { name: "snapshot_time set", - oldObj: &ateapipb.GoldenSnapshotStatus{}, + oldObj: &ateapi.GoldenSnapshotStatus{}, newObj: valid(), }, { name: "error_message set", oldObj: valid(), - newObj: valid(func(s *ateapipb.GoldenSnapshotStatus) { + newObj: valid(func(s *ateapi.GoldenSnapshotStatus) { s.ErrorMessage = "GoldenActorCrashed: golden actor crashed before its snapshot was taken" }), }, { name: "error_message set too long", oldObj: valid(), - newObj: valid(func(s *ateapipb.GoldenSnapshotStatus) { + newObj: valid(func(s *ateapi.GoldenSnapshotStatus) { s.ErrorMessage = strings.Repeat("x", 4097) }), want: field.ErrorList{field.TooLong(field.NewPath("error_message"), nil, 4096).WithOrigin("maxLength")}, diff --git a/cmd/ateapi/internal/apivalidation/worker.go b/cmd/ateapi/internal/apivalidation/worker.go index 00e8567d4d..2f665edd3b 100644 --- a/cmd/ateapi/internal/apivalidation/worker.go +++ b/cmd/ateapi/internal/apivalidation/worker.go @@ -17,37 +17,37 @@ package apivalidation import ( "context" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "k8s.io/apimachinery/pkg/api/operation" "k8s.io/apimachinery/pkg/api/validate" "k8s.io/apimachinery/pkg/util/validation/field" ) -func ValidateListWorkerActorAssignmentsRequest(ctx context.Context, req *ateapipb.ListWorkerActorAssignmentsRequest) field.ErrorList { +func ValidateListWorkerActorAssignmentsRequest(ctx context.Context, req *ateapi.ListWorkerActorAssignmentsRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_ListWorkerActorAssignmentsRequest(ctx, op, nil, req, nil) } -func ValidateListWorkersRequest(ctx context.Context, req *ateapipb.ListWorkersRequest) field.ErrorList { +func ValidateListWorkersRequest(ctx context.Context, req *ateapi.ListWorkersRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_ListWorkersRequest(ctx, op, nil, req, nil) } -func ValidateGetWorkerRequest(ctx context.Context, req *ateapipb.GetWorkerRequest) field.ErrorList { +func ValidateGetWorkerRequest(ctx context.Context, req *ateapi.GetWorkerRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_GetWorkerRequest(ctx, op, nil, req, nil) } -func ValidateCreateWorkerRequest(ctx context.Context, req *ateapipb.CreateWorkerRequest) field.ErrorList { +func ValidateCreateWorkerRequest(ctx context.Context, req *ateapi.CreateWorkerRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_CreateWorkerRequest(ctx, op, nil, req, nil) } -func ValidateUpdateWorkerRequest(ctx context.Context, req *ateapipb.UpdateWorkerRequest) field.ErrorList { +func ValidateUpdateWorkerRequest(ctx context.Context, req *ateapi.UpdateWorkerRequest) field.ErrorList { // Call the generated validation. // We model this as a create rather than an update because updates assume // the existence of a "current" value, which we do not have yet. This is @@ -57,7 +57,7 @@ func ValidateUpdateWorkerRequest(ctx context.Context, req *ateapipb.UpdateWorker return Validate_UpdateWorkerRequest(ctx, op, nil, req, nil) } -func ValidateDeleteWorkerRequest(ctx context.Context, req *ateapipb.DeleteWorkerRequest) field.ErrorList { +func ValidateDeleteWorkerRequest(ctx context.Context, req *ateapi.DeleteWorkerRequest) field.ErrorList { // Call the generated validation. The preconditions in options are each // optional: a zero value waives that guard, so only non-zero values are // checked for shape. @@ -65,50 +65,50 @@ func ValidateDeleteWorkerRequest(ctx context.Context, req *ateapipb.DeleteWorker return Validate_DeleteWorkerRequest(ctx, op, nil, req, nil) } -func ValidateDrainWorkerRequest(ctx context.Context, req *ateapipb.DrainWorkerRequest) field.ErrorList { +func ValidateDrainWorkerRequest(ctx context.Context, req *ateapi.DrainWorkerRequest) field.ErrorList { // Call the generated validation. op := MakeCreateOp(ctx) return Validate_DrainWorkerRequest(ctx, op, nil, req, nil) } -func ValidateAcquireWorkerEpochRequest(ctx context.Context, req *ateapipb.AcquireWorkerEpochRequest) field.ErrorList { +func ValidateAcquireWorkerEpochRequest(ctx context.Context, req *ateapi.AcquireWorkerEpochRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_AcquireWorkerEpochRequest(ctx, op, nil, req, nil) } -func ValidateRegisterWorkerRequest(ctx context.Context, req *ateapipb.RegisterWorkerRequest) field.ErrorList { +func ValidateRegisterWorkerRequest(ctx context.Context, req *ateapi.RegisterWorkerRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_RegisterWorkerRequest(ctx, op, nil, req, nil) } -func ValidateSetWorkerSandboxRuntimesRequest(ctx context.Context, req *ateapipb.SetWorkerSandboxRuntimesRequest) field.ErrorList { +func ValidateSetWorkerSandboxRuntimesRequest(ctx context.Context, req *ateapi.SetWorkerSandboxRuntimesRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_SetWorkerSandboxRuntimesRequest(ctx, op, nil, req, nil) } -func ValidateRequestActorSuspendRequest(ctx context.Context, req *ateapipb.RequestActorSuspendRequest) field.ErrorList { +func ValidateRequestActorSuspendRequest(ctx context.Context, req *ateapi.RequestActorSuspendRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_RequestActorSuspendRequest(ctx, op, nil, req, nil) } -func ValidateReportActorCrashedRequest(ctx context.Context, req *ateapipb.ReportActorCrashedRequest) field.ErrorList { +func ValidateReportActorCrashedRequest(ctx context.Context, req *ateapi.ReportActorCrashedRequest) field.ErrorList { op := operation.Operation{Type: operation.Create} return Validate_ReportActorCrashedRequest(ctx, op, nil, req, nil) } -func ValidateMarkWorkerAvailableRequest(ctx context.Context, req *ateapipb.MarkWorkerAvailableRequest) field.ErrorList { +func ValidateMarkWorkerAvailableRequest(ctx context.Context, req *ateapi.MarkWorkerAvailableRequest) field.ErrorList { // Call the generated validation. op := operation.Operation{Type: operation.Create} return Validate_MarkWorkerAvailableRequest(ctx, op, nil, req, nil) } -func ValidateMarkWorkerUnavailableRequest(ctx context.Context, req *ateapipb.MarkWorkerUnavailableRequest) field.ErrorList { +func ValidateMarkWorkerUnavailableRequest(ctx context.Context, req *ateapi.MarkWorkerUnavailableRequest) field.ErrorList { // Call the generated validation. op := operation.Operation{Type: operation.Create} return Validate_MarkWorkerUnavailableRequest(ctx, op, nil, req, nil) } -func ValidateReportActorSnapshotStateRequest(ctx context.Context, req *ateapipb.ReportActorSnapshotStateRequest) field.ErrorList { +func ValidateReportActorSnapshotStateRequest(ctx context.Context, req *ateapi.ReportActorSnapshotStateRequest) field.ErrorList { op := operation.Operation{Type: operation.Create} errs := Validate_ReportActorSnapshotStateRequest(ctx, op, nil, req, nil) // A report with neither latest_local nor uploading is a detach, which @@ -122,7 +122,7 @@ func ValidateReportActorSnapshotStateRequest(ctx context.Context, req *ateapipb. // validateWorkerUpdate validates a Worker against the previous stored value. // It is what enforces the immutable fields, which need an old value to compare // against. -func ValidateWorkerUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapipb.Worker, requireStatus bool) field.ErrorList { +func ValidateWorkerUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapi.Worker, requireStatus bool) field.ErrorList { // Call the generated validation. op := MakeUpdateOp(ctx) errs := Validate_Worker(ctx, op, fldPath, newVal, oldVal) @@ -159,7 +159,7 @@ func ValidateCustom_Worker_WorkerSpiffeId(_ context.Context, _ operation.Operati } // This exists only because nested subfield tags are not supported yet. -func ValidateCustom_UpdateWorkerRequest_Worker(ctx context.Context, op operation.Operation, fldPath *field.Path, worker, _ *ateapipb.Worker) field.ErrorList { +func ValidateCustom_UpdateWorkerRequest_Worker(ctx context.Context, op operation.Operation, fldPath *field.Path, worker, _ *ateapi.Worker) field.ErrorList { if worker == nil || worker.Metadata == nil { return nil // handled by DV } diff --git a/cmd/ateapi/internal/apivalidation/worker_test.go b/cmd/ateapi/internal/apivalidation/worker_test.go index c32dd82269..35b4540f7c 100644 --- a/cmd/ateapi/internal/apivalidation/worker_test.go +++ b/cmd/ateapi/internal/apivalidation/worker_test.go @@ -20,7 +20,7 @@ import ( "strings" "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" "k8s.io/apimachinery/pkg/util/validation/field" @@ -39,8 +39,8 @@ func TestValidateCreateWorkerRequest(t *testing.T) { // This test verifies validation of user input for creation. The RPC scrubs // status before validating, so status is absent from the valid shape; when // a request does carry one, it is validated like any other field. - validReq := func(actor *ateapipb.Worker, mods ...func(actor *ateapipb.CreateWorkerRequest)) *ateapipb.CreateWorkerRequest { - req := &ateapipb.CreateWorkerRequest{ + validReq := func(actor *ateapi.Worker, mods ...func(actor *ateapi.CreateWorkerRequest)) *ateapi.CreateWorkerRequest { + req := &ateapi.CreateWorkerRequest{ Worker: actor, } for _, m := range mods { @@ -53,7 +53,7 @@ func TestValidateCreateWorkerRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.CreateWorkerRequest + req *ateapi.CreateWorkerRequest want field.ErrorList }{{ name: "valid unassigned worker", @@ -63,84 +63,84 @@ func TestValidateCreateWorkerRequest(t *testing.T) { req: validReq(validWorker(apiWorkerName, withStatus())), }, { name: "missing worker", - req: &ateapipb.CreateWorkerRequest{Worker: nil}, + req: &ateapi.CreateWorkerRequest{Worker: nil}, want: field.ErrorList{field.Required(field.NewPath("worker"), "")}, }, { name: "missing metadata", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { w.Metadata = nil })), + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.Metadata = nil })), want: field.ErrorList{field.Required(field.NewPath("worker", "metadata"), "")}, }, { name: "missing metadata.name", - req: validReq(validWorker(apiWorkerName, withMetadata(func(m *ateapipb.ResourceMetadata) { m.Name = "" }))), + req: validReq(validWorker(apiWorkerName, withMetadata(func(m *ateapi.ResourceMetadata) { m.Name = "" }))), want: field.ErrorList{field.Required(field.NewPath("worker", "metadata", "name"), "")}, }, { name: "invalid metadata.name", - req: validReq(validWorker(apiWorkerName, withMetadata(func(m *ateapipb.ResourceMetadata) { m.Name = "not a name" }))), + req: validReq(validWorker(apiWorkerName, withMetadata(func(m *ateapi.ResourceMetadata) { m.Name = "not a name" }))), want: field.ErrorList{field.Invalid(field.NewPath("worker", "metadata", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "metadata.atespace set on a global-scoped Worker", - req: validReq(validWorker(apiWorkerName, withMetadata(func(m *ateapipb.ResourceMetadata) { m.Atespace = "team-a" }))), + req: validReq(validWorker(apiWorkerName, withMetadata(func(m *ateapi.ResourceMetadata) { m.Atespace = "team-a" }))), want: field.ErrorList{field.Forbidden(field.NewPath("worker", "metadata", "atespace"), "")}, }, { name: "missing worker_namespace", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { w.WorkerNamespace = "" })), + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.WorkerNamespace = "" })), want: field.ErrorList{field.Required(field.NewPath("worker", "worker_namespace"), "")}, }, { name: "invalid worker_namespace", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { w.WorkerNamespace = "NS-1" })), + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.WorkerNamespace = "NS-1" })), want: field.ErrorList{field.Invalid(field.NewPath("worker", "worker_namespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "missing worker_pool", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { w.WorkerPool = "" })), + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.WorkerPool = "" })), want: field.ErrorList{field.Required(field.NewPath("worker", "worker_pool"), "")}, }, { name: "invalid worker_pool", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { w.WorkerPool = "POOL_1" })), + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.WorkerPool = "POOL_1" })), want: field.ErrorList{field.Invalid(field.NewPath("worker", "worker_pool"), nil, "").WithOrigin("format=k8s-long-name")}, }, { name: "missing worker_pod", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { w.WorkerPod = "" })), + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.WorkerPod = "" })), want: field.ErrorList{field.Required(field.NewPath("worker", "worker_pod"), "")}, }, { name: "invalid worker_pod", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { w.WorkerPod = "POD_1" })), + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.WorkerPod = "POD_1" })), want: field.ErrorList{field.Invalid(field.NewPath("worker", "worker_pod"), nil, "").WithOrigin("format=k8s-long-name")}, }, { name: "missing worker_pod_uid", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { w.WorkerPodUid = "" })), + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.WorkerPodUid = "" })), want: field.ErrorList{field.Required(field.NewPath("worker", "worker_pod_uid"), "")}, }, { name: "invalid worker_pod_uid", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { w.WorkerPodUid = "INVALID-UUID" })), + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.WorkerPodUid = "INVALID-UUID" })), want: field.ErrorList{field.Invalid(field.NewPath("worker", "worker_pod_uid"), nil, "").WithOrigin("format=k8s-uuid")}, }, { name: "missing node_name", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { w.NodeName = "" })), + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.NodeName = "" })), want: field.ErrorList{field.Required(field.NewPath("worker", "node_name"), "")}, }, { name: "invalid node_name", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { w.NodeName = "NODE_NAME" })), + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.NodeName = "NODE_NAME" })), want: field.ErrorList{field.Invalid(field.NewPath("worker", "node_name"), nil, "").WithOrigin("format=k8s-long-name")}, }, { name: "valid dual-stack status.ips", - req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapipb.WorkerStatus) { s.Ips = []string{"fd00::1", "10.1.2.3"} }))), + req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapi.WorkerStatus) { s.Ips = []string{"fd00::1", "10.1.2.3"} }))), }, { name: "invalid status.ips", - req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapipb.WorkerStatus) { s.Ips = []string{"not-an-ip"} }))), + req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapi.WorkerStatus) { s.Ips = []string{"not-an-ip"} }))), want: field.ErrorList{field.Invalid(field.NewPath("worker", "status", "ips").Index(0), nil, "").WithOrigin("format=ip-strict")}, }, { name: "two status.ips in one family", - req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapipb.WorkerStatus) { s.Ips = []string{"10.1.2.3", "10.1.2.4"} }))), + req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapi.WorkerStatus) { s.Ips = []string{"10.1.2.3", "10.1.2.4"} }))), want: field.ErrorList{field.Invalid(field.NewPath("worker", "status", "ips").Index(1), nil, "")}, }, { name: "too many status.ips", - req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapipb.WorkerStatus) { + req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapi.WorkerStatus) { s.Ips = []string{"10.1.2.3", "fd00::1", "10.1.2.4"} }))), want: field.ErrorList{field.TooMany(field.NewPath("worker", "status", "ips"), 3, 2).WithOrigin("maxItems")}, }, { name: "negative status epochs", - req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapipb.WorkerStatus) { + req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapi.WorkerStatus) { s.IssuedEpoch = -1 s.RegisteredEpoch = -1 }))), @@ -150,29 +150,29 @@ func TestValidateCreateWorkerRequest(t *testing.T) { }, }, { name: "valid worker_spiffe_id", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.WorkerSpiffeId = "spiffe://cluster.local/ns/ate-system/sa/ateworker" })), }, { name: "invalid worker_spiffe_id", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.WorkerSpiffeId = "https://cluster.local/ns/ate-system/sa/ateworker" })), want: field.ErrorList{field.Invalid(field.NewPath("worker", "worker_spiffe_id"), nil, "")}, }, { name: "worker_spiffe_id too long", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.WorkerSpiffeId = "spiffe://cluster.local/" + strings.Repeat("a", 2048) })), want: field.ErrorList{field.TooLong(field.NewPath("worker", "worker_spiffe_id"), nil, 2048).WithOrigin("maxLength")}, }, { name: "valid labels", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.Labels = map[string]string{"tier": "batch", "pool.ate.io/zone": "us-west1-c"} })), }, { name: "too many labels", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { labels := make(map[string]string, 65) for i := 0; i < 65; i++ { labels[fmt.Sprintf("key-%d", i)] = "v" @@ -182,23 +182,23 @@ func TestValidateCreateWorkerRequest(t *testing.T) { want: field.ErrorList{field.TooMany(field.NewPath("worker", "labels"), 65, 64).WithOrigin("maxProperties")}, }, { name: "invalid label key", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { w.Labels = map[string]string{"bad key!": "batch"} })), + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.Labels = map[string]string{"bad key!": "batch"} })), want: field.ErrorList{field.Invalid(field.NewPath("worker", "labels"), "bad key!", "").WithOrigin("format=k8s-label-key")}, }, { name: "invalid label value", - req: validReq(validWorker(apiWorkerName, func(w *ateapipb.Worker) { w.Labels = map[string]string{"tier": "not valid!"} })), + req: validReq(validWorker(apiWorkerName, func(w *ateapi.Worker) { w.Labels = map[string]string{"tier": "not valid!"} })), want: field.ErrorList{field.Invalid(field.NewPath("worker", "labels").Key("tier"), "not valid!", "").WithOrigin("format=k8s-label-value")}, }, { name: "status needs a state", - req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapipb.WorkerStatus) { s.State = 0 }))), + req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapi.WorkerStatus) { s.State = 0 }))), want: field.ErrorList{field.Required(field.NewPath("worker", "status", "state"), "")}, }, { name: "status invalid state (too small)", - req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapipb.WorkerStatus) { s.State = -1 }))), + req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapi.WorkerStatus) { s.State = -1 }))), want: field.ErrorList{field.Invalid(field.NewPath("worker", "status", "state"), nil, "").WithOrigin("minimum")}, }, { name: "status invalid state (too large)", - req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapipb.WorkerStatus) { s.State = 99 }))), + req: validReq(validWorker(apiWorkerName, withStatus(func(s *ateapi.WorkerStatus) { s.State = 99 }))), want: field.ErrorList{field.Invalid(field.NewPath("worker", "status", "state"), nil, "").WithOrigin("maximum")}, }} for _, tc := range tests { @@ -211,51 +211,51 @@ func TestValidateCreateWorkerRequest(t *testing.T) { func TestValidateDeleteWorkerRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.DeleteWorkerRequest + req *ateapi.DeleteWorkerRequest want field.ErrorList }{{ "valid, no options", - &ateapipb.DeleteWorkerRequest{Worker: workerRef(apiWorkerName)}, + &ateapi.DeleteWorkerRequest{Worker: workerRef(apiWorkerName)}, nil, }, { "valid, both guards", - &ateapipb.DeleteWorkerRequest{ + &ateapi.DeleteWorkerRequest{ Worker: workerRef(apiWorkerName), - Options: &ateapipb.DeleteOptions{Uid: apiOtherWorkerName, Version: 3}, + Options: &ateapi.DeleteOptions{Uid: apiOtherWorkerName, Version: 3}, }, nil, }, { "missing worker", - &ateapipb.DeleteWorkerRequest{}, + &ateapi.DeleteWorkerRequest{}, field.ErrorList{field.Required(field.NewPath("worker"), "")}, }, { "missing worker.name", - &ateapipb.DeleteWorkerRequest{Worker: &ateapipb.ObjectRef{}}, + &ateapi.DeleteWorkerRequest{Worker: &ateapi.ObjectRef{}}, field.ErrorList{field.Required(field.NewPath("worker", "name"), "")}, }, { "worker.atespace must be empty", - &ateapipb.DeleteWorkerRequest{Worker: &ateapipb.ObjectRef{Atespace: "team-a", Name: apiWorkerName}}, + &ateapi.DeleteWorkerRequest{Worker: &ateapi.ObjectRef{Atespace: "team-a", Name: apiWorkerName}}, field.ErrorList{field.Forbidden(field.NewPath("worker", "atespace"), "")}, }, { "invalid options.uid", - &ateapipb.DeleteWorkerRequest{ + &ateapi.DeleteWorkerRequest{ Worker: workerRef(apiWorkerName), - Options: &ateapipb.DeleteOptions{Uid: "not-a-uuid"}, + Options: &ateapi.DeleteOptions{Uid: "not-a-uuid"}, }, field.ErrorList{field.Invalid(field.NewPath("options", "uid"), nil, "").WithOrigin("format=k8s-uuid")}, }, { "negative options.version", - &ateapipb.DeleteWorkerRequest{ + &ateapi.DeleteWorkerRequest{ Worker: workerRef(apiWorkerName), - Options: &ateapipb.DeleteOptions{Version: -1}, + Options: &ateapi.DeleteOptions{Version: -1}, }, field.ErrorList{field.Invalid(field.NewPath("options", "version"), nil, "").WithOrigin("minimum")}, }, { // Zero values waive the guards, so they are never validated for shape. "zero options are waived, not validated", - &ateapipb.DeleteWorkerRequest{ + &ateapi.DeleteWorkerRequest{ Worker: workerRef(apiWorkerName), - Options: &ateapipb.DeleteOptions{}, + Options: &ateapi.DeleteOptions{}, }, nil, }} @@ -270,19 +270,19 @@ func TestValidateUpdateWorkerRequest(t *testing.T) { // This test verifies validation of user input for update. The worker body // is deliberately not descended into here (updates are validated in two // steps); only the metadata that addresses the resource is checked. - validReq := func(mods ...func(w *ateapipb.Worker)) *ateapipb.UpdateWorkerRequest { + validReq := func(mods ...func(w *ateapi.Worker)) *ateapi.UpdateWorkerRequest { worker := validWorker(apiWorkerName) worker.Metadata.Uid = apiOtherWorkerName worker.Metadata.Version = 3 for _, m := range mods { m(worker) } - return &ateapipb.UpdateWorkerRequest{Worker: worker} + return &ateapi.UpdateWorkerRequest{Worker: worker} } tests := []struct { name string - req *ateapipb.UpdateWorkerRequest + req *ateapi.UpdateWorkerRequest want field.ErrorList }{{ "valid", @@ -292,31 +292,31 @@ func TestValidateUpdateWorkerRequest(t *testing.T) { // uid and version are preconditions the store requires; the request // validation deliberately leaves their presence to the store. "missing uid and version pass request validation", - validReq(func(w *ateapipb.Worker) { w.Metadata.Uid = ""; w.Metadata.Version = 0 }), + validReq(func(w *ateapi.Worker) { w.Metadata.Uid = ""; w.Metadata.Version = 0 }), nil, }, { "missing worker", - &ateapipb.UpdateWorkerRequest{}, + &ateapi.UpdateWorkerRequest{}, field.ErrorList{field.Required(field.NewPath("worker"), "")}, }, { "missing metadata", - validReq(func(w *ateapipb.Worker) { w.Metadata = nil }), + validReq(func(w *ateapi.Worker) { w.Metadata = nil }), field.ErrorList{field.Required(field.NewPath("worker", "metadata"), "")}, }, { "missing metadata.name", - validReq(func(w *ateapipb.Worker) { w.Metadata.Name = "" }), + validReq(func(w *ateapi.Worker) { w.Metadata.Name = "" }), field.ErrorList{field.Required(field.NewPath("worker", "metadata", "name"), "")}, }, { "invalid metadata.name", - validReq(func(w *ateapipb.Worker) { w.Metadata.Name = "Not A Name" }), + validReq(func(w *ateapi.Worker) { w.Metadata.Name = "Not A Name" }), field.ErrorList{field.Invalid(field.NewPath("worker", "metadata", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { "invalid metadata.uid", - validReq(func(w *ateapipb.Worker) { w.Metadata.Uid = "not-a-uuid" }), + validReq(func(w *ateapi.Worker) { w.Metadata.Uid = "not-a-uuid" }), field.ErrorList{field.Invalid(field.NewPath("worker", "metadata", "uid"), nil, "").WithOrigin("format=k8s-uuid")}, }, { "metadata.atespace set on a global-scoped Worker", - validReq(func(w *ateapipb.Worker) { w.Metadata.Atespace = "team-a" }), + validReq(func(w *ateapi.Worker) { w.Metadata.Atespace = "team-a" }), field.ErrorList{field.Forbidden(field.NewPath("worker", "metadata", "atespace"), "")}, }} for _, tt := range tests { @@ -331,8 +331,8 @@ func TestValidateUpdateWorkerRequest(t *testing.T) { // a direct call shows the guard catching a worker without one. func TestValidateWorkerUpdate_RequireStatus(t *testing.T) { oldVal := validWorker(apiWorkerName) - oldVal.Status = &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_ACTIVE} - newVal := proto.Clone(oldVal).(*ateapipb.Worker) + oldVal.Status = &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_ACTIVE} + newVal := proto.Clone(oldVal).(*ateapi.Worker) newVal.Status = nil want := field.ErrorList{field.Required(field.NewPath("worker", "status"), "")} @@ -346,22 +346,22 @@ func TestValidateWorkerUpdate_RequireStatus(t *testing.T) { func TestValidateAcquireWorkerEpochRequest(t *testing.T) { tests := []struct { name string - req *ateapipb.AcquireWorkerEpochRequest + req *ateapi.AcquireWorkerEpochRequest want field.ErrorList }{{ name: "valid", - req: &ateapipb.AcquireWorkerEpochRequest{Worker: workerRef(apiWorkerName)}, + req: &ateapi.AcquireWorkerEpochRequest{Worker: workerRef(apiWorkerName)}, }, { name: "missing worker", - req: &ateapipb.AcquireWorkerEpochRequest{}, + req: &ateapi.AcquireWorkerEpochRequest{}, want: field.ErrorList{field.Required(field.NewPath("worker"), "")}, }, { name: "worker.atespace must be empty", - req: &ateapipb.AcquireWorkerEpochRequest{Worker: &ateapipb.ObjectRef{Atespace: "team-a", Name: apiWorkerName}}, + req: &ateapi.AcquireWorkerEpochRequest{Worker: &ateapi.ObjectRef{Atespace: "team-a", Name: apiWorkerName}}, want: field.ErrorList{field.Forbidden(field.NewPath("worker", "atespace"), "")}, }, { name: "missing worker.name", - req: &ateapipb.AcquireWorkerEpochRequest{Worker: &ateapipb.ObjectRef{}}, + req: &ateapi.AcquireWorkerEpochRequest{Worker: &ateapi.ObjectRef{}}, want: field.ErrorList{field.Required(field.NewPath("worker", "name"), "")}, }} for _, tt := range tests { @@ -372,12 +372,12 @@ func TestValidateAcquireWorkerEpochRequest(t *testing.T) { } func TestValidateRegisterWorkerRequest(t *testing.T) { - valid := func(mutate ...func(*ateapipb.RegisterWorkerRequest)) *ateapipb.RegisterWorkerRequest { - r := &ateapipb.RegisterWorkerRequest{ + valid := func(mutate ...func(*ateapi.RegisterWorkerRequest)) *ateapi.RegisterWorkerRequest { + r := &ateapi.RegisterWorkerRequest{ Worker: workerRef(apiWorkerName), Epoch: 1, Ips: []string{"10.1.2.3"}, - Capacity: &ateapipb.WorkerResources{ + Capacity: &ateapi.WorkerResources{ Actors: 10, CpuMillicores: 2000, MemoryBytes: 4 << 30, }, @@ -389,68 +389,68 @@ func TestValidateRegisterWorkerRequest(t *testing.T) { } tests := []struct { name string - req *ateapipb.RegisterWorkerRequest + req *ateapi.RegisterWorkerRequest want field.ErrorList }{{ name: "valid", req: valid(), }, { name: "valid empty capacity", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Capacity = &ateapipb.WorkerResources{} }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Capacity = &ateapi.WorkerResources{} }), }, { name: "valid dual-stack ips", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Ips = []string{"fd00::1", "10.1.2.3"} }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Ips = []string{"fd00::1", "10.1.2.3"} }), }, { name: "missing worker", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Worker = nil }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Worker = nil }), want: field.ErrorList{field.Required(field.NewPath("worker"), "")}, }, { name: "worker.atespace must be empty", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Worker.Atespace = "team-a" }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Worker.Atespace = "team-a" }), want: field.ErrorList{field.Forbidden(field.NewPath("worker", "atespace"), "")}, }, { name: "missing worker.name", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Worker.Name = "" }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Worker.Name = "" }), want: field.ErrorList{field.Required(field.NewPath("worker", "name"), "")}, }, { name: "invalid worker.name", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Worker.Name = "UPPER" }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Worker.Name = "UPPER" }), want: field.ErrorList{field.Invalid(field.NewPath("worker", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "missing epoch", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Epoch = 0 }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Epoch = 0 }), want: field.ErrorList{field.Required(field.NewPath("epoch"), "")}, }, { name: "negative epoch", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Epoch = -1 }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Epoch = -1 }), want: field.ErrorList{field.Invalid(field.NewPath("epoch"), nil, "").WithOrigin("minimum")}, }, { name: "missing ips", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Ips = nil }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Ips = nil }), want: field.ErrorList{field.Required(field.NewPath("ips"), "")}, }, { name: "invalid ip", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Ips = []string{"not-an-ip"} }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Ips = []string{"not-an-ip"} }), want: field.ErrorList{field.Invalid(field.NewPath("ips").Index(0), nil, "").WithOrigin("format=ip-strict")}, }, { name: "two ips in one family", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Ips = []string{"10.1.2.3", "10.1.2.4"} }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Ips = []string{"10.1.2.3", "10.1.2.4"} }), want: field.ErrorList{field.Invalid(field.NewPath("ips").Index(1), nil, "")}, }, { name: "too many ips", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Ips = []string{"10.1.2.3", "fd00::1", "10.1.2.4"} }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Ips = []string{"10.1.2.3", "fd00::1", "10.1.2.4"} }), want: field.ErrorList{field.TooMany(field.NewPath("ips"), 3, 2).WithOrigin("maxItems")}, }, { name: "missing capacity", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Capacity = nil }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Capacity = nil }), want: field.ErrorList{field.Required(field.NewPath("capacity"), "")}, }, { name: "negative capacity.actors", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Capacity.Actors = -1 }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Capacity.Actors = -1 }), want: field.ErrorList{field.Invalid(field.NewPath("capacity", "actors"), nil, "").WithOrigin("minimum")}, }, { name: "negative capacity.memory_bytes", - req: valid(func(r *ateapipb.RegisterWorkerRequest) { r.Capacity.MemoryBytes = -1 }), + req: valid(func(r *ateapi.RegisterWorkerRequest) { r.Capacity.MemoryBytes = -1 }), want: field.ErrorList{field.Invalid(field.NewPath("capacity", "memory_bytes"), nil, "").WithOrigin("minimum")}, }} for _, tt := range tests { @@ -461,11 +461,11 @@ func TestValidateRegisterWorkerRequest(t *testing.T) { } func TestValidateSetWorkerSandboxRuntimesRequest(t *testing.T) { - valid := func(mutate ...func(*ateapipb.SetWorkerSandboxRuntimesRequest)) *ateapipb.SetWorkerSandboxRuntimesRequest { - r := &ateapipb.SetWorkerSandboxRuntimesRequest{ + valid := func(mutate ...func(*ateapi.SetWorkerSandboxRuntimesRequest)) *ateapi.SetWorkerSandboxRuntimesRequest { + r := &ateapi.SetWorkerSandboxRuntimesRequest{ Worker: workerRef(apiWorkerName), Epoch: 1, - SandboxClasses: []*ateapipb.WorkerSandboxClass{validSandboxClass()}, + SandboxClasses: []*ateapi.WorkerSandboxClass{validSandboxClass()}, } for _, m := range mutate { m(r) @@ -479,48 +479,48 @@ func TestValidateSetWorkerSandboxRuntimesRequest(t *testing.T) { restorablePath := classPath.Child("restorable_runtimes") tests := []struct { name string - req *ateapipb.SetWorkerSandboxRuntimesRequest + req *ateapi.SetWorkerSandboxRuntimesRequest want field.ErrorList }{{ name: "valid", req: valid(), }, { name: "valid with restorable runtimes", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { - r.SandboxClasses[0].RestorableRuntimes = []*ateapipb.WorkerSandboxRuntime{{Version: &ateapipb.VersionedSandboxCompat{ + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { + r.SandboxClasses[0].RestorableRuntimes = []*ateapi.WorkerSandboxRuntime{{Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{ + Attributes: []*ateapi.AttributeEntry{ {Key: "architecture", Value: "amd64"}, }, }}} }), }, { name: "missing worker", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { r.Worker = nil }), + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.Worker = nil }), want: field.ErrorList{field.Required(field.NewPath("worker"), "")}, }, { name: "worker.atespace must be empty", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { r.Worker.Atespace = "team-a" }), + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.Worker.Atespace = "team-a" }), want: field.ErrorList{field.Forbidden(field.NewPath("worker", "atespace"), "")}, }, { name: "missing epoch", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { r.Epoch = 0 }), + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.Epoch = 0 }), want: field.ErrorList{field.Required(field.NewPath("epoch"), "")}, }, { name: "negative epoch", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { r.Epoch = -1 }), + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.Epoch = -1 }), want: field.ErrorList{field.Invalid(field.NewPath("epoch"), nil, "").WithOrigin("minimum")}, }, { name: "missing sandbox_classes", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses = nil }), + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses = nil }), want: field.ErrorList{field.Required(classesPath, "")}, }, { name: "empty sandbox_classes", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses = []*ateapipb.WorkerSandboxClass{} }), + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses = []*ateapi.WorkerSandboxClass{} }), want: field.ErrorList{field.Required(classesPath, "")}, }, { name: "too many sandbox_classes", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { second := validSandboxClass() second.SandboxClass = "microvm" r.SandboxClasses = append(r.SandboxClasses, second) @@ -528,11 +528,11 @@ func TestValidateSetWorkerSandboxRuntimesRequest(t *testing.T) { want: field.ErrorList{field.TooMany(classesPath, 2, 1).WithOrigin("maxItems")}, }, { name: "missing sandbox_classes.sandbox_class", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].SandboxClass = "" }), + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].SandboxClass = "" }), want: field.ErrorList{field.Required(classPath.Child("sandbox_class"), "")}, }, { name: "sandbox_classes.sandbox_class too long", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].SandboxClass = strings.Repeat("c", 64) }), want: field.ErrorList{ @@ -541,38 +541,38 @@ func TestValidateSetWorkerSandboxRuntimesRequest(t *testing.T) { }, }, { name: "unsupported sandbox_classes.sandbox_class", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].SandboxClass = "kata" }), + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].SandboxClass = "kata" }), want: field.ErrorList{field.NotSupported[string](classPath.Child("sandbox_class"), nil, nil)}, }, { name: "missing sandbox_classes.default_runtime", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].DefaultRuntime = nil }), + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].DefaultRuntime = nil }), want: field.ErrorList{field.Required(defaultRuntimePath, "")}, }, { name: "missing default_runtime.version", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].DefaultRuntime.Version = nil }), + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].DefaultRuntime.Version = nil }), want: field.ErrorList{field.Required(defaultVersionPath, "")}, }, { name: "missing default_runtime.schema_version", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].DefaultRuntime.Version.SchemaVersion = "" }), want: field.ErrorList{field.Required(defaultVersionPath.Child("schema_version"), "")}, }, { name: "default_runtime.schema_version too long", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].DefaultRuntime.Version.SchemaVersion = strings.Repeat("v", 65) }), want: field.ErrorList{field.TooLong(defaultVersionPath.Child("schema_version"), "", 64).WithOrigin("maxLength")}, }, { name: "missing default_runtime.attributes", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].DefaultRuntime.Version.Attributes = nil }), want: field.ErrorList{field.Required(defaultVersionPath.Child("attributes"), "")}, }, { name: "duplicate attribute key", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { - r.SandboxClasses[0].DefaultRuntime.Version.Attributes = []*ateapipb.AttributeEntry{ + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { + r.SandboxClasses[0].DefaultRuntime.Version.Attributes = []*ateapi.AttributeEntry{ {Key: "architecture", Value: "amd64"}, {Key: "architecture", Value: "arm64"}, } @@ -580,65 +580,65 @@ func TestValidateSetWorkerSandboxRuntimesRequest(t *testing.T) { want: field.ErrorList{field.Duplicate(defaultVersionPath.Child("attributes").Index(1), nil)}, }, { name: "missing attribute key", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { - r.SandboxClasses[0].DefaultRuntime.Version.Attributes = []*ateapipb.AttributeEntry{{Value: "amd64"}} + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { + r.SandboxClasses[0].DefaultRuntime.Version.Attributes = []*ateapi.AttributeEntry{{Value: "amd64"}} }), want: field.ErrorList{field.Required(defaultVersionPath.Child("attributes").Index(0).Child("key"), "")}, }, { name: "attribute key too long", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { - r.SandboxClasses[0].DefaultRuntime.Version.Attributes = []*ateapipb.AttributeEntry{{Key: strings.Repeat("k", 129), Value: "v"}} + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { + r.SandboxClasses[0].DefaultRuntime.Version.Attributes = []*ateapi.AttributeEntry{{Key: strings.Repeat("k", 129), Value: "v"}} }), want: field.ErrorList{field.TooLong(defaultVersionPath.Child("attributes").Index(0).Child("key"), "", 128).WithOrigin("maxLength")}, }, { name: "missing attribute value", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { - r.SandboxClasses[0].DefaultRuntime.Version.Attributes = []*ateapipb.AttributeEntry{{Key: "k"}} + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { + r.SandboxClasses[0].DefaultRuntime.Version.Attributes = []*ateapi.AttributeEntry{{Key: "k"}} }), want: field.ErrorList{field.Required(defaultVersionPath.Child("attributes").Index(0).Child("value"), "")}, }, { name: "attribute value too long", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { - r.SandboxClasses[0].DefaultRuntime.Version.Attributes = []*ateapipb.AttributeEntry{{Key: "k", Value: strings.Repeat("v", 257)}} + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { + r.SandboxClasses[0].DefaultRuntime.Version.Attributes = []*ateapi.AttributeEntry{{Key: "k", Value: strings.Repeat("v", 257)}} }), want: field.ErrorList{field.TooLong(defaultVersionPath.Child("attributes").Index(0).Child("value"), "", 256).WithOrigin("maxLength")}, }, { name: "attributes at the bound", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].DefaultRuntime.Version.Attributes = attributeEntries(32) }), }, { name: "too many attributes", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].DefaultRuntime.Version.Attributes = attributeEntries(33) }), want: field.ErrorList{field.TooMany(defaultVersionPath.Child("attributes"), 33, 32).WithOrigin("maxItems")}, }, { name: "nil restorable_runtimes entry", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { - r.SandboxClasses[0].RestorableRuntimes = []*ateapipb.WorkerSandboxRuntime{nil} + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { + r.SandboxClasses[0].RestorableRuntimes = []*ateapi.WorkerSandboxRuntime{nil} }), want: field.ErrorList{field.Required(restorablePath.Index(0), "")}, }, { name: "invalid restorable_runtimes entry", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { - r.SandboxClasses[0].RestorableRuntimes = []*ateapipb.WorkerSandboxRuntime{{Version: &ateapipb.VersionedSandboxCompat{Attributes: attributeEntries(1)}}} + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { + r.SandboxClasses[0].RestorableRuntimes = []*ateapi.WorkerSandboxRuntime{{Version: &ateapi.VersionedSandboxCompat{Attributes: attributeEntries(1)}}} }), want: field.ErrorList{field.Required(restorablePath.Index(0).Child("version", "schema_version"), "")}, }, { name: "restorable_runtimes entry without a version", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { - r.SandboxClasses[0].RestorableRuntimes = []*ateapipb.WorkerSandboxRuntime{{}} + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { + r.SandboxClasses[0].RestorableRuntimes = []*ateapi.WorkerSandboxRuntime{{}} }), want: field.ErrorList{field.Required(restorablePath.Index(0).Child("version"), "")}, }, { name: "restorable_runtimes at the bound", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].RestorableRuntimes = sandboxRuntimes(32) }), }, { name: "too many restorable_runtimes", - req: valid(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { + req: valid(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses[0].RestorableRuntimes = sandboxRuntimes(33) }), want: field.ErrorList{field.TooMany(restorablePath, 33, 32).WithOrigin("maxItems")}, @@ -658,24 +658,24 @@ func TestValidateSetWorkerSandboxRuntimesRequest(t *testing.T) { func TestValidateWorkerUpdate_SandboxClasses(t *testing.T) { classesPath := field.NewPath("worker", "status", "sandbox_classes") classPath := classesPath.Index(0) - oldVal := validWorker(apiWorkerName, withWorkerStatus(func(s *ateapipb.WorkerStatus) { - s.SandboxClasses = []*ateapipb.WorkerSandboxClass{validSandboxClass()} + oldVal := validWorker(apiWorkerName, withWorkerStatus(func(s *ateapi.WorkerStatus) { + s.SandboxClasses = []*ateapi.WorkerSandboxClass{validSandboxClass()} })) tests := []struct { name string - mutate func(s *ateapipb.WorkerStatus) + mutate func(s *ateapi.WorkerStatus) want field.ErrorList }{{ name: "valid runtimes", - mutate: func(s *ateapipb.WorkerStatus) { + mutate: func(s *ateapi.WorkerStatus) { s.SandboxClasses[0].RestorableRuntimes = sandboxRuntimes(32) }, }, { name: "empty sandbox_classes", - mutate: func(s *ateapipb.WorkerStatus) { s.SandboxClasses = []*ateapipb.WorkerSandboxClass{} }, + mutate: func(s *ateapi.WorkerStatus) { s.SandboxClasses = []*ateapi.WorkerSandboxClass{} }, }, { name: "too many sandbox_classes", - mutate: func(s *ateapipb.WorkerStatus) { + mutate: func(s *ateapi.WorkerStatus) { second := validSandboxClass() second.SandboxClass = "microvm" s.SandboxClasses = append(s.SandboxClasses, second) @@ -683,42 +683,42 @@ func TestValidateWorkerUpdate_SandboxClasses(t *testing.T) { want: field.ErrorList{field.TooMany(classesPath, 2, 1).WithOrigin("maxItems")}, }, { name: "missing sandbox_classes.sandbox_class", - mutate: func(s *ateapipb.WorkerStatus) { s.SandboxClasses[0].SandboxClass = "" }, + mutate: func(s *ateapi.WorkerStatus) { s.SandboxClasses[0].SandboxClass = "" }, want: field.ErrorList{field.Required(classPath.Child("sandbox_class"), "")}, }, { name: "unsupported sandbox_classes.sandbox_class", - mutate: func(s *ateapipb.WorkerStatus) { s.SandboxClasses[0].SandboxClass = "kata" }, + mutate: func(s *ateapi.WorkerStatus) { s.SandboxClasses[0].SandboxClass = "kata" }, want: field.ErrorList{field.NotSupported[string](classPath.Child("sandbox_class"), nil, nil)}, }, { name: "missing sandbox_classes.default_runtime", - mutate: func(s *ateapipb.WorkerStatus) { s.SandboxClasses[0].DefaultRuntime = nil }, + mutate: func(s *ateapi.WorkerStatus) { s.SandboxClasses[0].DefaultRuntime = nil }, want: field.ErrorList{field.Required(classPath.Child("default_runtime"), "")}, }, { name: "missing sandbox_classes.default_runtime.version", - mutate: func(s *ateapipb.WorkerStatus) { s.SandboxClasses[0].DefaultRuntime.Version = nil }, + mutate: func(s *ateapi.WorkerStatus) { s.SandboxClasses[0].DefaultRuntime.Version = nil }, want: field.ErrorList{field.Required(classPath.Child("default_runtime", "version"), "")}, }, { name: "too many default_runtime attributes", - mutate: func(s *ateapipb.WorkerStatus) { + mutate: func(s *ateapi.WorkerStatus) { s.SandboxClasses[0].DefaultRuntime.Version.Attributes = attributeEntries(33) }, want: field.ErrorList{field.TooMany(classPath.Child("default_runtime", "version", "attributes"), 33, 32).WithOrigin("maxItems")}, }, { name: "invalid restorable_runtimes entry", - mutate: func(s *ateapipb.WorkerStatus) { - s.SandboxClasses[0].RestorableRuntimes = []*ateapipb.WorkerSandboxRuntime{{Version: &ateapipb.VersionedSandboxCompat{Attributes: attributeEntries(1)}}} + mutate: func(s *ateapi.WorkerStatus) { + s.SandboxClasses[0].RestorableRuntimes = []*ateapi.WorkerSandboxRuntime{{Version: &ateapi.VersionedSandboxCompat{Attributes: attributeEntries(1)}}} }, want: field.ErrorList{field.Required(classPath.Child("restorable_runtimes").Index(0).Child("version", "schema_version"), "")}, }, { name: "too many restorable_runtimes", - mutate: func(s *ateapipb.WorkerStatus) { + mutate: func(s *ateapi.WorkerStatus) { s.SandboxClasses[0].RestorableRuntimes = sandboxRuntimes(33) }, want: field.ErrorList{field.TooMany(classPath.Child("restorable_runtimes"), 33, 32).WithOrigin("maxItems")}, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - newVal := proto.Clone(oldVal).(*ateapipb.Worker) + newVal := proto.Clone(oldVal).(*ateapi.Worker) tt.mutate(newVal.Status) assertValidateErr(t, ValidateWorkerUpdate(context.Background(), field.NewPath("worker"), newVal, oldVal, true), tt.want) }) @@ -726,10 +726,10 @@ func TestValidateWorkerUpdate_SandboxClasses(t *testing.T) { } func TestValidateRequestActorSuspendRequest(t *testing.T) { - valid := func(mutate ...func(*ateapipb.RequestActorSuspendRequest)) *ateapipb.RequestActorSuspendRequest { - r := &ateapipb.RequestActorSuspendRequest{ + valid := func(mutate ...func(*ateapi.RequestActorSuspendRequest)) *ateapi.RequestActorSuspendRequest { + r := &ateapi.RequestActorSuspendRequest{ Worker: workerRef(apiWorkerName), - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "actor-1"}, + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "actor-1"}, ActorUid: apiOtherWorkerName, } for _, m := range mutate { @@ -739,54 +739,54 @@ func TestValidateRequestActorSuspendRequest(t *testing.T) { } tests := []struct { name string - req *ateapipb.RequestActorSuspendRequest + req *ateapi.RequestActorSuspendRequest want field.ErrorList }{{ name: "valid", req: valid(), }, { name: "missing worker", - req: valid(func(r *ateapipb.RequestActorSuspendRequest) { r.Worker = nil }), + req: valid(func(r *ateapi.RequestActorSuspendRequest) { r.Worker = nil }), want: field.ErrorList{field.Required(field.NewPath("worker"), "")}, }, { name: "worker.atespace must be empty", - req: valid(func(r *ateapipb.RequestActorSuspendRequest) { r.Worker.Atespace = "team-a" }), + req: valid(func(r *ateapi.RequestActorSuspendRequest) { r.Worker.Atespace = "team-a" }), want: field.ErrorList{field.Forbidden(field.NewPath("worker", "atespace"), "")}, }, { name: "missing worker.name", - req: valid(func(r *ateapipb.RequestActorSuspendRequest) { r.Worker.Name = "" }), + req: valid(func(r *ateapi.RequestActorSuspendRequest) { r.Worker.Name = "" }), want: field.ErrorList{field.Required(field.NewPath("worker", "name"), "")}, }, { name: "invalid worker.name", - req: valid(func(r *ateapipb.RequestActorSuspendRequest) { r.Worker.Name = "UPPER" }), + req: valid(func(r *ateapi.RequestActorSuspendRequest) { r.Worker.Name = "UPPER" }), want: field.ErrorList{field.Invalid(field.NewPath("worker", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "missing actor", - req: valid(func(r *ateapipb.RequestActorSuspendRequest) { r.Actor = nil }), + req: valid(func(r *ateapi.RequestActorSuspendRequest) { r.Actor = nil }), want: field.ErrorList{field.Required(field.NewPath("actor"), "")}, }, { name: "missing actor.atespace", - req: valid(func(r *ateapipb.RequestActorSuspendRequest) { r.Actor.Atespace = "" }), + req: valid(func(r *ateapi.RequestActorSuspendRequest) { r.Actor.Atespace = "" }), want: field.ErrorList{field.Required(field.NewPath("actor", "atespace"), "")}, }, { name: "invalid actor.atespace", - req: valid(func(r *ateapipb.RequestActorSuspendRequest) { r.Actor.Atespace = "../escape" }), + req: valid(func(r *ateapi.RequestActorSuspendRequest) { r.Actor.Atespace = "../escape" }), want: field.ErrorList{field.Invalid(field.NewPath("actor", "atespace"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "missing actor.name", - req: valid(func(r *ateapipb.RequestActorSuspendRequest) { r.Actor.Name = "" }), + req: valid(func(r *ateapi.RequestActorSuspendRequest) { r.Actor.Name = "" }), want: field.ErrorList{field.Required(field.NewPath("actor", "name"), "")}, }, { name: "invalid actor.name", - req: valid(func(r *ateapipb.RequestActorSuspendRequest) { r.Actor.Name = "UPPER" }), + req: valid(func(r *ateapi.RequestActorSuspendRequest) { r.Actor.Name = "UPPER" }), want: field.ErrorList{field.Invalid(field.NewPath("actor", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "missing actor_uid", - req: valid(func(r *ateapipb.RequestActorSuspendRequest) { r.ActorUid = "" }), + req: valid(func(r *ateapi.RequestActorSuspendRequest) { r.ActorUid = "" }), want: field.ErrorList{field.Required(field.NewPath("actor_uid"), "")}, }, { name: "invalid actor_uid", - req: valid(func(r *ateapipb.RequestActorSuspendRequest) { r.ActorUid = "not-a-uuid" }), + req: valid(func(r *ateapi.RequestActorSuspendRequest) { r.ActorUid = "not-a-uuid" }), want: field.ErrorList{field.Invalid(field.NewPath("actor_uid"), nil, "").WithOrigin("format=k8s-uuid")}, }} for _, tt := range tests { @@ -797,22 +797,22 @@ func TestValidateRequestActorSuspendRequest(t *testing.T) { } func TestValidateReportActorSnapshotStateRequest(t *testing.T) { - report := func(gen int32) *ateapipb.SnapshotReport { - return &ateapipb.SnapshotReport{ + report := func(gen int32) *ateapi.SnapshotReport { + return &ateapi.SnapshotReport{ Uuid: fmt.Sprintf("snap-%d", gen), Generation: gen, - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: fmt.Sprintf("gs://bucket/actors/a/snap-%d", gen)}, + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + Object: &ateapi.ObjectSnapshot{SnapshotUri: fmt.Sprintf("gs://bucket/actors/a/snap-%d", gen)}, LocalCommitTime: timestamppb.Now(), } } - valid := func(mutate ...func(*ateapipb.ReportActorSnapshotStateRequest)) *ateapipb.ReportActorSnapshotStateRequest { + valid := func(mutate ...func(*ateapi.ReportActorSnapshotStateRequest)) *ateapi.ReportActorSnapshotStateRequest { durable := report(1) durable.DurableCompleteTime = timestamppb.Now() - r := &ateapipb.ReportActorSnapshotStateRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "actor-1"}, + r := &ateapi.ReportActorSnapshotStateRequest{ + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "actor-1"}, ActorUid: apiOtherWorkerName, - State: &ateapipb.ActorSnapshotState{ + State: &ateapi.ActorSnapshotState{ LatestLocal: report(2), Uploading: report(2), LatestDurable: durable, @@ -827,91 +827,91 @@ func TestValidateReportActorSnapshotStateRequest(t *testing.T) { local := field.NewPath("state", "latest_local") tests := []struct { name string - req *ateapipb.ReportActorSnapshotStateRequest + req *ateapi.ReportActorSnapshotStateRequest want field.ErrorList }{{ name: "valid", req: valid(), }, { name: "valid detach: no local snapshot", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.State.LatestLocal = nil r.State.Uploading = nil r.State.UploadDueTime = nil }), }, { name: "empty state", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.State = &ateapipb.ActorSnapshotState{} }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.State = &ateapi.ActorSnapshotState{} }), want: field.ErrorList{field.Required(field.NewPath("state", "latest_durable"), "")}, }, { name: "valid upload in flight with no local snapshot", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { - r.State = &ateapipb.ActorSnapshotState{Uploading: r.State.GetUploading()} + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { + r.State = &ateapi.ActorSnapshotState{Uploading: r.State.GetUploading()} }), }, { name: "missing actor", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.Actor = nil }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.Actor = nil }), want: field.ErrorList{field.Required(field.NewPath("actor"), "")}, }, { name: "missing actor.atespace", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.Actor.Atespace = "" }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.Actor.Atespace = "" }), want: field.ErrorList{field.Required(field.NewPath("actor", "atespace"), "")}, }, { name: "invalid actor.name", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.Actor.Name = "UPPER" }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.Actor.Name = "UPPER" }), want: field.ErrorList{field.Invalid(field.NewPath("actor", "name"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "missing actor_uid", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.ActorUid = "" }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.ActorUid = "" }), want: field.ErrorList{field.Required(field.NewPath("actor_uid"), "")}, }, { name: "invalid actor_uid", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.ActorUid = "not-a-uuid" }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.ActorUid = "not-a-uuid" }), want: field.ErrorList{field.Invalid(field.NewPath("actor_uid"), nil, "").WithOrigin("format=k8s-uuid")}, }, { name: "missing state", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.State = nil }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.State = nil }), want: field.ErrorList{field.Required(field.NewPath("state"), "")}, }, { name: "missing uuid", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.State.LatestLocal.Uuid = "" }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.State.LatestLocal.Uuid = "" }), want: field.ErrorList{field.Required(local.Child("uuid"), "")}, }, { name: "invalid uuid", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.State.LatestLocal.Uuid = "../escape" }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.State.LatestLocal.Uuid = "../escape" }), want: field.ErrorList{field.Invalid(local.Child("uuid"), nil, "").WithOrigin("format=k8s-short-name")}, }, { name: "generation below 1", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.State.LatestLocal.Generation = -1 }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.State.LatestLocal.Generation = -1 }), want: field.ErrorList{field.Invalid(local.Child("generation"), nil, "").WithOrigin("minimum")}, }, { name: "missing fidelity", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { - r.State.LatestLocal.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { + r.State.LatestLocal.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED }), want: field.ErrorList{field.Required(local.Child("fidelity"), "")}, }, { name: "unknown fidelity", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.State.LatestLocal.Fidelity = 4 }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.State.LatestLocal.Fidelity = 4 }), want: field.ErrorList{field.Invalid(local.Child("fidelity"), nil, "").WithOrigin("maximum")}, }, { name: "missing object", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.State.LatestLocal.Object = nil }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.State.LatestLocal.Object = nil }), want: field.ErrorList{field.Required(local.Child("object"), "")}, }, { name: "missing object.snapshot_uri", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.State.LatestLocal.Object.SnapshotUri = "" }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.State.LatestLocal.Object.SnapshotUri = "" }), want: field.ErrorList{field.Required(local.Child("object", "snapshot_uri"), "")}, }, { name: "valid without local_commit_time", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.State.LatestDurable.LocalCommitTime = nil }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.State.LatestDurable.LocalCommitTime = nil }), }, { name: "uploading is validated", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.State.Uploading.Uuid = "" }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.State.Uploading.Uuid = "" }), want: field.ErrorList{field.Required(field.NewPath("state", "uploading", "uuid"), "")}, }, { name: "latest_durable is validated", - req: valid(func(r *ateapipb.ReportActorSnapshotStateRequest) { r.State.LatestDurable.Object = nil }), + req: valid(func(r *ateapi.ReportActorSnapshotStateRequest) { r.State.LatestDurable.Object = nil }), want: field.ErrorList{field.Required(field.NewPath("state", "latest_durable", "object"), "")}, }} for _, tt := range tests { @@ -923,9 +923,9 @@ func TestValidateReportActorSnapshotStateRequest(t *testing.T) { // validWorker returns a Worker in the shape CreateWorker accepts: named, with // its pod coordinates filled in and no status — status is output-only. -func validWorker(name string, mods ...func(*ateapipb.Worker)) *ateapipb.Worker { - w := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: name}, +func validWorker(name string, mods ...func(*ateapi.Worker)) *ateapi.Worker { + w := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: name}, WorkerNamespace: "ate-system", WorkerPool: "pool-1", WorkerPod: "worker-pod-1", @@ -940,16 +940,16 @@ func validWorker(name string, mods ...func(*ateapipb.Worker)) *ateapipb.Worker { // withWorkerMetadata returns a modifier func (see validWorker) which sets // the worker's resource metadata to a valid value. -func withWorkerMetadata(mutate func(*ateapipb.ResourceMetadata)) func(*ateapipb.Worker) { - return func(a *ateapipb.Worker) { mutate(a.Metadata) } +func withWorkerMetadata(mutate func(*ateapi.ResourceMetadata)) func(*ateapi.Worker) { + return func(a *ateapi.Worker) { mutate(a.Metadata) } } // withWorkerStatus returns a modifier func (see validWorker) which sets the // actor's status to a valid value. -func withWorkerStatus(mods ...func(*ateapipb.WorkerStatus)) func(*ateapipb.Worker) { - return func(a *ateapipb.Worker) { - a.Status = &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, +func withWorkerStatus(mods ...func(*ateapi.WorkerStatus)) func(*ateapi.Worker) { + return func(a *ateapi.Worker) { + a.Status = &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, } for _, m := range mods { m(a.Status) @@ -957,41 +957,41 @@ func withWorkerStatus(mods ...func(*ateapipb.WorkerStatus)) func(*ateapipb.Worke } } -func workerRef(name string) *ateapipb.ObjectRef { - return &ateapipb.ObjectRef{Name: name} +func workerRef(name string) *ateapi.ObjectRef { + return &ateapi.ObjectRef{Name: name} } // validSandboxClass returns a WorkerSandboxClass in the shape RegisterWorker // accepts: a sandbox class and a default runtime, with nothing restorable. -func validSandboxClass() *ateapipb.WorkerSandboxClass { - return &ateapipb.WorkerSandboxClass{ +func validSandboxClass() *ateapi.WorkerSandboxClass { + return &ateapi.WorkerSandboxClass{ SandboxClass: "gvisor", - DefaultRuntime: &ateapipb.WorkerSandboxRuntime{Version: validSandboxCompat()}, + DefaultRuntime: &ateapi.WorkerSandboxRuntime{Version: validSandboxCompat()}, } } // validSandboxCompat returns a v1 compatibility identity with one attribute. -func validSandboxCompat() *ateapipb.VersionedSandboxCompat { - return &ateapipb.VersionedSandboxCompat{ +func validSandboxCompat() *ateapi.VersionedSandboxCompat { + return &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{{Key: "architecture", Value: "amd64"}}, + Attributes: []*ateapi.AttributeEntry{{Key: "architecture", Value: "amd64"}}, } } // attributeEntries returns n valid attributes with distinct keys. -func attributeEntries(n int) []*ateapipb.AttributeEntry { - attrs := make([]*ateapipb.AttributeEntry, n) +func attributeEntries(n int) []*ateapi.AttributeEntry { + attrs := make([]*ateapi.AttributeEntry, n) for i := range attrs { - attrs[i] = &ateapipb.AttributeEntry{Key: fmt.Sprintf("k%d", i), Value: "v"} + attrs[i] = &ateapi.AttributeEntry{Key: fmt.Sprintf("k%d", i), Value: "v"} } return attrs } // sandboxRuntimes returns n valid runtimes. -func sandboxRuntimes(n int) []*ateapipb.WorkerSandboxRuntime { - runtimes := make([]*ateapipb.WorkerSandboxRuntime, n) +func sandboxRuntimes(n int) []*ateapi.WorkerSandboxRuntime { + runtimes := make([]*ateapi.WorkerSandboxRuntime, n) for i := range runtimes { - runtimes[i] = &ateapipb.WorkerSandboxRuntime{Version: validSandboxCompat()} + runtimes[i] = &ateapi.WorkerSandboxRuntime{Version: validSandboxCompat()} } return runtimes } diff --git a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go index bb5572845b..5d32a05e7c 100644 --- a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go +++ b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go @@ -22,7 +22,7 @@ package apivalidation import ( context "context" - ateapipb "go.ate.dev/substrate/pkg/proto/ateapipb" + v1 "go.ate.dev/substrate/api/ateapi/v1" timestamppb "google.golang.org/protobuf/types/known/timestamppb" operation "k8s.io/apimachinery/pkg/api/operation" safe "k8s.io/apimachinery/pkg/api/safe" @@ -34,12 +34,12 @@ import ( // to declarative validation rules in the API schema. func Validate_AccessPolicy( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.AccessPolicy) (errs field.ErrorList) { + obj, oldObj *v1.AccessPolicy) (errs field.ErrorList) { - { // field ateapipb.AccessPolicy.Metadata + { // field v1.AccessPolicy.Metadata fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ResourceMetadata, + obj, oldObj *v1.ResourceMetadata, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -65,16 +65,16 @@ func Validate_AccessPolicy( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.AccessPolicy) *ateapipb.ResourceMetadata { + func(oldObj *v1.AccessPolicy) *v1.ResourceMetadata { return oldObj.Metadata }) errs = append(errs, fn(fldPath.Child("metadata"), obj.Metadata, oldVal, oldObj != nil)...) } - { // field ateapipb.AccessPolicy.Bindings + { // field v1.AccessPolicy.Bindings fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.Binding, + obj, oldObj []*v1.Binding, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -84,7 +84,7 @@ func Validate_AccessPolicy( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.Binding](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.Binding](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -105,7 +105,7 @@ func Validate_AccessPolicy( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.AccessPolicy) []*ateapipb.Binding { + func(oldObj *v1.AccessPolicy) []*v1.Binding { return oldObj.Bindings }) errs = append(errs, fn(fldPath.Child("bindings"), obj.Bindings, oldVal, oldObj != nil)...) @@ -118,12 +118,12 @@ func Validate_AccessPolicy( // to declarative validation rules in the API schema. func Validate_AcquireWorkerEpochRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.AcquireWorkerEpochRequest) (errs field.ErrorList) { + obj, oldObj *v1.AcquireWorkerEpochRequest) (errs field.ErrorList) { - { // field ateapipb.AcquireWorkerEpochRequest.Worker + { // field v1.AcquireWorkerEpochRequest.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -143,16 +143,16 @@ func Validate_AcquireWorkerEpochRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -164,7 +164,7 @@ func Validate_AcquireWorkerEpochRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.AcquireWorkerEpochRequest) *ateapipb.ObjectRef { + func(oldObj *v1.AcquireWorkerEpochRequest) *v1.ObjectRef { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) @@ -177,12 +177,12 @@ func Validate_AcquireWorkerEpochRequest( // to declarative validation rules in the API schema. func Validate_Actor( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.Actor) (errs field.ErrorList) { + obj, oldObj *v1.Actor) (errs field.ErrorList) { - { // field ateapipb.Actor.Metadata + { // field v1.Actor.Metadata fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ResourceMetadata, + obj, oldObj *v1.ResourceMetadata, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -202,16 +202,16 @@ func Validate_Actor( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.Immutable).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.Immutable).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -223,16 +223,16 @@ func Validate_Actor( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Actor) *ateapipb.ResourceMetadata { + func(oldObj *v1.Actor) *v1.ResourceMetadata { return oldObj.Metadata }) errs = append(errs, fn(fldPath.Child("metadata"), obj.Metadata, oldVal, oldObj != nil)...) } - { // field ateapipb.Actor.ActorTemplate + { // field v1.Actor.ActorTemplate fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -252,12 +252,12 @@ func Validate_Actor( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -269,16 +269,16 @@ func Validate_Actor( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Actor) *ateapipb.ObjectRef { + func(oldObj *v1.Actor) *v1.ObjectRef { return oldObj.ActorTemplate }) errs = append(errs, fn(fldPath.Child("actor_template"), obj.ActorTemplate, oldVal, oldObj != nil)...) } - { // field ateapipb.Actor.WorkerSelector + { // field v1.Actor.WorkerSelector fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Selector, + obj, oldObj *v1.Selector, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -299,16 +299,16 @@ func Validate_Actor( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Actor) *ateapipb.Selector { + func(oldObj *v1.Actor) *v1.Selector { return oldObj.WorkerSelector }) errs = append(errs, fn(fldPath.Child("worker_selector"), obj.WorkerSelector, oldVal, oldObj != nil)...) } - { // field ateapipb.Actor.SourceTag + { // field v1.Actor.SourceTag fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -331,12 +331,12 @@ func Validate_Actor( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -348,16 +348,16 @@ func Validate_Actor( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Actor) *ateapipb.ObjectRef { + func(oldObj *v1.Actor) *v1.ObjectRef { return oldObj.SourceTag }) errs = append(errs, fn(fldPath.Child("source_tag"), obj.SourceTag, oldVal, oldObj != nil)...) } - { // field ateapipb.Actor.Status + { // field v1.Actor.Status fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ActorStatus, + obj, oldObj *v1.ActorStatus, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -378,7 +378,7 @@ func Validate_Actor( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Actor) *ateapipb.ActorStatus { + func(oldObj *v1.Actor) *v1.ActorStatus { return oldObj.Status }) errs = append(errs, fn(fldPath.Child("status"), obj.Status, oldVal, oldObj != nil)...) @@ -391,9 +391,9 @@ func Validate_Actor( // to declarative validation rules in the API schema. func Validate_ActorCrash( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ActorCrash) (errs field.ErrorList) { + obj, oldObj *v1.ActorCrash) (errs field.ErrorList) { - { // field ateapipb.ActorCrash.Message + { // field v1.ActorCrash.Message fn := func( fldPath *field.Path, obj, oldObj *string, @@ -418,13 +418,13 @@ func Validate_ActorCrash( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorCrash) *string { + func(oldObj *v1.ActorCrash) *string { return &oldObj.Message }) errs = append(errs, fn(fldPath.Child("message"), &obj.Message, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorCrash.CrashTime + { // field v1.ActorCrash.CrashTime fn := func( fldPath *field.Path, obj, oldObj *timestamppb.Timestamp, @@ -446,7 +446,7 @@ func Validate_ActorCrash( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorCrash) *timestamppb.Timestamp { + func(oldObj *v1.ActorCrash) *timestamppb.Timestamp { return oldObj.CrashTime }) errs = append(errs, fn(fldPath.Child("crash_time"), obj.CrashTime, oldVal, oldObj != nil)...) @@ -459,9 +459,9 @@ func Validate_ActorCrash( // to declarative validation rules in the API schema. func Validate_ActorJwtSource( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ActorJwtSource) (errs field.ErrorList) { + obj, oldObj *v1.ActorJwtSource) (errs field.ErrorList) { - { // field ateapipb.ActorJwtSource.Audiences + { // field v1.ActorJwtSource.Audiences fn := func( fldPath *field.Path, obj, oldObj []string, @@ -504,13 +504,13 @@ func Validate_ActorJwtSource( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorJwtSource) []string { + func(oldObj *v1.ActorJwtSource) []string { return oldObj.Audiences }) errs = append(errs, fn(fldPath.Child("audiences"), obj.Audiences, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorJwtSource.ExpirationSeconds + { // field v1.ActorJwtSource.ExpirationSeconds fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -539,7 +539,7 @@ func Validate_ActorJwtSource( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorJwtSource) *int64 { + func(oldObj *v1.ActorJwtSource) *int64 { return &oldObj.ExpirationSeconds }) errs = append(errs, fn(fldPath.Child("expiration_seconds"), &obj.ExpirationSeconds, oldVal, oldObj != nil)...) @@ -552,12 +552,12 @@ func Validate_ActorJwtSource( // to declarative validation rules in the API schema. func Validate_ActorMetadataDataSource( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ActorMetadataDataSource) (errs field.ErrorList) { + obj, oldObj *v1.ActorMetadataDataSource) (errs field.ErrorList) { - { // field ateapipb.ActorMetadataDataSource.Items + { // field v1.ActorMetadataDataSource.Items fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.ActorMetadataItem, + obj, oldObj []*v1.ActorMetadataItem, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -567,7 +567,7 @@ func Validate_ActorMetadataDataSource( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.ActorMetadataItem](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.ActorMetadataItem](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -587,18 +587,18 @@ func Validate_ActorMetadataDataSource( } // lists with map semantics require unique keys if e := validate.PtrSliceUnique(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.ActorMetadataItem, b *ateapipb.ActorMetadataItem) bool { return a.Field == b.Field }); len(e) != 0 { + func(a *v1.ActorMetadataItem, b *v1.ActorMetadataItem) bool { return a.Field == b.Field }); len(e) != 0 { errs = append(errs, e...) } // iterate the list and call the type's validation function if e := validate.EachPtrSliceVal(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.ActorMetadataItem, b *ateapipb.ActorMetadataItem) bool { return a.Field == b.Field }, ateDeepEqual, Validate_ActorMetadataItem); len(e) != 0 { + func(a *v1.ActorMetadataItem, b *v1.ActorMetadataItem) bool { return a.Field == b.Field }, ateDeepEqual, Validate_ActorMetadataItem); len(e) != 0 { errs = append(errs, e...) } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorMetadataDataSource) []*ateapipb.ActorMetadataItem { + func(oldObj *v1.ActorMetadataDataSource) []*v1.ActorMetadataItem { return oldObj.Items }) errs = append(errs, fn(fldPath.Child("items"), obj.Items, oldVal, oldObj != nil)...) @@ -611,12 +611,12 @@ func Validate_ActorMetadataDataSource( // to declarative validation rules in the API schema. func Validate_ActorMetadataItem( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ActorMetadataItem) (errs field.ErrorList) { + obj, oldObj *v1.ActorMetadataItem) (errs field.ErrorList) { - { // field ateapipb.ActorMetadataItem.Field + { // field v1.ActorMetadataItem.Field fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ActorMetadataField, + obj, oldObj *v1.ActorMetadataField, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -642,13 +642,13 @@ func Validate_ActorMetadataItem( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorMetadataItem) *ateapipb.ActorMetadataField { + func(oldObj *v1.ActorMetadataItem) *v1.ActorMetadataField { return &oldObj.Field }) errs = append(errs, fn(fldPath.Child("field"), &obj.Field, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorMetadataItem.Path + { // field v1.ActorMetadataItem.Path fn := func( fldPath *field.Path, obj, oldObj *string, @@ -681,7 +681,7 @@ func Validate_ActorMetadataItem( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorMetadataItem) *string { + func(oldObj *v1.ActorMetadataItem) *string { return &oldObj.Path }) errs = append(errs, fn(fldPath.Child("path"), &obj.Path, oldVal, oldObj != nil)...) @@ -694,9 +694,9 @@ func Validate_ActorMetadataItem( // to declarative validation rules in the API schema. func Validate_ActorSandboxRuntime( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ActorSandboxRuntime) (errs field.ErrorList) { + obj, oldObj *v1.ActorSandboxRuntime) (errs field.ErrorList) { - { // field ateapipb.ActorSandboxRuntime.SandboxClass + { // field v1.ActorSandboxRuntime.SandboxClass fn := func( fldPath *field.Path, obj, oldObj *string, @@ -726,16 +726,16 @@ func Validate_ActorSandboxRuntime( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorSandboxRuntime) *string { + func(oldObj *v1.ActorSandboxRuntime) *string { return &oldObj.SandboxClass }) errs = append(errs, fn(fldPath.Child("sandbox_class"), &obj.SandboxClass, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorSandboxRuntime.Version + { // field v1.ActorSandboxRuntime.Version fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.VersionedSandboxCompat, + obj, oldObj *v1.VersionedSandboxCompat, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -757,7 +757,7 @@ func Validate_ActorSandboxRuntime( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorSandboxRuntime) *ateapipb.VersionedSandboxCompat { + func(oldObj *v1.ActorSandboxRuntime) *v1.VersionedSandboxCompat { return oldObj.Version }) errs = append(errs, fn(fldPath.Child("version"), obj.Version, oldVal, oldObj != nil)...) @@ -770,12 +770,12 @@ func Validate_ActorSandboxRuntime( // to declarative validation rules in the API schema. func Validate_ActorSnapshotState( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ActorSnapshotState) (errs field.ErrorList) { + obj, oldObj *v1.ActorSnapshotState) (errs field.ErrorList) { - { // field ateapipb.ActorSnapshotState.LatestLocal + { // field v1.ActorSnapshotState.LatestLocal fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.SnapshotReport, + obj, oldObj *v1.SnapshotReport, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -796,16 +796,16 @@ func Validate_ActorSnapshotState( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorSnapshotState) *ateapipb.SnapshotReport { + func(oldObj *v1.ActorSnapshotState) *v1.SnapshotReport { return oldObj.LatestLocal }) errs = append(errs, fn(fldPath.Child("latest_local"), obj.LatestLocal, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorSnapshotState.Uploading + { // field v1.ActorSnapshotState.Uploading fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.SnapshotReport, + obj, oldObj *v1.SnapshotReport, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -826,16 +826,16 @@ func Validate_ActorSnapshotState( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorSnapshotState) *ateapipb.SnapshotReport { + func(oldObj *v1.ActorSnapshotState) *v1.SnapshotReport { return oldObj.Uploading }) errs = append(errs, fn(fldPath.Child("uploading"), obj.Uploading, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorSnapshotState.LatestDurable + { // field v1.ActorSnapshotState.LatestDurable fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.SnapshotReport, + obj, oldObj *v1.SnapshotReport, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -856,13 +856,13 @@ func Validate_ActorSnapshotState( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorSnapshotState) *ateapipb.SnapshotReport { + func(oldObj *v1.ActorSnapshotState) *v1.SnapshotReport { return oldObj.LatestDurable }) errs = append(errs, fn(fldPath.Child("latest_durable"), obj.LatestDurable, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorSnapshotState.UploadDueTime + { // field v1.ActorSnapshotState.UploadDueTime fn := func( fldPath *field.Path, obj, oldObj *timestamppb.Timestamp, @@ -884,7 +884,7 @@ func Validate_ActorSnapshotState( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorSnapshotState) *timestamppb.Timestamp { + func(oldObj *v1.ActorSnapshotState) *timestamppb.Timestamp { return oldObj.UploadDueTime }) errs = append(errs, fn(fldPath.Child("upload_due_time"), obj.UploadDueTime, oldVal, oldObj != nil)...) @@ -897,12 +897,12 @@ func Validate_ActorSnapshotState( // to declarative validation rules in the API schema. func Validate_ActorStatus( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ActorStatus) (errs field.ErrorList) { + obj, oldObj *v1.ActorStatus) (errs field.ErrorList) { - { // field ateapipb.ActorStatus.State + { // field v1.ActorStatus.State fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ActorState, + obj, oldObj *v1.ActorState, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -928,16 +928,16 @@ func Validate_ActorStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorStatus) *ateapipb.ActorState { + func(oldObj *v1.ActorStatus) *v1.ActorState { return &oldObj.State }) errs = append(errs, fn(fldPath.Child("state"), &obj.State, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorStatus.WorkerAssignment + { // field v1.ActorStatus.WorkerAssignment fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.WorkerAssignment, + obj, oldObj *v1.WorkerAssignment, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -958,16 +958,16 @@ func Validate_ActorStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorStatus) *ateapipb.WorkerAssignment { + func(oldObj *v1.ActorStatus) *v1.WorkerAssignment { return oldObj.WorkerAssignment }) errs = append(errs, fn(fldPath.Child("worker_assignment"), obj.WorkerAssignment, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorStatus.ExternalVolumes + { // field v1.ActorStatus.ExternalVolumes fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ExternalVolumes, + obj, oldObj *v1.ExternalVolumes, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -988,16 +988,16 @@ func Validate_ActorStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorStatus) *ateapipb.ExternalVolumes { + func(oldObj *v1.ActorStatus) *v1.ExternalVolumes { return oldObj.ExternalVolumes }) errs = append(errs, fn(fldPath.Child("external_volumes"), obj.ExternalVolumes, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorStatus.Crash + { // field v1.ActorStatus.Crash fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ActorCrash, + obj, oldObj *v1.ActorCrash, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -1018,13 +1018,13 @@ func Validate_ActorStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorStatus) *ateapipb.ActorCrash { + func(oldObj *v1.ActorStatus) *v1.ActorCrash { return oldObj.Crash }) errs = append(errs, fn(fldPath.Child("crash"), obj.Crash, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorStatus.AssignedNode + { // field v1.ActorStatus.AssignedNode fn := func( fldPath *field.Path, obj, oldObj *string, @@ -1049,16 +1049,16 @@ func Validate_ActorStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorStatus) *string { + func(oldObj *v1.ActorStatus) *string { return &oldObj.AssignedNode }) errs = append(errs, fn(fldPath.Child("assigned_node"), &obj.AssignedNode, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorStatus.Snapshots + { // field v1.ActorStatus.Snapshots fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.Snapshot, + obj, oldObj []*v1.Snapshot, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -1068,7 +1068,7 @@ func Validate_ActorStatus( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.Snapshot](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.Snapshot](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -1084,24 +1084,24 @@ func Validate_ActorStatus( } // lists with map semantics require unique keys if e := validate.PtrSliceUnique(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.Snapshot, b *ateapipb.Snapshot) bool { return a.Generation == b.Generation }); len(e) != 0 { + func(a *v1.Snapshot, b *v1.Snapshot) bool { return a.Generation == b.Generation }); len(e) != 0 { errs = append(errs, e...) } // iterate the list and call the type's validation function if e := validate.EachPtrSliceVal(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.Snapshot, b *ateapipb.Snapshot) bool { return a.Generation == b.Generation }, ateDeepEqual, Validate_Snapshot); len(e) != 0 { + func(a *v1.Snapshot, b *v1.Snapshot) bool { return a.Generation == b.Generation }, ateDeepEqual, Validate_Snapshot); len(e) != 0 { errs = append(errs, e...) } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorStatus) []*ateapipb.Snapshot { + func(oldObj *v1.ActorStatus) []*v1.Snapshot { return oldObj.Snapshots }) errs = append(errs, fn(fldPath.Child("snapshots"), obj.Snapshots, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorStatus.LastAssignedGeneration + { // field v1.ActorStatus.LastAssignedGeneration fn := func( fldPath *field.Path, obj, oldObj *int32, @@ -1134,7 +1134,7 @@ func Validate_ActorStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorStatus) *int32 { + func(oldObj *v1.ActorStatus) *int32 { return &oldObj.LastAssignedGeneration }) errs = append(errs, fn(fldPath.Child("last_assigned_generation"), &obj.LastAssignedGeneration, oldVal, oldObj != nil)...) @@ -1147,12 +1147,12 @@ func Validate_ActorStatus( // to declarative validation rules in the API schema. func Validate_ActorTemplate( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ActorTemplate) (errs field.ErrorList) { + obj, oldObj *v1.ActorTemplate) (errs field.ErrorList) { - { // field ateapipb.ActorTemplate.Metadata + { // field v1.ActorTemplate.Metadata fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ResourceMetadata, + obj, oldObj *v1.ResourceMetadata, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -1172,16 +1172,16 @@ func Validate_ActorTemplate( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.Immutable).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.Immutable).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -1193,16 +1193,16 @@ func Validate_ActorTemplate( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorTemplate) *ateapipb.ResourceMetadata { + func(oldObj *v1.ActorTemplate) *v1.ResourceMetadata { return oldObj.Metadata }) errs = append(errs, fn(fldPath.Child("metadata"), obj.Metadata, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorTemplate.WorkerSelector + { // field v1.ActorTemplate.WorkerSelector fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Selector, + obj, oldObj *v1.Selector, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -1223,16 +1223,16 @@ func Validate_ActorTemplate( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorTemplate) *ateapipb.Selector { + func(oldObj *v1.ActorTemplate) *v1.Selector { return oldObj.WorkerSelector }) errs = append(errs, fn(fldPath.Child("worker_selector"), obj.WorkerSelector, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorTemplate.Containers + { // field v1.ActorTemplate.Containers fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.Container, + obj, oldObj []*v1.Container, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -1242,7 +1242,7 @@ func Validate_ActorTemplate( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.Container](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.Container](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -1259,27 +1259,27 @@ func Validate_ActorTemplate( } // lists with map semantics require unique keys if e := validate.PtrSliceUnique(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.Container, b *ateapipb.Container) bool { return a.Name == b.Name }); len(e) != 0 { + func(a *v1.Container, b *v1.Container) bool { return a.Name == b.Name }); len(e) != 0 { errs = append(errs, e...) } // iterate the list and call the type's validation function if e := validate.EachPtrSliceVal(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.Container, b *ateapipb.Container) bool { return a.Name == b.Name }, ateDeepEqual, Validate_Container); len(e) != 0 { + func(a *v1.Container, b *v1.Container) bool { return a.Name == b.Name }, ateDeepEqual, Validate_Container); len(e) != 0 { errs = append(errs, e...) } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorTemplate) []*ateapipb.Container { + func(oldObj *v1.ActorTemplate) []*v1.Container { return oldObj.Containers }) errs = append(errs, fn(fldPath.Child("containers"), obj.Containers, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorTemplate.Volumes + { // field v1.ActorTemplate.Volumes fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.Volume, + obj, oldObj []*v1.Volume, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -1289,7 +1289,7 @@ func Validate_ActorTemplate( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.Volume](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.Volume](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -1305,27 +1305,27 @@ func Validate_ActorTemplate( } // lists with map semantics require unique keys if e := validate.PtrSliceUnique(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.Volume, b *ateapipb.Volume) bool { return a.Name == b.Name }); len(e) != 0 { + func(a *v1.Volume, b *v1.Volume) bool { return a.Name == b.Name }); len(e) != 0 { errs = append(errs, e...) } // iterate the list and call the type's validation function if e := validate.EachPtrSliceVal(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.Volume, b *ateapipb.Volume) bool { return a.Name == b.Name }, ateDeepEqual, Validate_Volume); len(e) != 0 { + func(a *v1.Volume, b *v1.Volume) bool { return a.Name == b.Name }, ateDeepEqual, Validate_Volume); len(e) != 0 { errs = append(errs, e...) } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorTemplate) []*ateapipb.Volume { + func(oldObj *v1.ActorTemplate) []*v1.Volume { return oldObj.Volumes }) errs = append(errs, fn(fldPath.Child("volumes"), obj.Volumes, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorTemplate.SnapshotConfig + { // field v1.ActorTemplate.SnapshotConfig fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.SnapshotConfig, + obj, oldObj *v1.SnapshotConfig, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -1346,16 +1346,16 @@ func Validate_ActorTemplate( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorTemplate) *ateapipb.SnapshotConfig { + func(oldObj *v1.ActorTemplate) *v1.SnapshotConfig { return oldObj.SnapshotConfig }) errs = append(errs, fn(fldPath.Child("snapshot_config"), obj.SnapshotConfig, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorTemplate.Resources + { // field v1.ActorTemplate.Resources fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ResourceRequirements, + obj, oldObj *v1.ResourceRequirements, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -1381,16 +1381,16 @@ func Validate_ActorTemplate( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorTemplate) *ateapipb.ResourceRequirements { + func(oldObj *v1.ActorTemplate) *v1.ResourceRequirements { return oldObj.Resources }) errs = append(errs, fn(fldPath.Child("resources"), obj.Resources, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorTemplate.GoldenEgressPolicy + { // field v1.ActorTemplate.GoldenEgressPolicy fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.EgressPolicyTemplate, + obj, oldObj *v1.EgressPolicyTemplate, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -1418,16 +1418,16 @@ func Validate_ActorTemplate( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorTemplate) *ateapipb.EgressPolicyTemplate { + func(oldObj *v1.ActorTemplate) *v1.EgressPolicyTemplate { return oldObj.GoldenEgressPolicy }) errs = append(errs, fn(fldPath.Child("golden_egress_policy"), obj.GoldenEgressPolicy, oldVal, oldObj != nil)...) } - { // field ateapipb.ActorTemplate.Status + { // field v1.ActorTemplate.Status fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ActorTemplateStatus, + obj, oldObj *v1.ActorTemplateStatus, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -1448,7 +1448,7 @@ func Validate_ActorTemplate( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorTemplate) *ateapipb.ActorTemplateStatus { + func(oldObj *v1.ActorTemplate) *v1.ActorTemplateStatus { return oldObj.Status }) errs = append(errs, fn(fldPath.Child("status"), obj.Status, oldVal, oldObj != nil)...) @@ -1461,12 +1461,12 @@ func Validate_ActorTemplate( // to declarative validation rules in the API schema. func Validate_ActorTemplateStatus( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ActorTemplateStatus) (errs field.ErrorList) { + obj, oldObj *v1.ActorTemplateStatus) (errs field.ErrorList) { - { // field ateapipb.ActorTemplateStatus.GoldenSnapshotStatus + { // field v1.ActorTemplateStatus.GoldenSnapshotStatus fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.GoldenSnapshotStatus, + obj, oldObj *v1.GoldenSnapshotStatus, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -1487,7 +1487,7 @@ func Validate_ActorTemplateStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ActorTemplateStatus) *ateapipb.GoldenSnapshotStatus { + func(oldObj *v1.ActorTemplateStatus) *v1.GoldenSnapshotStatus { return oldObj.GoldenSnapshotStatus }) errs = append(errs, fn(fldPath.Child("golden_snapshot_status"), obj.GoldenSnapshotStatus, oldVal, oldObj != nil)...) @@ -1500,12 +1500,12 @@ func Validate_ActorTemplateStatus( // to declarative validation rules in the API schema. func Validate_Atespace( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.Atespace) (errs field.ErrorList) { + obj, oldObj *v1.Atespace) (errs field.ErrorList) { - { // field ateapipb.Atespace.Metadata + { // field v1.Atespace.Metadata fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ResourceMetadata, + obj, oldObj *v1.ResourceMetadata, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -1525,20 +1525,20 @@ func Validate_Atespace( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.Immutable).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.Immutable).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -1550,7 +1550,7 @@ func Validate_Atespace( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Atespace) *ateapipb.ResourceMetadata { + func(oldObj *v1.Atespace) *v1.ResourceMetadata { return oldObj.Metadata }) errs = append(errs, fn(fldPath.Child("metadata"), obj.Metadata, oldVal, oldObj != nil)...) @@ -1563,9 +1563,9 @@ func Validate_Atespace( // to declarative validation rules in the API schema. func Validate_AttributeEntry( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.AttributeEntry) (errs field.ErrorList) { + obj, oldObj *v1.AttributeEntry) (errs field.ErrorList) { - { // field ateapipb.AttributeEntry.Key + { // field v1.AttributeEntry.Key fn := func( fldPath *field.Path, obj, oldObj *string, @@ -1591,13 +1591,13 @@ func Validate_AttributeEntry( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.AttributeEntry) *string { + func(oldObj *v1.AttributeEntry) *string { return &oldObj.Key }) errs = append(errs, fn(fldPath.Child("key"), &obj.Key, oldVal, oldObj != nil)...) } - { // field ateapipb.AttributeEntry.Value + { // field v1.AttributeEntry.Value fn := func( fldPath *field.Path, obj, oldObj *string, @@ -1623,7 +1623,7 @@ func Validate_AttributeEntry( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.AttributeEntry) *string { + func(oldObj *v1.AttributeEntry) *string { return &oldObj.Value }) errs = append(errs, fn(fldPath.Child("value"), &obj.Value, oldVal, oldObj != nil)...) @@ -1636,9 +1636,9 @@ func Validate_AttributeEntry( // to declarative validation rules in the API schema. func Validate_Binding( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.Binding) (errs field.ErrorList) { + obj, oldObj *v1.Binding) (errs field.ErrorList) { - { // field ateapipb.Binding.Role + { // field v1.Binding.Role fn := func( fldPath *field.Path, obj, oldObj *string, @@ -1664,13 +1664,13 @@ func Validate_Binding( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Binding) *string { + func(oldObj *v1.Binding) *string { return &oldObj.Role }) errs = append(errs, fn(fldPath.Child("role"), &obj.Role, oldVal, oldObj != nil)...) } - { // field ateapipb.Binding.Members + { // field v1.Binding.Members fn := func( fldPath *field.Path, obj, oldObj []string, @@ -1707,7 +1707,7 @@ func Validate_Binding( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Binding) []string { + func(oldObj *v1.Binding) []string { return oldObj.Members }) errs = append(errs, fn(fldPath.Child("members"), obj.Members, oldVal, oldObj != nil)...) @@ -1720,9 +1720,9 @@ func Validate_Binding( // to declarative validation rules in the API schema. func Validate_Capabilities( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.Capabilities) (errs field.ErrorList) { + obj, oldObj *v1.Capabilities) (errs field.ErrorList) { - { // field ateapipb.Capabilities.Add + { // field v1.Capabilities.Add fn := func( fldPath *field.Path, obj, oldObj []string, @@ -1756,13 +1756,13 @@ func Validate_Capabilities( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Capabilities) []string { + func(oldObj *v1.Capabilities) []string { return oldObj.Add }) errs = append(errs, fn(fldPath.Child("add"), obj.Add, oldVal, oldObj != nil)...) } - { // field ateapipb.Capabilities.Drop + { // field v1.Capabilities.Drop fn := func( fldPath *field.Path, obj, oldObj []string, @@ -1796,7 +1796,7 @@ func Validate_Capabilities( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Capabilities) []string { + func(oldObj *v1.Capabilities) []string { return oldObj.Drop }) errs = append(errs, fn(fldPath.Child("drop"), obj.Drop, oldVal, oldObj != nil)...) @@ -1809,9 +1809,9 @@ func Validate_Capabilities( // to declarative validation rules in the API schema. func Validate_Container( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.Container) (errs field.ErrorList) { + obj, oldObj *v1.Container) (errs field.ErrorList) { - { // field ateapipb.Container.Name + { // field v1.Container.Name fn := func( fldPath *field.Path, obj, oldObj *string, @@ -1837,13 +1837,13 @@ func Validate_Container( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Container) *string { + func(oldObj *v1.Container) *string { return &oldObj.Name }) errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) } - { // field ateapipb.Container.Image + { // field v1.Container.Image fn := func( fldPath *field.Path, obj, oldObj *string, @@ -1873,13 +1873,13 @@ func Validate_Container( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Container) *string { + func(oldObj *v1.Container) *string { return &oldObj.Image }) errs = append(errs, fn(fldPath.Child("image"), &obj.Image, oldVal, oldObj != nil)...) } - { // field ateapipb.Container.Command + { // field v1.Container.Command fn := func( fldPath *field.Path, obj, oldObj []string, @@ -1911,13 +1911,13 @@ func Validate_Container( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Container) []string { + func(oldObj *v1.Container) []string { return oldObj.Command }) errs = append(errs, fn(fldPath.Child("command"), obj.Command, oldVal, oldObj != nil)...) } - { // field ateapipb.Container.Args + { // field v1.Container.Args fn := func( fldPath *field.Path, obj, oldObj []string, @@ -1949,16 +1949,16 @@ func Validate_Container( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Container) []string { + func(oldObj *v1.Container) []string { return oldObj.Args }) errs = append(errs, fn(fldPath.Child("args"), obj.Args, oldVal, oldObj != nil)...) } - { // field ateapipb.Container.Env + { // field v1.Container.Env fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.EnvVar, + obj, oldObj []*v1.EnvVar, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -1968,7 +1968,7 @@ func Validate_Container( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.EnvVar](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.EnvVar](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -1984,27 +1984,27 @@ func Validate_Container( } // lists with map semantics require unique keys if e := validate.PtrSliceUnique(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.EnvVar, b *ateapipb.EnvVar) bool { return a.Name == b.Name }); len(e) != 0 { + func(a *v1.EnvVar, b *v1.EnvVar) bool { return a.Name == b.Name }); len(e) != 0 { errs = append(errs, e...) } // iterate the list and call the type's validation function if e := validate.EachPtrSliceVal(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.EnvVar, b *ateapipb.EnvVar) bool { return a.Name == b.Name }, ateDeepEqual, Validate_EnvVar); len(e) != 0 { + func(a *v1.EnvVar, b *v1.EnvVar) bool { return a.Name == b.Name }, ateDeepEqual, Validate_EnvVar); len(e) != 0 { errs = append(errs, e...) } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Container) []*ateapipb.EnvVar { + func(oldObj *v1.Container) []*v1.EnvVar { return oldObj.Env }) errs = append(errs, fn(fldPath.Child("env"), obj.Env, oldVal, oldObj != nil)...) } - { // field ateapipb.Container.WakeupProbe + { // field v1.Container.WakeupProbe fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.WakeupProbe, + obj, oldObj *v1.WakeupProbe, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2025,16 +2025,16 @@ func Validate_Container( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Container) *ateapipb.WakeupProbe { + func(oldObj *v1.Container) *v1.WakeupProbe { return oldObj.WakeupProbe }) errs = append(errs, fn(fldPath.Child("wakeup_probe"), obj.WakeupProbe, oldVal, oldObj != nil)...) } - { // field ateapipb.Container.VolumeMounts + { // field v1.Container.VolumeMounts fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.VolumeMount, + obj, oldObj []*v1.VolumeMount, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2044,7 +2044,7 @@ func Validate_Container( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.VolumeMount](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.VolumeMount](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -2064,27 +2064,27 @@ func Validate_Container( } // lists with map semantics require unique keys if e := validate.PtrSliceUnique(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.VolumeMount, b *ateapipb.VolumeMount) bool { return a.MountPath == b.MountPath }); len(e) != 0 { + func(a *v1.VolumeMount, b *v1.VolumeMount) bool { return a.MountPath == b.MountPath }); len(e) != 0 { errs = append(errs, e...) } // iterate the list and call the type's validation function if e := validate.EachPtrSliceVal(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.VolumeMount, b *ateapipb.VolumeMount) bool { return a.MountPath == b.MountPath }, ateDeepEqual, Validate_VolumeMount); len(e) != 0 { + func(a *v1.VolumeMount, b *v1.VolumeMount) bool { return a.MountPath == b.MountPath }, ateDeepEqual, Validate_VolumeMount); len(e) != 0 { errs = append(errs, e...) } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Container) []*ateapipb.VolumeMount { + func(oldObj *v1.Container) []*v1.VolumeMount { return oldObj.VolumeMounts }) errs = append(errs, fn(fldPath.Child("volume_mounts"), obj.VolumeMounts, oldVal, oldObj != nil)...) } - { // field ateapipb.Container.SecurityContext + { // field v1.Container.SecurityContext fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.SecurityContext, + obj, oldObj *v1.SecurityContext, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2105,16 +2105,16 @@ func Validate_Container( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Container) *ateapipb.SecurityContext { + func(oldObj *v1.Container) *v1.SecurityContext { return oldObj.SecurityContext }) errs = append(errs, fn(fldPath.Child("security_context"), obj.SecurityContext, oldVal, oldObj != nil)...) } - { // field ateapipb.Container.Resources + { // field v1.Container.Resources fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ResourceRequirements, + obj, oldObj *v1.ResourceRequirements, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2135,7 +2135,7 @@ func Validate_Container( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Container) *ateapipb.ResourceRequirements { + func(oldObj *v1.Container) *v1.ResourceRequirements { return oldObj.Resources }) errs = append(errs, fn(fldPath.Child("resources"), obj.Resources, oldVal, oldObj != nil)...) @@ -2148,17 +2148,17 @@ func Validate_Container( // to declarative validation rules in the API schema. func Validate_CreateActorEgressPolicyRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.CreateActorEgressPolicyRequest) (errs field.ErrorList) { + obj, oldObj *v1.CreateActorEgressPolicyRequest) (errs field.ErrorList) { // custom validation if e := ValidateCustom_CreateActorEgressPolicyRequest(ctx, op, fldPath, obj, oldObj); len(e) != 0 { errs = append(errs, e...) } - { // field ateapipb.CreateActorEgressPolicyRequest.Actor + { // field v1.CreateActorEgressPolicyRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2178,12 +2178,12 @@ func Validate_CreateActorEgressPolicyRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -2195,16 +2195,16 @@ func Validate_CreateActorEgressPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.CreateActorEgressPolicyRequest) *ateapipb.ObjectRef { + func(oldObj *v1.CreateActorEgressPolicyRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) } - { // field ateapipb.CreateActorEgressPolicyRequest.EgressPolicy + { // field v1.CreateActorEgressPolicyRequest.EgressPolicy fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.EgressPolicy, + obj, oldObj *v1.EgressPolicy, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2226,7 +2226,7 @@ func Validate_CreateActorEgressPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.CreateActorEgressPolicyRequest) *ateapipb.EgressPolicy { + func(oldObj *v1.CreateActorEgressPolicyRequest) *v1.EgressPolicy { return oldObj.EgressPolicy }) errs = append(errs, fn(fldPath.Child("egress_policy"), obj.EgressPolicy, oldVal, oldObj != nil)...) @@ -2239,12 +2239,12 @@ func Validate_CreateActorEgressPolicyRequest( // to declarative validation rules in the API schema. func Validate_CreateActorRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.CreateActorRequest) (errs field.ErrorList) { + obj, oldObj *v1.CreateActorRequest) (errs field.ErrorList) { - { // field ateapipb.CreateActorRequest.Actor + { // field v1.CreateActorRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Actor, + obj, oldObj *v1.Actor, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2266,7 +2266,7 @@ func Validate_CreateActorRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.CreateActorRequest) *ateapipb.Actor { + func(oldObj *v1.CreateActorRequest) *v1.Actor { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) @@ -2279,12 +2279,12 @@ func Validate_CreateActorRequest( // to declarative validation rules in the API schema. func Validate_CreateActorTemplateRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.CreateActorTemplateRequest) (errs field.ErrorList) { + obj, oldObj *v1.CreateActorTemplateRequest) (errs field.ErrorList) { - { // field ateapipb.CreateActorTemplateRequest.ActorTemplate + { // field v1.CreateActorTemplateRequest.ActorTemplate fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ActorTemplate, + obj, oldObj *v1.ActorTemplate, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2310,7 +2310,7 @@ func Validate_CreateActorTemplateRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.CreateActorTemplateRequest) *ateapipb.ActorTemplate { + func(oldObj *v1.CreateActorTemplateRequest) *v1.ActorTemplate { return oldObj.ActorTemplate }) errs = append(errs, fn(fldPath.Child("actor_template"), obj.ActorTemplate, oldVal, oldObj != nil)...) @@ -2323,12 +2323,12 @@ func Validate_CreateActorTemplateRequest( // to declarative validation rules in the API schema. func Validate_CreateAtespaceAccessPolicyRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.CreateAtespaceAccessPolicyRequest) (errs field.ErrorList) { + obj, oldObj *v1.CreateAtespaceAccessPolicyRequest) (errs field.ErrorList) { - { // field ateapipb.CreateAtespaceAccessPolicyRequest.Atespace + { // field v1.CreateAtespaceAccessPolicyRequest.Atespace fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2348,16 +2348,16 @@ func Validate_CreateAtespaceAccessPolicyRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -2369,16 +2369,16 @@ func Validate_CreateAtespaceAccessPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.CreateAtespaceAccessPolicyRequest) *ateapipb.ObjectRef { + func(oldObj *v1.CreateAtespaceAccessPolicyRequest) *v1.ObjectRef { return oldObj.Atespace }) errs = append(errs, fn(fldPath.Child("atespace"), obj.Atespace, oldVal, oldObj != nil)...) } - { // field ateapipb.CreateAtespaceAccessPolicyRequest.AccessPolicy + { // field v1.CreateAtespaceAccessPolicyRequest.AccessPolicy fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.AccessPolicy, + obj, oldObj *v1.AccessPolicy, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2400,7 +2400,7 @@ func Validate_CreateAtespaceAccessPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.CreateAtespaceAccessPolicyRequest) *ateapipb.AccessPolicy { + func(oldObj *v1.CreateAtespaceAccessPolicyRequest) *v1.AccessPolicy { return oldObj.AccessPolicy }) errs = append(errs, fn(fldPath.Child("access_policy"), obj.AccessPolicy, oldVal, oldObj != nil)...) @@ -2413,12 +2413,12 @@ func Validate_CreateAtespaceAccessPolicyRequest( // to declarative validation rules in the API schema. func Validate_CreateAtespaceRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.CreateAtespaceRequest) (errs field.ErrorList) { + obj, oldObj *v1.CreateAtespaceRequest) (errs field.ErrorList) { - { // field ateapipb.CreateAtespaceRequest.Atespace + { // field v1.CreateAtespaceRequest.Atespace fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Atespace, + obj, oldObj *v1.Atespace, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2440,7 +2440,7 @@ func Validate_CreateAtespaceRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.CreateAtespaceRequest) *ateapipb.Atespace { + func(oldObj *v1.CreateAtespaceRequest) *v1.Atespace { return oldObj.Atespace }) errs = append(errs, fn(fldPath.Child("atespace"), obj.Atespace, oldVal, oldObj != nil)...) @@ -2453,12 +2453,12 @@ func Validate_CreateAtespaceRequest( // to declarative validation rules in the API schema. func Validate_CreateGlobalAccessPolicyRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.CreateGlobalAccessPolicyRequest) (errs field.ErrorList) { + obj, oldObj *v1.CreateGlobalAccessPolicyRequest) (errs field.ErrorList) { - { // field ateapipb.CreateGlobalAccessPolicyRequest.AccessPolicy + { // field v1.CreateGlobalAccessPolicyRequest.AccessPolicy fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.AccessPolicy, + obj, oldObj *v1.AccessPolicy, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2480,7 +2480,7 @@ func Validate_CreateGlobalAccessPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.CreateGlobalAccessPolicyRequest) *ateapipb.AccessPolicy { + func(oldObj *v1.CreateGlobalAccessPolicyRequest) *v1.AccessPolicy { return oldObj.AccessPolicy }) errs = append(errs, fn(fldPath.Child("access_policy"), obj.AccessPolicy, oldVal, oldObj != nil)...) @@ -2493,17 +2493,17 @@ func Validate_CreateGlobalAccessPolicyRequest( // to declarative validation rules in the API schema. func Validate_CreateTagRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.CreateTagRequest) (errs field.ErrorList) { + obj, oldObj *v1.CreateTagRequest) (errs field.ErrorList) { // custom validation if e := ValidateCustom_CreateTagRequest(ctx, op, fldPath, obj, oldObj); len(e) != 0 { errs = append(errs, e...) } - { // field ateapipb.CreateTagRequest.Tag + { // field v1.CreateTagRequest.Tag fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Tag, + obj, oldObj *v1.Tag, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2525,7 +2525,7 @@ func Validate_CreateTagRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.CreateTagRequest) *ateapipb.Tag { + func(oldObj *v1.CreateTagRequest) *v1.Tag { return oldObj.Tag }) errs = append(errs, fn(fldPath.Child("tag"), obj.Tag, oldVal, oldObj != nil)...) @@ -2538,12 +2538,12 @@ func Validate_CreateTagRequest( // to declarative validation rules in the API schema. func Validate_CreateWorkerRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.CreateWorkerRequest) (errs field.ErrorList) { + obj, oldObj *v1.CreateWorkerRequest) (errs field.ErrorList) { - { // field ateapipb.CreateWorkerRequest.Worker + { // field v1.CreateWorkerRequest.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Worker, + obj, oldObj *v1.Worker, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2565,7 +2565,7 @@ func Validate_CreateWorkerRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.CreateWorkerRequest) *ateapipb.Worker { + func(oldObj *v1.CreateWorkerRequest) *v1.Worker { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) @@ -2574,23 +2574,23 @@ func Validate_CreateWorkerRequest( return errs } -var unionMembershipFor_go_ate_dev_substrate_pkg_proto_ateapipb_CredentialHeader_ = validate.NewUnionMembership(validate.NewUnionMember("credential_uri"), validate.NewUnionMember("actor_jwt")) +var unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_CredentialHeader_ = validate.NewUnionMembership(validate.NewUnionMember("credential_uri"), validate.NewUnionMember("actor_jwt")) // Validate_CredentialHeader validates an instance of CredentialHeader according // to declarative validation rules in the API schema. func Validate_CredentialHeader( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.CredentialHeader) (errs field.ErrorList) { + obj, oldObj *v1.CredentialHeader) (errs field.ErrorList) { - if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_pkg_proto_ateapipb_CredentialHeader_, - func(obj *ateapipb.CredentialHeader) bool { + if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_CredentialHeader_, + func(obj *v1.CredentialHeader) bool { if obj == nil { return false } var z string return obj.CredentialUri != z }, - func(obj *ateapipb.CredentialHeader) bool { + func(obj *v1.CredentialHeader) bool { if obj == nil { return false } @@ -2599,7 +2599,7 @@ func Validate_CredentialHeader( errs = append(errs, e...) } - { // field ateapipb.CredentialHeader.Header + { // field v1.CredentialHeader.Header fn := func( fldPath *field.Path, obj, oldObj *string, @@ -2626,13 +2626,13 @@ func Validate_CredentialHeader( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.CredentialHeader) *string { + func(oldObj *v1.CredentialHeader) *string { return &oldObj.Header }) errs = append(errs, fn(fldPath.Child("header"), &obj.Header, oldVal, oldObj != nil)...) } - { // field ateapipb.CredentialHeader.Prefix + { // field v1.CredentialHeader.Prefix fn := func( fldPath *field.Path, obj, oldObj *string, @@ -2658,13 +2658,13 @@ func Validate_CredentialHeader( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.CredentialHeader) *string { + func(oldObj *v1.CredentialHeader) *string { return &oldObj.Prefix }) errs = append(errs, fn(fldPath.Child("prefix"), &obj.Prefix, oldVal, oldObj != nil)...) } - { // field ateapipb.CredentialHeader.CredentialUri + { // field v1.CredentialHeader.CredentialUri fn := func( fldPath *field.Path, obj, oldObj *string, @@ -2690,16 +2690,16 @@ func Validate_CredentialHeader( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.CredentialHeader) *string { + func(oldObj *v1.CredentialHeader) *string { return &oldObj.CredentialUri }) errs = append(errs, fn(fldPath.Child("credential_uri"), &obj.CredentialUri, oldVal, oldObj != nil)...) } - { // field ateapipb.CredentialHeader.ActorJwt + { // field v1.CredentialHeader.ActorJwt fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ActorJwtSource, + obj, oldObj *v1.ActorJwtSource, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2720,7 +2720,7 @@ func Validate_CredentialHeader( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.CredentialHeader) *ateapipb.ActorJwtSource { + func(oldObj *v1.CredentialHeader) *v1.ActorJwtSource { return oldObj.ActorJwt }) errs = append(errs, fn(fldPath.Child("actor_jwt"), obj.ActorJwt, oldVal, oldObj != nil)...) @@ -2733,12 +2733,12 @@ func Validate_CredentialHeader( // to declarative validation rules in the API schema. func Validate_DeleteActorEgressPolicyRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.DeleteActorEgressPolicyRequest) (errs field.ErrorList) { + obj, oldObj *v1.DeleteActorEgressPolicyRequest) (errs field.ErrorList) { - { // field ateapipb.DeleteActorEgressPolicyRequest.Actor + { // field v1.DeleteActorEgressPolicyRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2758,12 +2758,12 @@ func Validate_DeleteActorEgressPolicyRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -2775,13 +2775,13 @@ func Validate_DeleteActorEgressPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteActorEgressPolicyRequest) *ateapipb.ObjectRef { + func(oldObj *v1.DeleteActorEgressPolicyRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) } - { // field ateapipb.DeleteActorEgressPolicyRequest.Name + { // field v1.DeleteActorEgressPolicyRequest.Name fn := func( fldPath *field.Path, obj, oldObj *string, @@ -2811,16 +2811,16 @@ func Validate_DeleteActorEgressPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteActorEgressPolicyRequest) *string { + func(oldObj *v1.DeleteActorEgressPolicyRequest) *string { return &oldObj.Name }) errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) } - { // field ateapipb.DeleteActorEgressPolicyRequest.Options + { // field v1.DeleteActorEgressPolicyRequest.Options fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.DeleteOptions, + obj, oldObj *v1.DeleteOptions, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2841,7 +2841,7 @@ func Validate_DeleteActorEgressPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteActorEgressPolicyRequest) *ateapipb.DeleteOptions { + func(oldObj *v1.DeleteActorEgressPolicyRequest) *v1.DeleteOptions { return oldObj.Options }) errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) @@ -2854,12 +2854,12 @@ func Validate_DeleteActorEgressPolicyRequest( // to declarative validation rules in the API schema. func Validate_DeleteActorRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.DeleteActorRequest) (errs field.ErrorList) { + obj, oldObj *v1.DeleteActorRequest) (errs field.ErrorList) { - { // field ateapipb.DeleteActorRequest.Actor + { // field v1.DeleteActorRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2879,12 +2879,12 @@ func Validate_DeleteActorRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -2896,16 +2896,16 @@ func Validate_DeleteActorRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteActorRequest) *ateapipb.ObjectRef { + func(oldObj *v1.DeleteActorRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) } - { // field ateapipb.DeleteActorRequest.Options + { // field v1.DeleteActorRequest.Options fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.DeleteOptions, + obj, oldObj *v1.DeleteOptions, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2926,7 +2926,7 @@ func Validate_DeleteActorRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteActorRequest) *ateapipb.DeleteOptions { + func(oldObj *v1.DeleteActorRequest) *v1.DeleteOptions { return oldObj.Options }) errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) @@ -2939,12 +2939,12 @@ func Validate_DeleteActorRequest( // to declarative validation rules in the API schema. func Validate_DeleteActorTemplateRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.DeleteActorTemplateRequest) (errs field.ErrorList) { + obj, oldObj *v1.DeleteActorTemplateRequest) (errs field.ErrorList) { - { // field ateapipb.DeleteActorTemplateRequest.ActorTemplate + { // field v1.DeleteActorTemplateRequest.ActorTemplate fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -2964,12 +2964,12 @@ func Validate_DeleteActorTemplateRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -2981,16 +2981,16 @@ func Validate_DeleteActorTemplateRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteActorTemplateRequest) *ateapipb.ObjectRef { + func(oldObj *v1.DeleteActorTemplateRequest) *v1.ObjectRef { return oldObj.ActorTemplate }) errs = append(errs, fn(fldPath.Child("actor_template"), obj.ActorTemplate, oldVal, oldObj != nil)...) } - { // field ateapipb.DeleteActorTemplateRequest.Options + { // field v1.DeleteActorTemplateRequest.Options fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.DeleteOptions, + obj, oldObj *v1.DeleteOptions, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3011,7 +3011,7 @@ func Validate_DeleteActorTemplateRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteActorTemplateRequest) *ateapipb.DeleteOptions { + func(oldObj *v1.DeleteActorTemplateRequest) *v1.DeleteOptions { return oldObj.Options }) errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) @@ -3024,12 +3024,12 @@ func Validate_DeleteActorTemplateRequest( // to declarative validation rules in the API schema. func Validate_DeleteAtespaceAccessPolicyRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.DeleteAtespaceAccessPolicyRequest) (errs field.ErrorList) { + obj, oldObj *v1.DeleteAtespaceAccessPolicyRequest) (errs field.ErrorList) { - { // field ateapipb.DeleteAtespaceAccessPolicyRequest.Atespace + { // field v1.DeleteAtespaceAccessPolicyRequest.Atespace fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3049,16 +3049,16 @@ func Validate_DeleteAtespaceAccessPolicyRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -3070,13 +3070,13 @@ func Validate_DeleteAtespaceAccessPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteAtespaceAccessPolicyRequest) *ateapipb.ObjectRef { + func(oldObj *v1.DeleteAtespaceAccessPolicyRequest) *v1.ObjectRef { return oldObj.Atespace }) errs = append(errs, fn(fldPath.Child("atespace"), obj.Atespace, oldVal, oldObj != nil)...) } - { // field ateapipb.DeleteAtespaceAccessPolicyRequest.Name + { // field v1.DeleteAtespaceAccessPolicyRequest.Name fn := func( fldPath *field.Path, obj, oldObj *string, @@ -3106,16 +3106,16 @@ func Validate_DeleteAtespaceAccessPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteAtespaceAccessPolicyRequest) *string { + func(oldObj *v1.DeleteAtespaceAccessPolicyRequest) *string { return &oldObj.Name }) errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) } - { // field ateapipb.DeleteAtespaceAccessPolicyRequest.Options + { // field v1.DeleteAtespaceAccessPolicyRequest.Options fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.DeleteOptions, + obj, oldObj *v1.DeleteOptions, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3136,7 +3136,7 @@ func Validate_DeleteAtespaceAccessPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteAtespaceAccessPolicyRequest) *ateapipb.DeleteOptions { + func(oldObj *v1.DeleteAtespaceAccessPolicyRequest) *v1.DeleteOptions { return oldObj.Options }) errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) @@ -3149,12 +3149,12 @@ func Validate_DeleteAtespaceAccessPolicyRequest( // to declarative validation rules in the API schema. func Validate_DeleteAtespaceRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.DeleteAtespaceRequest) (errs field.ErrorList) { + obj, oldObj *v1.DeleteAtespaceRequest) (errs field.ErrorList) { - { // field ateapipb.DeleteAtespaceRequest.Atespace + { // field v1.DeleteAtespaceRequest.Atespace fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3174,16 +3174,16 @@ func Validate_DeleteAtespaceRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -3195,16 +3195,16 @@ func Validate_DeleteAtespaceRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteAtespaceRequest) *ateapipb.ObjectRef { + func(oldObj *v1.DeleteAtespaceRequest) *v1.ObjectRef { return oldObj.Atespace }) errs = append(errs, fn(fldPath.Child("atespace"), obj.Atespace, oldVal, oldObj != nil)...) } - { // field ateapipb.DeleteAtespaceRequest.Options + { // field v1.DeleteAtespaceRequest.Options fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.DeleteOptions, + obj, oldObj *v1.DeleteOptions, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3225,7 +3225,7 @@ func Validate_DeleteAtespaceRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteAtespaceRequest) *ateapipb.DeleteOptions { + func(oldObj *v1.DeleteAtespaceRequest) *v1.DeleteOptions { return oldObj.Options }) errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) @@ -3238,9 +3238,9 @@ func Validate_DeleteAtespaceRequest( // to declarative validation rules in the API schema. func Validate_DeleteOptions( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.DeleteOptions) (errs field.ErrorList) { + obj, oldObj *v1.DeleteOptions) (errs field.ErrorList) { - { // field ateapipb.DeleteOptions.Version + { // field v1.DeleteOptions.Version fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -3265,13 +3265,13 @@ func Validate_DeleteOptions( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteOptions) *int64 { + func(oldObj *v1.DeleteOptions) *int64 { return &oldObj.Version }) errs = append(errs, fn(fldPath.Child("version"), &obj.Version, oldVal, oldObj != nil)...) } - { // field ateapipb.DeleteOptions.Uid + { // field v1.DeleteOptions.Uid fn := func( fldPath *field.Path, obj, oldObj *string, @@ -3296,7 +3296,7 @@ func Validate_DeleteOptions( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteOptions) *string { + func(oldObj *v1.DeleteOptions) *string { return &oldObj.Uid }) errs = append(errs, fn(fldPath.Child("uid"), &obj.Uid, oldVal, oldObj != nil)...) @@ -3309,12 +3309,12 @@ func Validate_DeleteOptions( // to declarative validation rules in the API schema. func Validate_DeleteTagRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.DeleteTagRequest) (errs field.ErrorList) { + obj, oldObj *v1.DeleteTagRequest) (errs field.ErrorList) { - { // field ateapipb.DeleteTagRequest.Tag + { // field v1.DeleteTagRequest.Tag fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3334,12 +3334,12 @@ func Validate_DeleteTagRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -3351,16 +3351,16 @@ func Validate_DeleteTagRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteTagRequest) *ateapipb.ObjectRef { + func(oldObj *v1.DeleteTagRequest) *v1.ObjectRef { return oldObj.Tag }) errs = append(errs, fn(fldPath.Child("tag"), obj.Tag, oldVal, oldObj != nil)...) } - { // field ateapipb.DeleteTagRequest.Options + { // field v1.DeleteTagRequest.Options fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.DeleteOptions, + obj, oldObj *v1.DeleteOptions, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3381,7 +3381,7 @@ func Validate_DeleteTagRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteTagRequest) *ateapipb.DeleteOptions { + func(oldObj *v1.DeleteTagRequest) *v1.DeleteOptions { return oldObj.Options }) errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) @@ -3394,12 +3394,12 @@ func Validate_DeleteTagRequest( // to declarative validation rules in the API schema. func Validate_DeleteWorkerRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.DeleteWorkerRequest) (errs field.ErrorList) { + obj, oldObj *v1.DeleteWorkerRequest) (errs field.ErrorList) { - { // field ateapipb.DeleteWorkerRequest.Worker + { // field v1.DeleteWorkerRequest.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3419,16 +3419,16 @@ func Validate_DeleteWorkerRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -3440,16 +3440,16 @@ func Validate_DeleteWorkerRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteWorkerRequest) *ateapipb.ObjectRef { + func(oldObj *v1.DeleteWorkerRequest) *v1.ObjectRef { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) } - { // field ateapipb.DeleteWorkerRequest.Options + { // field v1.DeleteWorkerRequest.Options fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.DeleteOptions, + obj, oldObj *v1.DeleteOptions, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3470,7 +3470,7 @@ func Validate_DeleteWorkerRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DeleteWorkerRequest) *ateapipb.DeleteOptions { + func(oldObj *v1.DeleteWorkerRequest) *v1.DeleteOptions { return oldObj.Options }) errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) @@ -3483,12 +3483,12 @@ func Validate_DeleteWorkerRequest( // to declarative validation rules in the API schema. func Validate_DrainWorkerRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.DrainWorkerRequest) (errs field.ErrorList) { + obj, oldObj *v1.DrainWorkerRequest) (errs field.ErrorList) { - { // field ateapipb.DrainWorkerRequest.Worker + { // field v1.DrainWorkerRequest.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3508,16 +3508,16 @@ func Validate_DrainWorkerRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -3529,7 +3529,7 @@ func Validate_DrainWorkerRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.DrainWorkerRequest) *ateapipb.ObjectRef { + func(oldObj *v1.DrainWorkerRequest) *v1.ObjectRef { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) @@ -3542,12 +3542,12 @@ func Validate_DrainWorkerRequest( // to declarative validation rules in the API schema. func Validate_EgressPolicy( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.EgressPolicy) (errs field.ErrorList) { + obj, oldObj *v1.EgressPolicy) (errs field.ErrorList) { - { // field ateapipb.EgressPolicy.Metadata + { // field v1.EgressPolicy.Metadata fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ResourceMetadata, + obj, oldObj *v1.ResourceMetadata, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3571,16 +3571,16 @@ func Validate_EgressPolicy( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.Immutable).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.Immutable).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -3592,16 +3592,16 @@ func Validate_EgressPolicy( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.EgressPolicy) *ateapipb.ResourceMetadata { + func(oldObj *v1.EgressPolicy) *v1.ResourceMetadata { return oldObj.Metadata }) errs = append(errs, fn(fldPath.Child("metadata"), obj.Metadata, oldVal, oldObj != nil)...) } - { // field ateapipb.EgressPolicy.Rules + { // field v1.EgressPolicy.Rules fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.EgressRule, + obj, oldObj []*v1.EgressRule, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3611,7 +3611,7 @@ func Validate_EgressPolicy( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.EgressRule](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.EgressRule](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -3636,7 +3636,7 @@ func Validate_EgressPolicy( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.EgressPolicy) []*ateapipb.EgressRule { + func(oldObj *v1.EgressPolicy) []*v1.EgressRule { return oldObj.Rules }) errs = append(errs, fn(fldPath.Child("rules"), obj.Rules, oldVal, oldObj != nil)...) @@ -3649,12 +3649,12 @@ func Validate_EgressPolicy( // to declarative validation rules in the API schema. func Validate_EgressPolicyTemplate( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.EgressPolicyTemplate) (errs field.ErrorList) { + obj, oldObj *v1.EgressPolicyTemplate) (errs field.ErrorList) { - { // field ateapipb.EgressPolicyTemplate.Rules + { // field v1.EgressPolicyTemplate.Rules fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.EgressRule, + obj, oldObj []*v1.EgressRule, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3664,7 +3664,7 @@ func Validate_EgressPolicyTemplate( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.EgressRule](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.EgressRule](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -3690,7 +3690,7 @@ func Validate_EgressPolicyTemplate( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.EgressPolicyTemplate) []*ateapipb.EgressRule { + func(oldObj *v1.EgressPolicyTemplate) []*v1.EgressRule { return oldObj.Rules }) errs = append(errs, fn(fldPath.Child("rules"), obj.Rules, oldVal, oldObj != nil)...) @@ -3699,28 +3699,28 @@ func Validate_EgressPolicyTemplate( return errs } -var unionMembershipFor_go_ate_dev_substrate_pkg_proto_ateapipb_EgressRule_ = validate.NewUnionMembership(validate.NewUnionMember("http"), validate.NewUnionMember("https"), validate.NewUnionMember("tls_passthrough")) +var unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_EgressRule_ = validate.NewUnionMembership(validate.NewUnionMember("http"), validate.NewUnionMember("https"), validate.NewUnionMember("tls_passthrough")) // Validate_EgressRule validates an instance of EgressRule according // to declarative validation rules in the API schema. func Validate_EgressRule( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.EgressRule) (errs field.ErrorList) { + obj, oldObj *v1.EgressRule) (errs field.ErrorList) { - if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_pkg_proto_ateapipb_EgressRule_, - func(obj *ateapipb.EgressRule) bool { + if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_EgressRule_, + func(obj *v1.EgressRule) bool { if obj == nil { return false } return obj.Http != nil }, - func(obj *ateapipb.EgressRule) bool { + func(obj *v1.EgressRule) bool { if obj == nil { return false } return obj.Https != nil }, - func(obj *ateapipb.EgressRule) bool { + func(obj *v1.EgressRule) bool { if obj == nil { return false } @@ -3729,10 +3729,10 @@ func Validate_EgressRule( errs = append(errs, e...) } - { // field ateapipb.EgressRule.Http + { // field v1.EgressRule.Http fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.HttpRule, + obj, oldObj *v1.HttpRule, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3753,16 +3753,16 @@ func Validate_EgressRule( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.EgressRule) *ateapipb.HttpRule { + func(oldObj *v1.EgressRule) *v1.HttpRule { return oldObj.Http }) errs = append(errs, fn(fldPath.Child("http"), obj.Http, oldVal, oldObj != nil)...) } - { // field ateapipb.EgressRule.Https + { // field v1.EgressRule.Https fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.HttpsRule, + obj, oldObj *v1.HttpsRule, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3783,16 +3783,16 @@ func Validate_EgressRule( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.EgressRule) *ateapipb.HttpsRule { + func(oldObj *v1.EgressRule) *v1.HttpsRule { return oldObj.Https }) errs = append(errs, fn(fldPath.Child("https"), obj.Https, oldVal, oldObj != nil)...) } - { // field ateapipb.EgressRule.TlsPassthrough + { // field v1.EgressRule.TlsPassthrough fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.TlsPassthroughRule, + obj, oldObj *v1.TlsPassthroughRule, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3813,7 +3813,7 @@ func Validate_EgressRule( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.EgressRule) *ateapipb.TlsPassthroughRule { + func(oldObj *v1.EgressRule) *v1.TlsPassthroughRule { return oldObj.TlsPassthrough }) errs = append(errs, fn(fldPath.Child("tls_passthrough"), obj.TlsPassthrough, oldVal, oldObj != nil)...) @@ -3826,9 +3826,9 @@ func Validate_EgressRule( // to declarative validation rules in the API schema. func Validate_EnvVar( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.EnvVar) (errs field.ErrorList) { + obj, oldObj *v1.EnvVar) (errs field.ErrorList) { - { // field ateapipb.EnvVar.Name + { // field v1.EnvVar.Name fn := func( fldPath *field.Path, obj, oldObj *string, @@ -3858,13 +3858,13 @@ func Validate_EnvVar( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.EnvVar) *string { + func(oldObj *v1.EnvVar) *string { return &oldObj.Name }) errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) } - { // field ateapipb.EnvVar.Value + { // field v1.EnvVar.Value fn := func( fldPath *field.Path, obj, oldObj *string, @@ -3889,7 +3889,7 @@ func Validate_EnvVar( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.EnvVar) *string { + func(oldObj *v1.EnvVar) *string { return &oldObj.Value }) errs = append(errs, fn(fldPath.Child("value"), &obj.Value, oldVal, oldObj != nil)...) @@ -3898,16 +3898,16 @@ func Validate_EnvVar( return errs } -var unionMembershipFor_go_ate_dev_substrate_pkg_proto_ateapipb_ExternalVolumeSource_ = validate.NewUnionMembership(validate.NewUnionMember("template")) +var unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_ExternalVolumeSource_ = validate.NewUnionMembership(validate.NewUnionMember("template")) // Validate_ExternalVolumeSource validates an instance of ExternalVolumeSource according // to declarative validation rules in the API schema. func Validate_ExternalVolumeSource( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ExternalVolumeSource) (errs field.ErrorList) { + obj, oldObj *v1.ExternalVolumeSource) (errs field.ErrorList) { - if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_pkg_proto_ateapipb_ExternalVolumeSource_, - func(obj *ateapipb.ExternalVolumeSource) bool { + if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_ExternalVolumeSource_, + func(obj *v1.ExternalVolumeSource) bool { if obj == nil { return false } @@ -3916,10 +3916,10 @@ func Validate_ExternalVolumeSource( errs = append(errs, e...) } - { // field ateapipb.ExternalVolumeSource.Template + { // field v1.ExternalVolumeSource.Template fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ExternalVolumeTemplate, + obj, oldObj *v1.ExternalVolumeTemplate, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3940,7 +3940,7 @@ func Validate_ExternalVolumeSource( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ExternalVolumeSource) *ateapipb.ExternalVolumeTemplate { + func(oldObj *v1.ExternalVolumeSource) *v1.ExternalVolumeTemplate { return oldObj.Template }) errs = append(errs, fn(fldPath.Child("template"), obj.Template, oldVal, oldObj != nil)...) @@ -3953,9 +3953,9 @@ func Validate_ExternalVolumeSource( // to declarative validation rules in the API schema. func Validate_ExternalVolumeStatus( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ExternalVolumeStatus) (errs field.ErrorList) { + obj, oldObj *v1.ExternalVolumeStatus) (errs field.ErrorList) { - { // field ateapipb.ExternalVolumeStatus.Name + { // field v1.ExternalVolumeStatus.Name fn := func( fldPath *field.Path, obj, oldObj *string, @@ -3986,13 +3986,13 @@ func Validate_ExternalVolumeStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ExternalVolumeStatus) *string { + func(oldObj *v1.ExternalVolumeStatus) *string { return &oldObj.Name }) errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) } - { // field ateapipb.ExternalVolumeStatus.StorageVolumeId + { // field v1.ExternalVolumeStatus.StorageVolumeId fn := func( fldPath *field.Path, obj, oldObj *string, @@ -4026,13 +4026,13 @@ func Validate_ExternalVolumeStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ExternalVolumeStatus) *string { + func(oldObj *v1.ExternalVolumeStatus) *string { return &oldObj.StorageVolumeId }) errs = append(errs, fn(fldPath.Child("storage_volume_id"), &obj.StorageVolumeId, oldVal, oldObj != nil)...) } - { // field ateapipb.ExternalVolumeStatus.VolumeType + { // field v1.ExternalVolumeStatus.VolumeType fn := func( fldPath *field.Path, obj, oldObj *string, @@ -4067,13 +4067,13 @@ func Validate_ExternalVolumeStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ExternalVolumeStatus) *string { + func(oldObj *v1.ExternalVolumeStatus) *string { return &oldObj.VolumeType }) errs = append(errs, fn(fldPath.Child("volume_type"), &obj.VolumeType, oldVal, oldObj != nil)...) } - { // field ateapipb.ExternalVolumeStatus.VolumeContext + { // field v1.ExternalVolumeStatus.VolumeContext fn := func( fldPath *field.Path, obj, oldObj map[string]string, @@ -4099,7 +4099,7 @@ func Validate_ExternalVolumeStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ExternalVolumeStatus) map[string]string { + func(oldObj *v1.ExternalVolumeStatus) map[string]string { return oldObj.VolumeContext }) errs = append(errs, fn(fldPath.Child("volume_context"), obj.VolumeContext, oldVal, oldObj != nil)...) @@ -4112,9 +4112,9 @@ func Validate_ExternalVolumeStatus( // to declarative validation rules in the API schema. func Validate_ExternalVolumeTemplate( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ExternalVolumeTemplate) (errs field.ErrorList) { + obj, oldObj *v1.ExternalVolumeTemplate) (errs field.ErrorList) { - { // field ateapipb.ExternalVolumeTemplate.CapacityBytes + { // field v1.ExternalVolumeTemplate.CapacityBytes fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -4140,13 +4140,13 @@ func Validate_ExternalVolumeTemplate( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ExternalVolumeTemplate) *int64 { + func(oldObj *v1.ExternalVolumeTemplate) *int64 { return &oldObj.CapacityBytes }) errs = append(errs, fn(fldPath.Child("capacity_bytes"), &obj.CapacityBytes, oldVal, oldObj != nil)...) } - { // field ateapipb.ExternalVolumeTemplate.StorageClassName + { // field v1.ExternalVolumeTemplate.StorageClassName fn := func( fldPath *field.Path, obj, oldObj *string, @@ -4172,7 +4172,7 @@ func Validate_ExternalVolumeTemplate( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ExternalVolumeTemplate) *string { + func(oldObj *v1.ExternalVolumeTemplate) *string { return &oldObj.StorageClassName }) errs = append(errs, fn(fldPath.Child("storage_class_name"), &obj.StorageClassName, oldVal, oldObj != nil)...) @@ -4185,12 +4185,12 @@ func Validate_ExternalVolumeTemplate( // to declarative validation rules in the API schema. func Validate_ExternalVolumes( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ExternalVolumes) (errs field.ErrorList) { + obj, oldObj *v1.ExternalVolumes) (errs field.ErrorList) { - { // field ateapipb.ExternalVolumes.Volumes + { // field v1.ExternalVolumes.Volumes fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.ExternalVolumeStatus, + obj, oldObj []*v1.ExternalVolumeStatus, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -4200,7 +4200,7 @@ func Validate_ExternalVolumes( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.ExternalVolumeStatus](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.ExternalVolumeStatus](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -4216,18 +4216,18 @@ func Validate_ExternalVolumes( } // lists with map semantics require unique keys if e := validate.PtrSliceUnique(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.ExternalVolumeStatus, b *ateapipb.ExternalVolumeStatus) bool { return a.Name == b.Name }); len(e) != 0 { + func(a *v1.ExternalVolumeStatus, b *v1.ExternalVolumeStatus) bool { return a.Name == b.Name }); len(e) != 0 { errs = append(errs, e...) } // iterate the list and call the type's validation function if e := validate.EachPtrSliceVal(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.ExternalVolumeStatus, b *ateapipb.ExternalVolumeStatus) bool { return a.Name == b.Name }, ateDeepEqual, Validate_ExternalVolumeStatus); len(e) != 0 { + func(a *v1.ExternalVolumeStatus, b *v1.ExternalVolumeStatus) bool { return a.Name == b.Name }, ateDeepEqual, Validate_ExternalVolumeStatus); len(e) != 0 { errs = append(errs, e...) } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ExternalVolumes) []*ateapipb.ExternalVolumeStatus { + func(oldObj *v1.ExternalVolumes) []*v1.ExternalVolumeStatus { return oldObj.Volumes }) errs = append(errs, fn(fldPath.Child("volumes"), obj.Volumes, oldVal, oldObj != nil)...) @@ -4240,12 +4240,12 @@ func Validate_ExternalVolumes( // to declarative validation rules in the API schema. func Validate_GetActorEgressPolicyRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.GetActorEgressPolicyRequest) (errs field.ErrorList) { + obj, oldObj *v1.GetActorEgressPolicyRequest) (errs field.ErrorList) { - { // field ateapipb.GetActorEgressPolicyRequest.Actor + { // field v1.GetActorEgressPolicyRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -4265,12 +4265,12 @@ func Validate_GetActorEgressPolicyRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -4282,13 +4282,13 @@ func Validate_GetActorEgressPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.GetActorEgressPolicyRequest) *ateapipb.ObjectRef { + func(oldObj *v1.GetActorEgressPolicyRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) } - { // field ateapipb.GetActorEgressPolicyRequest.Name + { // field v1.GetActorEgressPolicyRequest.Name fn := func( fldPath *field.Path, obj, oldObj *string, @@ -4318,7 +4318,7 @@ func Validate_GetActorEgressPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.GetActorEgressPolicyRequest) *string { + func(oldObj *v1.GetActorEgressPolicyRequest) *string { return &oldObj.Name }) errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) @@ -4331,12 +4331,12 @@ func Validate_GetActorEgressPolicyRequest( // to declarative validation rules in the API schema. func Validate_GetActorRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.GetActorRequest) (errs field.ErrorList) { + obj, oldObj *v1.GetActorRequest) (errs field.ErrorList) { - { // field ateapipb.GetActorRequest.Actor + { // field v1.GetActorRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -4356,12 +4356,12 @@ func Validate_GetActorRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -4373,7 +4373,7 @@ func Validate_GetActorRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.GetActorRequest) *ateapipb.ObjectRef { + func(oldObj *v1.GetActorRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) @@ -4386,12 +4386,12 @@ func Validate_GetActorRequest( // to declarative validation rules in the API schema. func Validate_GetActorTemplateRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.GetActorTemplateRequest) (errs field.ErrorList) { + obj, oldObj *v1.GetActorTemplateRequest) (errs field.ErrorList) { - { // field ateapipb.GetActorTemplateRequest.ActorTemplate + { // field v1.GetActorTemplateRequest.ActorTemplate fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -4411,12 +4411,12 @@ func Validate_GetActorTemplateRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -4428,7 +4428,7 @@ func Validate_GetActorTemplateRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.GetActorTemplateRequest) *ateapipb.ObjectRef { + func(oldObj *v1.GetActorTemplateRequest) *v1.ObjectRef { return oldObj.ActorTemplate }) errs = append(errs, fn(fldPath.Child("actor_template"), obj.ActorTemplate, oldVal, oldObj != nil)...) @@ -4441,12 +4441,12 @@ func Validate_GetActorTemplateRequest( // to declarative validation rules in the API schema. func Validate_GetAtespaceAccessPolicyRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.GetAtespaceAccessPolicyRequest) (errs field.ErrorList) { + obj, oldObj *v1.GetAtespaceAccessPolicyRequest) (errs field.ErrorList) { - { // field ateapipb.GetAtespaceAccessPolicyRequest.Atespace + { // field v1.GetAtespaceAccessPolicyRequest.Atespace fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -4466,16 +4466,16 @@ func Validate_GetAtespaceAccessPolicyRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -4487,13 +4487,13 @@ func Validate_GetAtespaceAccessPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.GetAtespaceAccessPolicyRequest) *ateapipb.ObjectRef { + func(oldObj *v1.GetAtespaceAccessPolicyRequest) *v1.ObjectRef { return oldObj.Atespace }) errs = append(errs, fn(fldPath.Child("atespace"), obj.Atespace, oldVal, oldObj != nil)...) } - { // field ateapipb.GetAtespaceAccessPolicyRequest.Name + { // field v1.GetAtespaceAccessPolicyRequest.Name fn := func( fldPath *field.Path, obj, oldObj *string, @@ -4523,7 +4523,7 @@ func Validate_GetAtespaceAccessPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.GetAtespaceAccessPolicyRequest) *string { + func(oldObj *v1.GetAtespaceAccessPolicyRequest) *string { return &oldObj.Name }) errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) @@ -4536,12 +4536,12 @@ func Validate_GetAtespaceAccessPolicyRequest( // to declarative validation rules in the API schema. func Validate_GetAtespaceRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.GetAtespaceRequest) (errs field.ErrorList) { + obj, oldObj *v1.GetAtespaceRequest) (errs field.ErrorList) { - { // field ateapipb.GetAtespaceRequest.Atespace + { // field v1.GetAtespaceRequest.Atespace fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -4561,16 +4561,16 @@ func Validate_GetAtespaceRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -4582,7 +4582,7 @@ func Validate_GetAtespaceRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.GetAtespaceRequest) *ateapipb.ObjectRef { + func(oldObj *v1.GetAtespaceRequest) *v1.ObjectRef { return oldObj.Atespace }) errs = append(errs, fn(fldPath.Child("atespace"), obj.Atespace, oldVal, oldObj != nil)...) @@ -4595,9 +4595,9 @@ func Validate_GetAtespaceRequest( // to declarative validation rules in the API schema. func Validate_GetGlobalAccessPolicyRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.GetGlobalAccessPolicyRequest) (errs field.ErrorList) { + obj, oldObj *v1.GetGlobalAccessPolicyRequest) (errs field.ErrorList) { - { // field ateapipb.GetGlobalAccessPolicyRequest.Name + { // field v1.GetGlobalAccessPolicyRequest.Name fn := func( fldPath *field.Path, obj, oldObj *string, @@ -4627,7 +4627,7 @@ func Validate_GetGlobalAccessPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.GetGlobalAccessPolicyRequest) *string { + func(oldObj *v1.GetGlobalAccessPolicyRequest) *string { return &oldObj.Name }) errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) @@ -4640,12 +4640,12 @@ func Validate_GetGlobalAccessPolicyRequest( // to declarative validation rules in the API schema. func Validate_GetTagRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.GetTagRequest) (errs field.ErrorList) { + obj, oldObj *v1.GetTagRequest) (errs field.ErrorList) { - { // field ateapipb.GetTagRequest.Tag + { // field v1.GetTagRequest.Tag fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -4665,12 +4665,12 @@ func Validate_GetTagRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -4682,7 +4682,7 @@ func Validate_GetTagRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.GetTagRequest) *ateapipb.ObjectRef { + func(oldObj *v1.GetTagRequest) *v1.ObjectRef { return oldObj.Tag }) errs = append(errs, fn(fldPath.Child("tag"), obj.Tag, oldVal, oldObj != nil)...) @@ -4695,12 +4695,12 @@ func Validate_GetTagRequest( // to declarative validation rules in the API schema. func Validate_GetWorkerRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.GetWorkerRequest) (errs field.ErrorList) { + obj, oldObj *v1.GetWorkerRequest) (errs field.ErrorList) { - { // field ateapipb.GetWorkerRequest.Worker + { // field v1.GetWorkerRequest.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -4720,16 +4720,16 @@ func Validate_GetWorkerRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -4741,7 +4741,7 @@ func Validate_GetWorkerRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.GetWorkerRequest) *ateapipb.ObjectRef { + func(oldObj *v1.GetWorkerRequest) *v1.ObjectRef { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) @@ -4754,12 +4754,12 @@ func Validate_GetWorkerRequest( // to declarative validation rules in the API schema. func Validate_GoldenSnapshotConfig( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.GoldenSnapshotConfig) (errs field.ErrorList) { + obj, oldObj *v1.GoldenSnapshotConfig) (errs field.ErrorList) { - { // field ateapipb.GoldenSnapshotConfig.Mode + { // field v1.GoldenSnapshotConfig.Mode fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.GoldenSnapshotMode, + obj, oldObj *v1.GoldenSnapshotMode, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -4785,7 +4785,7 @@ func Validate_GoldenSnapshotConfig( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.GoldenSnapshotConfig) *ateapipb.GoldenSnapshotMode { + func(oldObj *v1.GoldenSnapshotConfig) *v1.GoldenSnapshotMode { return &oldObj.Mode }) errs = append(errs, fn(fldPath.Child("mode"), &obj.Mode, oldVal, oldObj != nil)...) @@ -4798,12 +4798,12 @@ func Validate_GoldenSnapshotConfig( // to declarative validation rules in the API schema. func Validate_GoldenSnapshotStatus( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.GoldenSnapshotStatus) (errs field.ErrorList) { + obj, oldObj *v1.GoldenSnapshotStatus) (errs field.ErrorList) { - { // field ateapipb.GoldenSnapshotStatus.GoldenTag + { // field v1.GoldenSnapshotStatus.GoldenTag fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -4822,12 +4822,12 @@ func Validate_GoldenSnapshotStatus( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -4839,13 +4839,13 @@ func Validate_GoldenSnapshotStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.GoldenSnapshotStatus) *ateapipb.ObjectRef { + func(oldObj *v1.GoldenSnapshotStatus) *v1.ObjectRef { return oldObj.GoldenTag }) errs = append(errs, fn(fldPath.Child("golden_tag"), obj.GoldenTag, oldVal, oldObj != nil)...) } - { // field ateapipb.GoldenSnapshotStatus.SnapshotTime + { // field v1.GoldenSnapshotStatus.SnapshotTime fn := func( fldPath *field.Path, obj, oldObj *timestamppb.Timestamp, @@ -4867,13 +4867,13 @@ func Validate_GoldenSnapshotStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.GoldenSnapshotStatus) *timestamppb.Timestamp { + func(oldObj *v1.GoldenSnapshotStatus) *timestamppb.Timestamp { return oldObj.SnapshotTime }) errs = append(errs, fn(fldPath.Child("snapshot_time"), obj.SnapshotTime, oldVal, oldObj != nil)...) } - { // field ateapipb.GoldenSnapshotStatus.ErrorMessage + { // field v1.GoldenSnapshotStatus.ErrorMessage fn := func( fldPath *field.Path, obj, oldObj *string, @@ -4898,7 +4898,7 @@ func Validate_GoldenSnapshotStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.GoldenSnapshotStatus) *string { + func(oldObj *v1.GoldenSnapshotStatus) *string { return &oldObj.ErrorMessage }) errs = append(errs, fn(fldPath.Child("error_message"), &obj.ErrorMessage, oldVal, oldObj != nil)...) @@ -4911,9 +4911,9 @@ func Validate_GoldenSnapshotStatus( // to declarative validation rules in the API schema. func Validate_HttpGetAction( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.HttpGetAction) (errs field.ErrorList) { + obj, oldObj *v1.HttpGetAction) (errs field.ErrorList) { - { // field ateapipb.HttpGetAction.Path + { // field v1.HttpGetAction.Path fn := func( fldPath *field.Path, obj, oldObj *string, @@ -4943,13 +4943,13 @@ func Validate_HttpGetAction( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.HttpGetAction) *string { + func(oldObj *v1.HttpGetAction) *string { return &oldObj.Path }) errs = append(errs, fn(fldPath.Child("path"), &obj.Path, oldVal, oldObj != nil)...) } - { // field ateapipb.HttpGetAction.Port + { // field v1.HttpGetAction.Port fn := func( fldPath *field.Path, obj, oldObj *int32, @@ -4978,7 +4978,7 @@ func Validate_HttpGetAction( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.HttpGetAction) *int32 { + func(oldObj *v1.HttpGetAction) *int32 { return &oldObj.Port }) errs = append(errs, fn(fldPath.Child("port"), &obj.Port, oldVal, oldObj != nil)...) @@ -4991,9 +4991,9 @@ func Validate_HttpGetAction( // to declarative validation rules in the API schema. func Validate_HttpRule( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.HttpRule) (errs field.ErrorList) { + obj, oldObj *v1.HttpRule) (errs field.ErrorList) { - { // field ateapipb.HttpRule.Hostnames + { // field v1.HttpRule.Hostnames fn := func( fldPath *field.Path, obj, oldObj []string, @@ -5028,16 +5028,16 @@ func Validate_HttpRule( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.HttpRule) []string { + func(oldObj *v1.HttpRule) []string { return oldObj.Hostnames }) errs = append(errs, fn(fldPath.Child("hostnames"), obj.Hostnames, oldVal, oldObj != nil)...) } - { // field ateapipb.HttpRule.Ports + { // field v1.HttpRule.Ports fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Ports, + obj, oldObj *v1.Ports, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -5058,16 +5058,16 @@ func Validate_HttpRule( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.HttpRule) *ateapipb.Ports { + func(oldObj *v1.HttpRule) *v1.Ports { return oldObj.Ports }) errs = append(errs, fn(fldPath.Child("ports"), obj.Ports, oldVal, oldObj != nil)...) } - { // field ateapipb.HttpRule.Effects + { // field v1.HttpRule.Effects fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.HttpRuleEffects, + obj, oldObj *v1.HttpRuleEffects, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -5088,7 +5088,7 @@ func Validate_HttpRule( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.HttpRule) *ateapipb.HttpRuleEffects { + func(oldObj *v1.HttpRule) *v1.HttpRuleEffects { return oldObj.Effects }) errs = append(errs, fn(fldPath.Child("effects"), obj.Effects, oldVal, oldObj != nil)...) @@ -5101,17 +5101,17 @@ func Validate_HttpRule( // to declarative validation rules in the API schema. func Validate_HttpRuleEffects( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.HttpRuleEffects) (errs field.ErrorList) { + obj, oldObj *v1.HttpRuleEffects) (errs field.ErrorList) { // custom validation if e := ValidateCustom_HttpRuleEffects(ctx, op, fldPath, obj, oldObj); len(e) != 0 { errs = append(errs, e...) } - { // field ateapipb.HttpRuleEffects.ReplaceHeaders + { // field v1.HttpRuleEffects.ReplaceHeaders fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.CredentialHeader, + obj, oldObj []*v1.CredentialHeader, oldValueCorrelated bool) (errs field.ErrorList) { // Uniqueness validation is implemented via custom, handwritten validation // don't revalidate unchanged data @@ -5122,7 +5122,7 @@ func Validate_HttpRuleEffects( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.CredentialHeader](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.CredentialHeader](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -5142,13 +5142,13 @@ func Validate_HttpRuleEffects( } // iterate the list and call the type's validation function if e := validate.EachPtrSliceVal(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.CredentialHeader, b *ateapipb.CredentialHeader) bool { return a.Header == b.Header }, ateDeepEqual, Validate_CredentialHeader); len(e) != 0 { + func(a *v1.CredentialHeader, b *v1.CredentialHeader) bool { return a.Header == b.Header }, ateDeepEqual, Validate_CredentialHeader); len(e) != 0 { errs = append(errs, e...) } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.HttpRuleEffects) []*ateapipb.CredentialHeader { + func(oldObj *v1.HttpRuleEffects) []*v1.CredentialHeader { return oldObj.ReplaceHeaders }) errs = append(errs, fn(fldPath.Child("replace_headers"), obj.ReplaceHeaders, oldVal, oldObj != nil)...) @@ -5161,9 +5161,9 @@ func Validate_HttpRuleEffects( // to declarative validation rules in the API schema. func Validate_HttpsRule( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.HttpsRule) (errs field.ErrorList) { + obj, oldObj *v1.HttpsRule) (errs field.ErrorList) { - { // field ateapipb.HttpsRule.Hostnames + { // field v1.HttpsRule.Hostnames fn := func( fldPath *field.Path, obj, oldObj []string, @@ -5198,16 +5198,16 @@ func Validate_HttpsRule( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.HttpsRule) []string { + func(oldObj *v1.HttpsRule) []string { return oldObj.Hostnames }) errs = append(errs, fn(fldPath.Child("hostnames"), obj.Hostnames, oldVal, oldObj != nil)...) } - { // field ateapipb.HttpsRule.Ports + { // field v1.HttpsRule.Ports fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Ports, + obj, oldObj *v1.Ports, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -5228,16 +5228,16 @@ func Validate_HttpsRule( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.HttpsRule) *ateapipb.Ports { + func(oldObj *v1.HttpsRule) *v1.Ports { return oldObj.Ports }) errs = append(errs, fn(fldPath.Child("ports"), obj.Ports, oldVal, oldObj != nil)...) } - { // field ateapipb.HttpsRule.Effects + { // field v1.HttpsRule.Effects fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.HttpRuleEffects, + obj, oldObj *v1.HttpRuleEffects, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -5258,7 +5258,7 @@ func Validate_HttpsRule( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.HttpsRule) *ateapipb.HttpRuleEffects { + func(oldObj *v1.HttpsRule) *v1.HttpRuleEffects { return oldObj.Effects }) errs = append(errs, fn(fldPath.Child("effects"), obj.Effects, oldVal, oldObj != nil)...) @@ -5271,9 +5271,9 @@ func Validate_HttpsRule( // to declarative validation rules in the API schema. func Validate_ImageVolumeSource( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ImageVolumeSource) (errs field.ErrorList) { + obj, oldObj *v1.ImageVolumeSource) (errs field.ErrorList) { - { // field ateapipb.ImageVolumeSource.Reference + { // field v1.ImageVolumeSource.Reference fn := func( fldPath *field.Path, obj, oldObj *string, @@ -5303,7 +5303,7 @@ func Validate_ImageVolumeSource( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ImageVolumeSource) *string { + func(oldObj *v1.ImageVolumeSource) *string { return &oldObj.Reference }) errs = append(errs, fn(fldPath.Child("reference"), &obj.Reference, oldVal, oldObj != nil)...) @@ -5316,9 +5316,9 @@ func Validate_ImageVolumeSource( // to declarative validation rules in the API schema. func Validate_ListActorTemplatesRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ListActorTemplatesRequest) (errs field.ErrorList) { + obj, oldObj *v1.ListActorTemplatesRequest) (errs field.ErrorList) { - { // field ateapipb.ListActorTemplatesRequest.Atespace + { // field v1.ListActorTemplatesRequest.Atespace fn := func( fldPath *field.Path, obj, oldObj *string, @@ -5343,16 +5343,16 @@ func Validate_ListActorTemplatesRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ListActorTemplatesRequest) *string { + func(oldObj *v1.ListActorTemplatesRequest) *string { return &oldObj.Atespace }) errs = append(errs, fn(fldPath.Child("atespace"), &obj.Atespace, oldVal, oldObj != nil)...) } - { // field ateapipb.ListActorTemplatesRequest.Options + { // field v1.ListActorTemplatesRequest.Options fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ListOptions, + obj, oldObj *v1.ListOptions, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -5373,7 +5373,7 @@ func Validate_ListActorTemplatesRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ListActorTemplatesRequest) *ateapipb.ListOptions { + func(oldObj *v1.ListActorTemplatesRequest) *v1.ListOptions { return oldObj.Options }) errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) @@ -5386,9 +5386,9 @@ func Validate_ListActorTemplatesRequest( // to declarative validation rules in the API schema. func Validate_ListActorsRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ListActorsRequest) (errs field.ErrorList) { + obj, oldObj *v1.ListActorsRequest) (errs field.ErrorList) { - { // field ateapipb.ListActorsRequest.Atespace + { // field v1.ListActorsRequest.Atespace fn := func( fldPath *field.Path, obj, oldObj *string, @@ -5413,16 +5413,16 @@ func Validate_ListActorsRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ListActorsRequest) *string { + func(oldObj *v1.ListActorsRequest) *string { return &oldObj.Atespace }) errs = append(errs, fn(fldPath.Child("atespace"), &obj.Atespace, oldVal, oldObj != nil)...) } - { // field ateapipb.ListActorsRequest.Options + { // field v1.ListActorsRequest.Options fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ListOptions, + obj, oldObj *v1.ListOptions, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -5443,7 +5443,7 @@ func Validate_ListActorsRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ListActorsRequest) *ateapipb.ListOptions { + func(oldObj *v1.ListActorsRequest) *v1.ListOptions { return oldObj.Options }) errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) @@ -5456,12 +5456,12 @@ func Validate_ListActorsRequest( // to declarative validation rules in the API schema. func Validate_ListAtespacesRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ListAtespacesRequest) (errs field.ErrorList) { + obj, oldObj *v1.ListAtespacesRequest) (errs field.ErrorList) { - { // field ateapipb.ListAtespacesRequest.Options + { // field v1.ListAtespacesRequest.Options fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ListOptions, + obj, oldObj *v1.ListOptions, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -5482,7 +5482,7 @@ func Validate_ListAtespacesRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ListAtespacesRequest) *ateapipb.ListOptions { + func(oldObj *v1.ListAtespacesRequest) *v1.ListOptions { return oldObj.Options }) errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) @@ -5495,9 +5495,9 @@ func Validate_ListAtespacesRequest( // to declarative validation rules in the API schema. func Validate_ListOptions( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ListOptions) (errs field.ErrorList) { + obj, oldObj *v1.ListOptions) (errs field.ErrorList) { - { // field ateapipb.ListOptions.PageSize + { // field v1.ListOptions.PageSize fn := func( fldPath *field.Path, obj, oldObj *int32, @@ -5522,13 +5522,13 @@ func Validate_ListOptions( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ListOptions) *int32 { + func(oldObj *v1.ListOptions) *int32 { return &oldObj.PageSize }) errs = append(errs, fn(fldPath.Child("page_size"), &obj.PageSize, oldVal, oldObj != nil)...) } - { // field ateapipb.ListOptions.PageToken + { // field v1.ListOptions.PageToken fn := func( fldPath *field.Path, obj, oldObj *string, @@ -5553,7 +5553,7 @@ func Validate_ListOptions( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ListOptions) *string { + func(oldObj *v1.ListOptions) *string { return &oldObj.PageToken }) errs = append(errs, fn(fldPath.Child("page_token"), &obj.PageToken, oldVal, oldObj != nil)...) @@ -5566,9 +5566,9 @@ func Validate_ListOptions( // to declarative validation rules in the API schema. func Validate_ListTagsRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ListTagsRequest) (errs field.ErrorList) { + obj, oldObj *v1.ListTagsRequest) (errs field.ErrorList) { - { // field ateapipb.ListTagsRequest.Atespace + { // field v1.ListTagsRequest.Atespace fn := func( fldPath *field.Path, obj, oldObj *string, @@ -5593,16 +5593,16 @@ func Validate_ListTagsRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ListTagsRequest) *string { + func(oldObj *v1.ListTagsRequest) *string { return &oldObj.Atespace }) errs = append(errs, fn(fldPath.Child("atespace"), &obj.Atespace, oldVal, oldObj != nil)...) } - { // field ateapipb.ListTagsRequest.Options + { // field v1.ListTagsRequest.Options fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ListOptions, + obj, oldObj *v1.ListOptions, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -5623,7 +5623,7 @@ func Validate_ListTagsRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ListTagsRequest) *ateapipb.ListOptions { + func(oldObj *v1.ListTagsRequest) *v1.ListOptions { return oldObj.Options }) errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) @@ -5636,12 +5636,12 @@ func Validate_ListTagsRequest( // to declarative validation rules in the API schema. func Validate_ListWorkerActorAssignmentsRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ListWorkerActorAssignmentsRequest) (errs field.ErrorList) { + obj, oldObj *v1.ListWorkerActorAssignmentsRequest) (errs field.ErrorList) { - { // field ateapipb.ListWorkerActorAssignmentsRequest.Worker + { // field v1.ListWorkerActorAssignmentsRequest.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -5661,16 +5661,16 @@ func Validate_ListWorkerActorAssignmentsRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -5682,16 +5682,16 @@ func Validate_ListWorkerActorAssignmentsRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ListWorkerActorAssignmentsRequest) *ateapipb.ObjectRef { + func(oldObj *v1.ListWorkerActorAssignmentsRequest) *v1.ObjectRef { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) } - { // field ateapipb.ListWorkerActorAssignmentsRequest.Options + { // field v1.ListWorkerActorAssignmentsRequest.Options fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ListOptions, + obj, oldObj *v1.ListOptions, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -5712,7 +5712,7 @@ func Validate_ListWorkerActorAssignmentsRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ListWorkerActorAssignmentsRequest) *ateapipb.ListOptions { + func(oldObj *v1.ListWorkerActorAssignmentsRequest) *v1.ListOptions { return oldObj.Options }) errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) @@ -5725,12 +5725,12 @@ func Validate_ListWorkerActorAssignmentsRequest( // to declarative validation rules in the API schema. func Validate_ListWorkersRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ListWorkersRequest) (errs field.ErrorList) { + obj, oldObj *v1.ListWorkersRequest) (errs field.ErrorList) { - { // field ateapipb.ListWorkersRequest.Options + { // field v1.ListWorkersRequest.Options fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ListOptions, + obj, oldObj *v1.ListOptions, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -5751,7 +5751,7 @@ func Validate_ListWorkersRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ListWorkersRequest) *ateapipb.ListOptions { + func(oldObj *v1.ListWorkersRequest) *v1.ListOptions { return oldObj.Options }) errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) @@ -5764,12 +5764,12 @@ func Validate_ListWorkersRequest( // to declarative validation rules in the API schema. func Validate_MarkWorkerAvailableRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.MarkWorkerAvailableRequest) (errs field.ErrorList) { + obj, oldObj *v1.MarkWorkerAvailableRequest) (errs field.ErrorList) { - { // field ateapipb.MarkWorkerAvailableRequest.Worker + { // field v1.MarkWorkerAvailableRequest.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -5789,16 +5789,16 @@ func Validate_MarkWorkerAvailableRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -5810,7 +5810,7 @@ func Validate_MarkWorkerAvailableRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MarkWorkerAvailableRequest) *ateapipb.ObjectRef { + func(oldObj *v1.MarkWorkerAvailableRequest) *v1.ObjectRef { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) @@ -5823,12 +5823,12 @@ func Validate_MarkWorkerAvailableRequest( // to declarative validation rules in the API schema. func Validate_MarkWorkerUnavailableRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.MarkWorkerUnavailableRequest) (errs field.ErrorList) { + obj, oldObj *v1.MarkWorkerUnavailableRequest) (errs field.ErrorList) { - { // field ateapipb.MarkWorkerUnavailableRequest.Worker + { // field v1.MarkWorkerUnavailableRequest.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -5848,16 +5848,16 @@ func Validate_MarkWorkerUnavailableRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -5869,7 +5869,7 @@ func Validate_MarkWorkerUnavailableRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MarkWorkerUnavailableRequest) *ateapipb.ObjectRef { + func(oldObj *v1.MarkWorkerUnavailableRequest) *v1.ObjectRef { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) @@ -5882,12 +5882,12 @@ func Validate_MarkWorkerUnavailableRequest( // to declarative validation rules in the API schema. func Validate_MintActorCertificateRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.MintActorCertificateRequest) (errs field.ErrorList) { + obj, oldObj *v1.MintActorCertificateRequest) (errs field.ErrorList) { - { // field ateapipb.MintActorCertificateRequest.Actor + { // field v1.MintActorCertificateRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -5909,13 +5909,13 @@ func Validate_MintActorCertificateRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MintActorCertificateRequest) *ateapipb.ObjectRef { + func(oldObj *v1.MintActorCertificateRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) } - { // field ateapipb.MintActorCertificateRequest.ActorUid + { // field v1.MintActorCertificateRequest.ActorUid fn := func( fldPath *field.Path, obj, oldObj *string, @@ -5941,13 +5941,13 @@ func Validate_MintActorCertificateRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MintActorCertificateRequest) *string { + func(oldObj *v1.MintActorCertificateRequest) *string { return &oldObj.ActorUid }) errs = append(errs, fn(fldPath.Child("actor_uid"), &obj.ActorUid, oldVal, oldObj != nil)...) } - { // field ateapipb.MintActorCertificateRequest.CertificateSigningRequest + { // field v1.MintActorCertificateRequest.CertificateSigningRequest fn := func( fldPath *field.Path, obj, oldObj []byte, @@ -5973,7 +5973,7 @@ func Validate_MintActorCertificateRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MintActorCertificateRequest) []byte { + func(oldObj *v1.MintActorCertificateRequest) []byte { return oldObj.CertificateSigningRequest }) errs = append(errs, fn(fldPath.Child("certificate_signing_request"), obj.CertificateSigningRequest, oldVal, oldObj != nil)...) @@ -5986,12 +5986,12 @@ func Validate_MintActorCertificateRequest( // to declarative validation rules in the API schema. func Validate_MintActorJwtRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.MintActorJwtRequest) (errs field.ErrorList) { + obj, oldObj *v1.MintActorJwtRequest) (errs field.ErrorList) { - { // field ateapipb.MintActorJwtRequest.Actor + { // field v1.MintActorJwtRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -6013,13 +6013,13 @@ func Validate_MintActorJwtRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MintActorJwtRequest) *ateapipb.ObjectRef { + func(oldObj *v1.MintActorJwtRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) } - { // field ateapipb.MintActorJwtRequest.Audiences + { // field v1.MintActorJwtRequest.Audiences fn := func( fldPath *field.Path, obj, oldObj []string, @@ -6056,13 +6056,13 @@ func Validate_MintActorJwtRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MintActorJwtRequest) []string { + func(oldObj *v1.MintActorJwtRequest) []string { return oldObj.Audiences }) errs = append(errs, fn(fldPath.Child("audiences"), obj.Audiences, oldVal, oldObj != nil)...) } - { // field ateapipb.MintActorJwtRequest.ExpirationSeconds + { // field v1.MintActorJwtRequest.ExpirationSeconds fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -6091,7 +6091,7 @@ func Validate_MintActorJwtRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MintActorJwtRequest) *int64 { + func(oldObj *v1.MintActorJwtRequest) *int64 { return &oldObj.ExpirationSeconds }) errs = append(errs, fn(fldPath.Child("expiration_seconds"), &obj.ExpirationSeconds, oldVal, oldObj != nil)...) @@ -6104,12 +6104,12 @@ func Validate_MintActorJwtRequest( // to declarative validation rules in the API schema. func Validate_MintWorkerActorCertificateRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.MintWorkerActorCertificateRequest) (errs field.ErrorList) { + obj, oldObj *v1.MintWorkerActorCertificateRequest) (errs field.ErrorList) { - { // field ateapipb.MintWorkerActorCertificateRequest.Actor + { // field v1.MintWorkerActorCertificateRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -6129,12 +6129,12 @@ func Validate_MintWorkerActorCertificateRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -6146,13 +6146,13 @@ func Validate_MintWorkerActorCertificateRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MintWorkerActorCertificateRequest) *ateapipb.ObjectRef { + func(oldObj *v1.MintWorkerActorCertificateRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) } - { // field ateapipb.MintWorkerActorCertificateRequest.ActorUid + { // field v1.MintWorkerActorCertificateRequest.ActorUid fn := func( fldPath *field.Path, obj, oldObj *string, @@ -6178,13 +6178,13 @@ func Validate_MintWorkerActorCertificateRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MintWorkerActorCertificateRequest) *string { + func(oldObj *v1.MintWorkerActorCertificateRequest) *string { return &oldObj.ActorUid }) errs = append(errs, fn(fldPath.Child("actor_uid"), &obj.ActorUid, oldVal, oldObj != nil)...) } - { // field ateapipb.MintWorkerActorCertificateRequest.CertificateSigningRequest + { // field v1.MintWorkerActorCertificateRequest.CertificateSigningRequest fn := func( fldPath *field.Path, obj, oldObj []byte, @@ -6210,16 +6210,16 @@ func Validate_MintWorkerActorCertificateRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MintWorkerActorCertificateRequest) []byte { + func(oldObj *v1.MintWorkerActorCertificateRequest) []byte { return oldObj.CertificateSigningRequest }) errs = append(errs, fn(fldPath.Child("certificate_signing_request"), obj.CertificateSigningRequest, oldVal, oldObj != nil)...) } - { // field ateapipb.MintWorkerActorCertificateRequest.Worker + { // field v1.MintWorkerActorCertificateRequest.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -6239,16 +6239,16 @@ func Validate_MintWorkerActorCertificateRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -6260,7 +6260,7 @@ func Validate_MintWorkerActorCertificateRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MintWorkerActorCertificateRequest) *ateapipb.ObjectRef { + func(oldObj *v1.MintWorkerActorCertificateRequest) *v1.ObjectRef { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) @@ -6273,12 +6273,12 @@ func Validate_MintWorkerActorCertificateRequest( // to declarative validation rules in the API schema. func Validate_MintWorkerActorJwtRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.MintWorkerActorJwtRequest) (errs field.ErrorList) { + obj, oldObj *v1.MintWorkerActorJwtRequest) (errs field.ErrorList) { - { // field ateapipb.MintWorkerActorJwtRequest.Actor + { // field v1.MintWorkerActorJwtRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -6298,12 +6298,12 @@ func Validate_MintWorkerActorJwtRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -6315,13 +6315,13 @@ func Validate_MintWorkerActorJwtRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MintWorkerActorJwtRequest) *ateapipb.ObjectRef { + func(oldObj *v1.MintWorkerActorJwtRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) } - { // field ateapipb.MintWorkerActorJwtRequest.ActorUid + { // field v1.MintWorkerActorJwtRequest.ActorUid fn := func( fldPath *field.Path, obj, oldObj *string, @@ -6347,13 +6347,13 @@ func Validate_MintWorkerActorJwtRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MintWorkerActorJwtRequest) *string { + func(oldObj *v1.MintWorkerActorJwtRequest) *string { return &oldObj.ActorUid }) errs = append(errs, fn(fldPath.Child("actor_uid"), &obj.ActorUid, oldVal, oldObj != nil)...) } - { // field ateapipb.MintWorkerActorJwtRequest.Audiences + { // field v1.MintWorkerActorJwtRequest.Audiences fn := func( fldPath *field.Path, obj, oldObj []string, @@ -6396,7 +6396,7 @@ func Validate_MintWorkerActorJwtRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.MintWorkerActorJwtRequest) []string { + func(oldObj *v1.MintWorkerActorJwtRequest) []string { return oldObj.Audiences }) errs = append(errs, fn(fldPath.Child("audiences"), obj.Audiences, oldVal, oldObj != nil)...) @@ -6409,9 +6409,9 @@ func Validate_MintWorkerActorJwtRequest( // to declarative validation rules in the API schema. func Validate_ObjectRef( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef) (errs field.ErrorList) { + obj, oldObj *v1.ObjectRef) (errs field.ErrorList) { - { // field ateapipb.ObjectRef.Atespace + { // field v1.ObjectRef.Atespace fn := func( fldPath *field.Path, obj, oldObj *string, @@ -6436,13 +6436,13 @@ func Validate_ObjectRef( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ObjectRef) *string { + func(oldObj *v1.ObjectRef) *string { return &oldObj.Atespace }) errs = append(errs, fn(fldPath.Child("atespace"), &obj.Atespace, oldVal, oldObj != nil)...) } - { // field ateapipb.ObjectRef.Name + { // field v1.ObjectRef.Name fn := func( fldPath *field.Path, obj, oldObj *string, @@ -6468,7 +6468,7 @@ func Validate_ObjectRef( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ObjectRef) *string { + func(oldObj *v1.ObjectRef) *string { return &oldObj.Name }) errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) @@ -6481,9 +6481,9 @@ func Validate_ObjectRef( // to declarative validation rules in the API schema. func Validate_ObjectSnapshot( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ObjectSnapshot) (errs field.ErrorList) { + obj, oldObj *v1.ObjectSnapshot) (errs field.ErrorList) { - { // field ateapipb.ObjectSnapshot.SnapshotUri + { // field v1.ObjectSnapshot.SnapshotUri fn := func( fldPath *field.Path, obj, oldObj *string, @@ -6509,7 +6509,7 @@ func Validate_ObjectSnapshot( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ObjectSnapshot) *string { + func(oldObj *v1.ObjectSnapshot) *string { return &oldObj.SnapshotUri }) errs = append(errs, fn(fldPath.Child("snapshot_uri"), &obj.SnapshotUri, oldVal, oldObj != nil)...) @@ -6518,22 +6518,22 @@ func Validate_ObjectSnapshot( return errs } -var unionMembershipFor_go_ate_dev_substrate_pkg_proto_ateapipb_Ports_ = validate.NewUnionMembership(validate.NewUnionMember("all"), validate.NewUnionMember("numbers")) +var unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_Ports_ = validate.NewUnionMembership(validate.NewUnionMember("all"), validate.NewUnionMember("numbers")) // Validate_Ports validates an instance of Ports according // to declarative validation rules in the API schema. func Validate_Ports( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.Ports) (errs field.ErrorList) { + obj, oldObj *v1.Ports) (errs field.ErrorList) { - if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_pkg_proto_ateapipb_Ports_, - func(obj *ateapipb.Ports) bool { + if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_Ports_, + func(obj *v1.Ports) bool { if obj == nil { return false } return obj.All != nil }, - func(obj *ateapipb.Ports) bool { + func(obj *v1.Ports) bool { if obj == nil { return false } @@ -6542,10 +6542,10 @@ func Validate_Ports( errs = append(errs, e...) } - { // field ateapipb.Ports.All + { // field v1.Ports.All fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.AllPorts, + obj, oldObj *v1.AllPorts, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -6564,13 +6564,13 @@ func Validate_Ports( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Ports) *ateapipb.AllPorts { + func(oldObj *v1.Ports) *v1.AllPorts { return oldObj.All }) errs = append(errs, fn(fldPath.Child("all"), obj.All, oldVal, oldObj != nil)...) } - { // field ateapipb.Ports.Numbers + { // field v1.Ports.Numbers fn := func( fldPath *field.Path, obj, oldObj []int32, @@ -6612,7 +6612,7 @@ func Validate_Ports( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Ports) []int32 { + func(oldObj *v1.Ports) []int32 { return oldObj.Numbers }) errs = append(errs, fn(fldPath.Child("numbers"), obj.Numbers, oldVal, oldObj != nil)...) @@ -6625,12 +6625,12 @@ func Validate_Ports( // to declarative validation rules in the API schema. func Validate_RegisterWorkerRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.RegisterWorkerRequest) (errs field.ErrorList) { + obj, oldObj *v1.RegisterWorkerRequest) (errs field.ErrorList) { - { // field ateapipb.RegisterWorkerRequest.Worker + { // field v1.RegisterWorkerRequest.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -6650,16 +6650,16 @@ func Validate_RegisterWorkerRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -6671,13 +6671,13 @@ func Validate_RegisterWorkerRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.RegisterWorkerRequest) *ateapipb.ObjectRef { + func(oldObj *v1.RegisterWorkerRequest) *v1.ObjectRef { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) } - { // field ateapipb.RegisterWorkerRequest.Epoch + { // field v1.RegisterWorkerRequest.Epoch fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -6703,13 +6703,13 @@ func Validate_RegisterWorkerRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.RegisterWorkerRequest) *int64 { + func(oldObj *v1.RegisterWorkerRequest) *int64 { return &oldObj.Epoch }) errs = append(errs, fn(fldPath.Child("epoch"), &obj.Epoch, oldVal, oldObj != nil)...) } - { // field ateapipb.RegisterWorkerRequest.Ips + { // field v1.RegisterWorkerRequest.Ips fn := func( fldPath *field.Path, obj, oldObj []string, @@ -6740,16 +6740,16 @@ func Validate_RegisterWorkerRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.RegisterWorkerRequest) []string { + func(oldObj *v1.RegisterWorkerRequest) []string { return oldObj.Ips }) errs = append(errs, fn(fldPath.Child("ips"), obj.Ips, oldVal, oldObj != nil)...) } - { // field ateapipb.RegisterWorkerRequest.Capacity + { // field v1.RegisterWorkerRequest.Capacity fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.WorkerResources, + obj, oldObj *v1.WorkerResources, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -6771,7 +6771,7 @@ func Validate_RegisterWorkerRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.RegisterWorkerRequest) *ateapipb.WorkerResources { + func(oldObj *v1.RegisterWorkerRequest) *v1.WorkerResources { return oldObj.Capacity }) errs = append(errs, fn(fldPath.Child("capacity"), obj.Capacity, oldVal, oldObj != nil)...) @@ -6784,12 +6784,12 @@ func Validate_RegisterWorkerRequest( // to declarative validation rules in the API schema. func Validate_ReportActorCrashedRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ReportActorCrashedRequest) (errs field.ErrorList) { + obj, oldObj *v1.ReportActorCrashedRequest) (errs field.ErrorList) { - { // field ateapipb.ReportActorCrashedRequest.Worker + { // field v1.ReportActorCrashedRequest.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -6809,16 +6809,16 @@ func Validate_ReportActorCrashedRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -6830,16 +6830,16 @@ func Validate_ReportActorCrashedRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ReportActorCrashedRequest) *ateapipb.ObjectRef { + func(oldObj *v1.ReportActorCrashedRequest) *v1.ObjectRef { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) } - { // field ateapipb.ReportActorCrashedRequest.Actor + { // field v1.ReportActorCrashedRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -6859,12 +6859,12 @@ func Validate_ReportActorCrashedRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -6876,13 +6876,13 @@ func Validate_ReportActorCrashedRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ReportActorCrashedRequest) *ateapipb.ObjectRef { + func(oldObj *v1.ReportActorCrashedRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) } - { // field ateapipb.ReportActorCrashedRequest.ActorUid + { // field v1.ReportActorCrashedRequest.ActorUid fn := func( fldPath *field.Path, obj, oldObj *string, @@ -6908,13 +6908,13 @@ func Validate_ReportActorCrashedRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ReportActorCrashedRequest) *string { + func(oldObj *v1.ReportActorCrashedRequest) *string { return &oldObj.ActorUid }) errs = append(errs, fn(fldPath.Child("actor_uid"), &obj.ActorUid, oldVal, oldObj != nil)...) } - { // field ateapipb.ReportActorCrashedRequest.Message + { // field v1.ReportActorCrashedRequest.Message fn := func( fldPath *field.Path, obj, oldObj *string, @@ -6940,7 +6940,7 @@ func Validate_ReportActorCrashedRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ReportActorCrashedRequest) *string { + func(oldObj *v1.ReportActorCrashedRequest) *string { return &oldObj.Message }) errs = append(errs, fn(fldPath.Child("message"), &obj.Message, oldVal, oldObj != nil)...) @@ -6953,12 +6953,12 @@ func Validate_ReportActorCrashedRequest( // to declarative validation rules in the API schema. func Validate_ReportActorSnapshotStateRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ReportActorSnapshotStateRequest) (errs field.ErrorList) { + obj, oldObj *v1.ReportActorSnapshotStateRequest) (errs field.ErrorList) { - { // field ateapipb.ReportActorSnapshotStateRequest.Actor + { // field v1.ReportActorSnapshotStateRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -6978,12 +6978,12 @@ func Validate_ReportActorSnapshotStateRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -6995,13 +6995,13 @@ func Validate_ReportActorSnapshotStateRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ReportActorSnapshotStateRequest) *ateapipb.ObjectRef { + func(oldObj *v1.ReportActorSnapshotStateRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) } - { // field ateapipb.ReportActorSnapshotStateRequest.ActorUid + { // field v1.ReportActorSnapshotStateRequest.ActorUid fn := func( fldPath *field.Path, obj, oldObj *string, @@ -7027,16 +7027,16 @@ func Validate_ReportActorSnapshotStateRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ReportActorSnapshotStateRequest) *string { + func(oldObj *v1.ReportActorSnapshotStateRequest) *string { return &oldObj.ActorUid }) errs = append(errs, fn(fldPath.Child("actor_uid"), &obj.ActorUid, oldVal, oldObj != nil)...) } - { // field ateapipb.ReportActorSnapshotStateRequest.State + { // field v1.ReportActorSnapshotStateRequest.State fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ActorSnapshotState, + obj, oldObj *v1.ActorSnapshotState, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -7058,7 +7058,7 @@ func Validate_ReportActorSnapshotStateRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ReportActorSnapshotStateRequest) *ateapipb.ActorSnapshotState { + func(oldObj *v1.ReportActorSnapshotStateRequest) *v1.ActorSnapshotState { return oldObj.State }) errs = append(errs, fn(fldPath.Child("state"), obj.State, oldVal, oldObj != nil)...) @@ -7071,12 +7071,12 @@ func Validate_ReportActorSnapshotStateRequest( // to declarative validation rules in the API schema. func Validate_RequestActorSuspendRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.RequestActorSuspendRequest) (errs field.ErrorList) { + obj, oldObj *v1.RequestActorSuspendRequest) (errs field.ErrorList) { - { // field ateapipb.RequestActorSuspendRequest.Worker + { // field v1.RequestActorSuspendRequest.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -7096,16 +7096,16 @@ func Validate_RequestActorSuspendRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -7117,16 +7117,16 @@ func Validate_RequestActorSuspendRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.RequestActorSuspendRequest) *ateapipb.ObjectRef { + func(oldObj *v1.RequestActorSuspendRequest) *v1.ObjectRef { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) } - { // field ateapipb.RequestActorSuspendRequest.Actor + { // field v1.RequestActorSuspendRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -7146,12 +7146,12 @@ func Validate_RequestActorSuspendRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -7163,13 +7163,13 @@ func Validate_RequestActorSuspendRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.RequestActorSuspendRequest) *ateapipb.ObjectRef { + func(oldObj *v1.RequestActorSuspendRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) } - { // field ateapipb.RequestActorSuspendRequest.ActorUid + { // field v1.RequestActorSuspendRequest.ActorUid fn := func( fldPath *field.Path, obj, oldObj *string, @@ -7195,7 +7195,7 @@ func Validate_RequestActorSuspendRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.RequestActorSuspendRequest) *string { + func(oldObj *v1.RequestActorSuspendRequest) *string { return &oldObj.ActorUid }) errs = append(errs, fn(fldPath.Child("actor_uid"), &obj.ActorUid, oldVal, oldObj != nil)...) @@ -7208,14 +7208,14 @@ func Validate_RequestActorSuspendRequest( // to declarative validation rules in the API schema. func Validate_ResourceMetadata( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ResourceMetadata) (errs field.ErrorList) { + obj, oldObj *v1.ResourceMetadata) (errs field.ErrorList) { // custom validation if e := ValidateCustom_ResourceMetadata(ctx, op, fldPath, obj, oldObj); len(e) != 0 { errs = append(errs, e...) } - { // field ateapipb.ResourceMetadata.Atespace + { // field v1.ResourceMetadata.Atespace fn := func( fldPath *field.Path, obj, oldObj *string, @@ -7244,13 +7244,13 @@ func Validate_ResourceMetadata( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ResourceMetadata) *string { + func(oldObj *v1.ResourceMetadata) *string { return &oldObj.Atespace }) errs = append(errs, fn(fldPath.Child("atespace"), &obj.Atespace, oldVal, oldObj != nil)...) } - { // field ateapipb.ResourceMetadata.Name + { // field v1.ResourceMetadata.Name fn := func( fldPath *field.Path, obj, oldObj *string, @@ -7280,13 +7280,13 @@ func Validate_ResourceMetadata( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ResourceMetadata) *string { + func(oldObj *v1.ResourceMetadata) *string { return &oldObj.Name }) errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) } - { // field ateapipb.ResourceMetadata.Uid + { // field v1.ResourceMetadata.Uid fn := func( fldPath *field.Path, obj, oldObj *string, @@ -7315,13 +7315,13 @@ func Validate_ResourceMetadata( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ResourceMetadata) *string { + func(oldObj *v1.ResourceMetadata) *string { return &oldObj.Uid }) errs = append(errs, fn(fldPath.Child("uid"), &obj.Uid, oldVal, oldObj != nil)...) } - { // field ateapipb.ResourceMetadata.Version + { // field v1.ResourceMetadata.Version fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -7354,13 +7354,13 @@ func Validate_ResourceMetadata( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ResourceMetadata) *int64 { + func(oldObj *v1.ResourceMetadata) *int64 { return &oldObj.Version }) errs = append(errs, fn(fldPath.Child("version"), &obj.Version, oldVal, oldObj != nil)...) } - { // field ateapipb.ResourceMetadata.CreateTime + { // field v1.ResourceMetadata.CreateTime fn := func( fldPath *field.Path, obj, oldObj *timestamppb.Timestamp, @@ -7386,13 +7386,13 @@ func Validate_ResourceMetadata( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ResourceMetadata) *timestamppb.Timestamp { + func(oldObj *v1.ResourceMetadata) *timestamppb.Timestamp { return oldObj.CreateTime }) errs = append(errs, fn(fldPath.Child("create_time"), obj.CreateTime, oldVal, oldObj != nil)...) } - { // field ateapipb.ResourceMetadata.UpdateTime + { // field v1.ResourceMetadata.UpdateTime fn := func( fldPath *field.Path, obj, oldObj *timestamppb.Timestamp, @@ -7418,13 +7418,13 @@ func Validate_ResourceMetadata( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ResourceMetadata) *timestamppb.Timestamp { + func(oldObj *v1.ResourceMetadata) *timestamppb.Timestamp { return oldObj.UpdateTime }) errs = append(errs, fn(fldPath.Child("update_time"), obj.UpdateTime, oldVal, oldObj != nil)...) } - { // field ateapipb.ResourceMetadata.DeleteTime + { // field v1.ResourceMetadata.DeleteTime fn := func( fldPath *field.Path, obj, oldObj *timestamppb.Timestamp, @@ -7450,7 +7450,7 @@ func Validate_ResourceMetadata( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ResourceMetadata) *timestamppb.Timestamp { + func(oldObj *v1.ResourceMetadata) *timestamppb.Timestamp { return oldObj.DeleteTime }) errs = append(errs, fn(fldPath.Child("delete_time"), obj.DeleteTime, oldVal, oldObj != nil)...) @@ -7463,12 +7463,12 @@ func Validate_ResourceMetadata( // to declarative validation rules in the API schema. func Validate_ResourceRequirements( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ResourceRequirements) (errs field.ErrorList) { + obj, oldObj *v1.ResourceRequirements) (errs field.ErrorList) { - { // field ateapipb.ResourceRequirements.Limits + { // field v1.ResourceRequirements.Limits fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Resources, + obj, oldObj *v1.Resources, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -7489,7 +7489,7 @@ func Validate_ResourceRequirements( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ResourceRequirements) *ateapipb.Resources { + func(oldObj *v1.ResourceRequirements) *v1.Resources { return oldObj.Limits }) errs = append(errs, fn(fldPath.Child("limits"), obj.Limits, oldVal, oldObj != nil)...) @@ -7502,9 +7502,9 @@ func Validate_ResourceRequirements( // to declarative validation rules in the API schema. func Validate_Resources( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.Resources) (errs field.ErrorList) { + obj, oldObj *v1.Resources) (errs field.ErrorList) { - { // field ateapipb.Resources.CpuMillicores + { // field v1.Resources.CpuMillicores fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -7532,13 +7532,13 @@ func Validate_Resources( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Resources) *int64 { + func(oldObj *v1.Resources) *int64 { return &oldObj.CpuMillicores }) errs = append(errs, fn(fldPath.Child("cpu_millicores"), &obj.CpuMillicores, oldVal, oldObj != nil)...) } - { // field ateapipb.Resources.MemoryBytes + { // field v1.Resources.MemoryBytes fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -7563,7 +7563,7 @@ func Validate_Resources( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Resources) *int64 { + func(oldObj *v1.Resources) *int64 { return &oldObj.MemoryBytes }) errs = append(errs, fn(fldPath.Child("memory_bytes"), &obj.MemoryBytes, oldVal, oldObj != nil)...) @@ -7576,12 +7576,12 @@ func Validate_Resources( // to declarative validation rules in the API schema. func Validate_ResumeActorRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.ResumeActorRequest) (errs field.ErrorList) { + obj, oldObj *v1.ResumeActorRequest) (errs field.ErrorList) { - { // field ateapipb.ResumeActorRequest.Actor + { // field v1.ResumeActorRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -7601,12 +7601,12 @@ func Validate_ResumeActorRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -7618,7 +7618,7 @@ func Validate_ResumeActorRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.ResumeActorRequest) *ateapipb.ObjectRef { + func(oldObj *v1.ResumeActorRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) @@ -7631,12 +7631,12 @@ func Validate_ResumeActorRequest( // to declarative validation rules in the API schema. func Validate_RevertActorRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.RevertActorRequest) (errs field.ErrorList) { + obj, oldObj *v1.RevertActorRequest) (errs field.ErrorList) { - { // field ateapipb.RevertActorRequest.Actor + { // field v1.RevertActorRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -7656,12 +7656,12 @@ func Validate_RevertActorRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -7673,7 +7673,7 @@ func Validate_RevertActorRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.RevertActorRequest) *ateapipb.ObjectRef { + func(oldObj *v1.RevertActorRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) @@ -7686,12 +7686,12 @@ func Validate_RevertActorRequest( // to declarative validation rules in the API schema. func Validate_SecurityContext( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.SecurityContext) (errs field.ErrorList) { + obj, oldObj *v1.SecurityContext) (errs field.ErrorList) { - { // field ateapipb.SecurityContext.Capabilities + { // field v1.SecurityContext.Capabilities fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Capabilities, + obj, oldObj *v1.Capabilities, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -7712,7 +7712,7 @@ func Validate_SecurityContext( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SecurityContext) *ateapipb.Capabilities { + func(oldObj *v1.SecurityContext) *v1.Capabilities { return oldObj.Capabilities }) errs = append(errs, fn(fldPath.Child("capabilities"), obj.Capabilities, oldVal, oldObj != nil)...) @@ -7721,16 +7721,16 @@ func Validate_SecurityContext( return errs } -var unionMembershipFor_go_ate_dev_substrate_pkg_proto_ateapipb_Selector_ = validate.NewUnionMembership(validate.NewUnionMember("match_labels")) +var unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_Selector_ = validate.NewUnionMembership(validate.NewUnionMember("match_labels")) // Validate_Selector validates an instance of Selector according // to declarative validation rules in the API schema. func Validate_Selector( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.Selector) (errs field.ErrorList) { + obj, oldObj *v1.Selector) (errs field.ErrorList) { - if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_pkg_proto_ateapipb_Selector_, - func(obj *ateapipb.Selector) bool { + if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_Selector_, + func(obj *v1.Selector) bool { if obj == nil { return false } @@ -7739,7 +7739,7 @@ func Validate_Selector( errs = append(errs, e...) } - { // field ateapipb.Selector.MatchLabels + { // field v1.Selector.MatchLabels fn := func( fldPath *field.Path, obj, oldObj map[string]string, @@ -7774,7 +7774,7 @@ func Validate_Selector( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Selector) map[string]string { + func(oldObj *v1.Selector) map[string]string { return oldObj.MatchLabels }) errs = append(errs, fn(fldPath.Child("match_labels"), obj.MatchLabels, oldVal, oldObj != nil)...) @@ -7787,12 +7787,12 @@ func Validate_Selector( // to declarative validation rules in the API schema. func Validate_SetWorkerSandboxRuntimesRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.SetWorkerSandboxRuntimesRequest) (errs field.ErrorList) { + obj, oldObj *v1.SetWorkerSandboxRuntimesRequest) (errs field.ErrorList) { - { // field ateapipb.SetWorkerSandboxRuntimesRequest.Worker + { // field v1.SetWorkerSandboxRuntimesRequest.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -7812,16 +7812,16 @@ func Validate_SetWorkerSandboxRuntimesRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -7833,13 +7833,13 @@ func Validate_SetWorkerSandboxRuntimesRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SetWorkerSandboxRuntimesRequest) *ateapipb.ObjectRef { + func(oldObj *v1.SetWorkerSandboxRuntimesRequest) *v1.ObjectRef { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) } - { // field ateapipb.SetWorkerSandboxRuntimesRequest.Epoch + { // field v1.SetWorkerSandboxRuntimesRequest.Epoch fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -7865,16 +7865,16 @@ func Validate_SetWorkerSandboxRuntimesRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SetWorkerSandboxRuntimesRequest) *int64 { + func(oldObj *v1.SetWorkerSandboxRuntimesRequest) *int64 { return &oldObj.Epoch }) errs = append(errs, fn(fldPath.Child("epoch"), &obj.Epoch, oldVal, oldObj != nil)...) } - { // field ateapipb.SetWorkerSandboxRuntimesRequest.SandboxClasses + { // field v1.SetWorkerSandboxRuntimesRequest.SandboxClasses fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.WorkerSandboxClass, + obj, oldObj []*v1.WorkerSandboxClass, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -7884,7 +7884,7 @@ func Validate_SetWorkerSandboxRuntimesRequest( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.WorkerSandboxClass](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.WorkerSandboxClass](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -7904,22 +7904,18 @@ func Validate_SetWorkerSandboxRuntimesRequest( } // lists with map semantics require unique keys if e := validate.PtrSliceUnique(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.WorkerSandboxClass, b *ateapipb.WorkerSandboxClass) bool { - return a.SandboxClass == b.SandboxClass - }); len(e) != 0 { + func(a *v1.WorkerSandboxClass, b *v1.WorkerSandboxClass) bool { return a.SandboxClass == b.SandboxClass }); len(e) != 0 { errs = append(errs, e...) } // iterate the list and call the type's validation function if e := validate.EachPtrSliceVal(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.WorkerSandboxClass, b *ateapipb.WorkerSandboxClass) bool { - return a.SandboxClass == b.SandboxClass - }, ateDeepEqual, Validate_WorkerSandboxClass); len(e) != 0 { + func(a *v1.WorkerSandboxClass, b *v1.WorkerSandboxClass) bool { return a.SandboxClass == b.SandboxClass }, ateDeepEqual, Validate_WorkerSandboxClass); len(e) != 0 { errs = append(errs, e...) } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SetWorkerSandboxRuntimesRequest) []*ateapipb.WorkerSandboxClass { + func(oldObj *v1.SetWorkerSandboxRuntimesRequest) []*v1.WorkerSandboxClass { return oldObj.SandboxClasses }) errs = append(errs, fn(fldPath.Child("sandbox_classes"), obj.SandboxClasses, oldVal, oldObj != nil)...) @@ -7932,9 +7928,9 @@ func Validate_SetWorkerSandboxRuntimesRequest( // to declarative validation rules in the API schema. func Validate_Snapshot( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.Snapshot) (errs field.ErrorList) { + obj, oldObj *v1.Snapshot) (errs field.ErrorList) { - { // field ateapipb.Snapshot.Uuid + { // field v1.Snapshot.Uuid fn := func( fldPath *field.Path, obj, oldObj *string, @@ -7960,13 +7956,13 @@ func Validate_Snapshot( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Snapshot) *string { + func(oldObj *v1.Snapshot) *string { return &oldObj.Uuid }) errs = append(errs, fn(fldPath.Child("uuid"), &obj.Uuid, oldVal, oldObj != nil)...) } - { // field ateapipb.Snapshot.Generation + { // field v1.Snapshot.Generation fn := func( fldPath *field.Path, obj, oldObj *int32, @@ -7992,16 +7988,16 @@ func Validate_Snapshot( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Snapshot) *int32 { + func(oldObj *v1.Snapshot) *int32 { return &oldObj.Generation }) errs = append(errs, fn(fldPath.Child("generation"), &obj.Generation, oldVal, oldObj != nil)...) } - { // field ateapipb.Snapshot.Owner + { // field v1.Snapshot.Owner fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.SnapshotOwner, + obj, oldObj *v1.SnapshotOwner, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8027,16 +8023,16 @@ func Validate_Snapshot( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Snapshot) *ateapipb.SnapshotOwner { + func(oldObj *v1.Snapshot) *v1.SnapshotOwner { return &oldObj.Owner }) errs = append(errs, fn(fldPath.Child("owner"), &obj.Owner, oldVal, oldObj != nil)...) } - { // field ateapipb.Snapshot.Fidelity + { // field v1.Snapshot.Fidelity fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.SnapshotFidelity, + obj, oldObj *v1.SnapshotFidelity, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8062,13 +8058,13 @@ func Validate_Snapshot( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Snapshot) *ateapipb.SnapshotFidelity { + func(oldObj *v1.Snapshot) *v1.SnapshotFidelity { return &oldObj.Fidelity }) errs = append(errs, fn(fldPath.Child("fidelity"), &obj.Fidelity, oldVal, oldObj != nil)...) } - { // field ateapipb.Snapshot.ActorTemplateUid + { // field v1.Snapshot.ActorTemplateUid fn := func( fldPath *field.Path, obj, oldObj *string, @@ -8093,13 +8089,13 @@ func Validate_Snapshot( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Snapshot) *string { + func(oldObj *v1.Snapshot) *string { return &oldObj.ActorTemplateUid }) errs = append(errs, fn(fldPath.Child("actor_template_uid"), &obj.ActorTemplateUid, oldVal, oldObj != nil)...) } - { // field ateapipb.Snapshot.Locality + { // field v1.Snapshot.Locality fn := func( fldPath *field.Path, obj, oldObj *string, @@ -8124,16 +8120,16 @@ func Validate_Snapshot( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Snapshot) *string { + func(oldObj *v1.Snapshot) *string { return &oldObj.Locality }) errs = append(errs, fn(fldPath.Child("locality"), &obj.Locality, oldVal, oldObj != nil)...) } - { // field ateapipb.Snapshot.DurableSnapshot + { // field v1.Snapshot.DurableSnapshot fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.SnapshotStorage, + obj, oldObj *v1.SnapshotStorage, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8154,16 +8150,16 @@ func Validate_Snapshot( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Snapshot) *ateapipb.SnapshotStorage { + func(oldObj *v1.Snapshot) *v1.SnapshotStorage { return oldObj.DurableSnapshot }) errs = append(errs, fn(fldPath.Child("durable_snapshot"), obj.DurableSnapshot, oldVal, oldObj != nil)...) } - { // field ateapipb.Snapshot.SandboxRuntime + { // field v1.Snapshot.SandboxRuntime fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ActorSandboxRuntime, + obj, oldObj *v1.ActorSandboxRuntime, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8184,7 +8180,7 @@ func Validate_Snapshot( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Snapshot) *ateapipb.ActorSandboxRuntime { + func(oldObj *v1.Snapshot) *v1.ActorSandboxRuntime { return oldObj.SandboxRuntime }) errs = append(errs, fn(fldPath.Child("sandbox_runtime"), obj.SandboxRuntime, oldVal, oldObj != nil)...) @@ -8197,9 +8193,9 @@ func Validate_Snapshot( // to declarative validation rules in the API schema. func Validate_SnapshotConfig( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.SnapshotConfig) (errs field.ErrorList) { + obj, oldObj *v1.SnapshotConfig) (errs field.ErrorList) { - { // field ateapipb.SnapshotConfig.StorageLocation + { // field v1.SnapshotConfig.StorageLocation fn := func( fldPath *field.Path, obj, oldObj *string, @@ -8228,16 +8224,16 @@ func Validate_SnapshotConfig( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SnapshotConfig) *string { + func(oldObj *v1.SnapshotConfig) *string { return &oldObj.StorageLocation }) errs = append(errs, fn(fldPath.Child("storage_location"), &obj.StorageLocation, oldVal, oldObj != nil)...) } - { // field ateapipb.SnapshotConfig.PreferredFidelity + { // field v1.SnapshotConfig.PreferredFidelity fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.SnapshotFidelity, + obj, oldObj *v1.SnapshotFidelity, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8263,16 +8259,16 @@ func Validate_SnapshotConfig( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SnapshotConfig) *ateapipb.SnapshotFidelity { + func(oldObj *v1.SnapshotConfig) *v1.SnapshotFidelity { return &oldObj.PreferredFidelity }) errs = append(errs, fn(fldPath.Child("preferred_fidelity"), &obj.PreferredFidelity, oldVal, oldObj != nil)...) } - { // field ateapipb.SnapshotConfig.GoldenSnapshotConfig + { // field v1.SnapshotConfig.GoldenSnapshotConfig fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.GoldenSnapshotConfig, + obj, oldObj *v1.GoldenSnapshotConfig, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8293,7 +8289,7 @@ func Validate_SnapshotConfig( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SnapshotConfig) *ateapipb.GoldenSnapshotConfig { + func(oldObj *v1.SnapshotConfig) *v1.GoldenSnapshotConfig { return oldObj.GoldenSnapshotConfig }) errs = append(errs, fn(fldPath.Child("golden_snapshot_config"), obj.GoldenSnapshotConfig, oldVal, oldObj != nil)...) @@ -8306,9 +8302,9 @@ func Validate_SnapshotConfig( // to declarative validation rules in the API schema. func Validate_SnapshotReport( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.SnapshotReport) (errs field.ErrorList) { + obj, oldObj *v1.SnapshotReport) (errs field.ErrorList) { - { // field ateapipb.SnapshotReport.Uuid + { // field v1.SnapshotReport.Uuid fn := func( fldPath *field.Path, obj, oldObj *string, @@ -8334,13 +8330,13 @@ func Validate_SnapshotReport( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SnapshotReport) *string { + func(oldObj *v1.SnapshotReport) *string { return &oldObj.Uuid }) errs = append(errs, fn(fldPath.Child("uuid"), &obj.Uuid, oldVal, oldObj != nil)...) } - { // field ateapipb.SnapshotReport.Generation + { // field v1.SnapshotReport.Generation fn := func( fldPath *field.Path, obj, oldObj *int32, @@ -8366,16 +8362,16 @@ func Validate_SnapshotReport( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SnapshotReport) *int32 { + func(oldObj *v1.SnapshotReport) *int32 { return &oldObj.Generation }) errs = append(errs, fn(fldPath.Child("generation"), &obj.Generation, oldVal, oldObj != nil)...) } - { // field ateapipb.SnapshotReport.Fidelity + { // field v1.SnapshotReport.Fidelity fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.SnapshotFidelity, + obj, oldObj *v1.SnapshotFidelity, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8401,16 +8397,16 @@ func Validate_SnapshotReport( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SnapshotReport) *ateapipb.SnapshotFidelity { + func(oldObj *v1.SnapshotReport) *v1.SnapshotFidelity { return &oldObj.Fidelity }) errs = append(errs, fn(fldPath.Child("fidelity"), &obj.Fidelity, oldVal, oldObj != nil)...) } - { // field ateapipb.SnapshotReport.Object + { // field v1.SnapshotReport.Object fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectSnapshot, + obj, oldObj *v1.ObjectSnapshot, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8432,13 +8428,13 @@ func Validate_SnapshotReport( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SnapshotReport) *ateapipb.ObjectSnapshot { + func(oldObj *v1.SnapshotReport) *v1.ObjectSnapshot { return oldObj.Object }) errs = append(errs, fn(fldPath.Child("object"), obj.Object, oldVal, oldObj != nil)...) } - { // field ateapipb.SnapshotReport.LocalCommitTime + { // field v1.SnapshotReport.LocalCommitTime fn := func( fldPath *field.Path, obj, oldObj *timestamppb.Timestamp, @@ -8460,13 +8456,13 @@ func Validate_SnapshotReport( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SnapshotReport) *timestamppb.Timestamp { + func(oldObj *v1.SnapshotReport) *timestamppb.Timestamp { return oldObj.LocalCommitTime }) errs = append(errs, fn(fldPath.Child("local_commit_time"), obj.LocalCommitTime, oldVal, oldObj != nil)...) } - { // field ateapipb.SnapshotReport.DurableCompleteTime + { // field v1.SnapshotReport.DurableCompleteTime fn := func( fldPath *field.Path, obj, oldObj *timestamppb.Timestamp, @@ -8488,7 +8484,7 @@ func Validate_SnapshotReport( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SnapshotReport) *timestamppb.Timestamp { + func(oldObj *v1.SnapshotReport) *timestamppb.Timestamp { return oldObj.DurableCompleteTime }) errs = append(errs, fn(fldPath.Child("durable_complete_time"), obj.DurableCompleteTime, oldVal, oldObj != nil)...) @@ -8501,12 +8497,12 @@ func Validate_SnapshotReport( // to declarative validation rules in the API schema. func Validate_SnapshotStorage( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.SnapshotStorage) (errs field.ErrorList) { + obj, oldObj *v1.SnapshotStorage) (errs field.ErrorList) { - { // field ateapipb.SnapshotStorage.Status + { // field v1.SnapshotStorage.Status fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.SnapshotStorageStatus, + obj, oldObj *v1.SnapshotStorageStatus, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8532,16 +8528,16 @@ func Validate_SnapshotStorage( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SnapshotStorage) *ateapipb.SnapshotStorageStatus { + func(oldObj *v1.SnapshotStorage) *v1.SnapshotStorageStatus { return &oldObj.Status }) errs = append(errs, fn(fldPath.Child("status"), &obj.Status, oldVal, oldObj != nil)...) } - { // field ateapipb.SnapshotStorage.Object + { // field v1.SnapshotStorage.Object fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectSnapshot, + obj, oldObj *v1.ObjectSnapshot, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8563,7 +8559,7 @@ func Validate_SnapshotStorage( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SnapshotStorage) *ateapipb.ObjectSnapshot { + func(oldObj *v1.SnapshotStorage) *v1.ObjectSnapshot { return oldObj.Object }) errs = append(errs, fn(fldPath.Child("object"), obj.Object, oldVal, oldObj != nil)...) @@ -8576,12 +8572,12 @@ func Validate_SnapshotStorage( // to declarative validation rules in the API schema. func Validate_SuspendActorRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.SuspendActorRequest) (errs field.ErrorList) { + obj, oldObj *v1.SuspendActorRequest) (errs field.ErrorList) { - { // field ateapipb.SuspendActorRequest.Actor + { // field v1.SuspendActorRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8601,12 +8597,12 @@ func Validate_SuspendActorRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -8618,16 +8614,16 @@ func Validate_SuspendActorRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SuspendActorRequest) *ateapipb.ObjectRef { + func(oldObj *v1.SuspendActorRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) } - { // field ateapipb.SuspendActorRequest.Options + { // field v1.SuspendActorRequest.Options fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.SuspendOptions, + obj, oldObj *v1.SuspendOptions, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8648,7 +8644,7 @@ func Validate_SuspendActorRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SuspendActorRequest) *ateapipb.SuspendOptions { + func(oldObj *v1.SuspendActorRequest) *v1.SuspendOptions { return oldObj.Options }) errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) @@ -8661,12 +8657,12 @@ func Validate_SuspendActorRequest( // to declarative validation rules in the API schema. func Validate_SuspendOptions( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.SuspendOptions) (errs field.ErrorList) { + obj, oldObj *v1.SuspendOptions) (errs field.ErrorList) { - { // field ateapipb.SuspendOptions.Mode + { // field v1.SuspendOptions.Mode fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.DurabilityMode, + obj, oldObj *v1.DurabilityMode, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8691,7 +8687,7 @@ func Validate_SuspendOptions( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SuspendOptions) *ateapipb.DurabilityMode { + func(oldObj *v1.SuspendOptions) *v1.DurabilityMode { return &oldObj.Mode }) errs = append(errs, fn(fldPath.Child("mode"), &obj.Mode, oldVal, oldObj != nil)...) @@ -8700,22 +8696,22 @@ func Validate_SuspendOptions( return errs } -var unionMembershipFor_go_ate_dev_substrate_pkg_proto_ateapipb_SystemInfoDataSource_ = validate.NewUnionMembership(validate.NewUnionMember("actor_metadata"), validate.NewUnionMember("trust_bundle")) +var unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_SystemInfoDataSource_ = validate.NewUnionMembership(validate.NewUnionMember("actor_metadata"), validate.NewUnionMember("trust_bundle")) // Validate_SystemInfoDataSource validates an instance of SystemInfoDataSource according // to declarative validation rules in the API schema. func Validate_SystemInfoDataSource( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.SystemInfoDataSource) (errs field.ErrorList) { + obj, oldObj *v1.SystemInfoDataSource) (errs field.ErrorList) { - if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_pkg_proto_ateapipb_SystemInfoDataSource_, - func(obj *ateapipb.SystemInfoDataSource) bool { + if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_SystemInfoDataSource_, + func(obj *v1.SystemInfoDataSource) bool { if obj == nil { return false } return obj.ActorMetadata != nil }, - func(obj *ateapipb.SystemInfoDataSource) bool { + func(obj *v1.SystemInfoDataSource) bool { if obj == nil { return false } @@ -8724,10 +8720,10 @@ func Validate_SystemInfoDataSource( errs = append(errs, e...) } - { // field ateapipb.SystemInfoDataSource.ActorMetadata + { // field v1.SystemInfoDataSource.ActorMetadata fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ActorMetadataDataSource, + obj, oldObj *v1.ActorMetadataDataSource, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8748,16 +8744,16 @@ func Validate_SystemInfoDataSource( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SystemInfoDataSource) *ateapipb.ActorMetadataDataSource { + func(oldObj *v1.SystemInfoDataSource) *v1.ActorMetadataDataSource { return oldObj.ActorMetadata }) errs = append(errs, fn(fldPath.Child("actor_metadata"), obj.ActorMetadata, oldVal, oldObj != nil)...) } - { // field ateapipb.SystemInfoDataSource.TrustBundle + { // field v1.SystemInfoDataSource.TrustBundle fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.TrustBundleDataSource, + obj, oldObj *v1.TrustBundleDataSource, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8778,7 +8774,7 @@ func Validate_SystemInfoDataSource( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SystemInfoDataSource) *ateapipb.TrustBundleDataSource { + func(oldObj *v1.SystemInfoDataSource) *v1.TrustBundleDataSource { return oldObj.TrustBundle }) errs = append(errs, fn(fldPath.Child("trust_bundle"), obj.TrustBundle, oldVal, oldObj != nil)...) @@ -8791,12 +8787,12 @@ func Validate_SystemInfoDataSource( // to declarative validation rules in the API schema. func Validate_SystemInfoVolumeSource( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.SystemInfoVolumeSource) (errs field.ErrorList) { + obj, oldObj *v1.SystemInfoVolumeSource) (errs field.ErrorList) { - { // field ateapipb.SystemInfoVolumeSource.DataSources + { // field v1.SystemInfoVolumeSource.DataSources fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.SystemInfoDataSource, + obj, oldObj []*v1.SystemInfoDataSource, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8806,7 +8802,7 @@ func Validate_SystemInfoVolumeSource( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.SystemInfoDataSource](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.SystemInfoDataSource](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -8831,7 +8827,7 @@ func Validate_SystemInfoVolumeSource( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.SystemInfoVolumeSource) []*ateapipb.SystemInfoDataSource { + func(oldObj *v1.SystemInfoVolumeSource) []*v1.SystemInfoDataSource { return oldObj.DataSources }) errs = append(errs, fn(fldPath.Child("data_sources"), obj.DataSources, oldVal, oldObj != nil)...) @@ -8844,12 +8840,12 @@ func Validate_SystemInfoVolumeSource( // to declarative validation rules in the API schema. func Validate_Tag( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.Tag) (errs field.ErrorList) { + obj, oldObj *v1.Tag) (errs field.ErrorList) { - { // field ateapipb.Tag.Metadata + { // field v1.Tag.Metadata fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ResourceMetadata, + obj, oldObj *v1.ResourceMetadata, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8869,16 +8865,16 @@ func Validate_Tag( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.Immutable).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.Immutable).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -8890,16 +8886,16 @@ func Validate_Tag( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Tag) *ateapipb.ResourceMetadata { + func(oldObj *v1.Tag) *v1.ResourceMetadata { return oldObj.Metadata }) errs = append(errs, fn(fldPath.Child("metadata"), obj.Metadata, oldVal, oldObj != nil)...) } - { // field ateapipb.Tag.Status + { // field v1.Tag.Status fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.TagStatus, + obj, oldObj *v1.TagStatus, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8920,16 +8916,16 @@ func Validate_Tag( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Tag) *ateapipb.TagStatus { + func(oldObj *v1.Tag) *v1.TagStatus { return oldObj.Status }) errs = append(errs, fn(fldPath.Child("status"), obj.Status, oldVal, oldObj != nil)...) } - { // field ateapipb.Tag.Scope + { // field v1.Tag.Scope fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.TagScope, + obj, oldObj *v1.TagScope, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8955,16 +8951,16 @@ func Validate_Tag( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Tag) *ateapipb.TagScope { + func(oldObj *v1.Tag) *v1.TagScope { return &oldObj.Scope }) errs = append(errs, fn(fldPath.Child("scope"), &obj.Scope, oldVal, oldObj != nil)...) } - { // field ateapipb.Tag.SourceActor + { // field v1.Tag.SourceActor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -8988,12 +8984,12 @@ func Validate_Tag( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -9005,7 +9001,7 @@ func Validate_Tag( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Tag) *ateapipb.ObjectRef { + func(oldObj *v1.Tag) *v1.ObjectRef { return oldObj.SourceActor }) errs = append(errs, fn(fldPath.Child("source_actor"), obj.SourceActor, oldVal, oldObj != nil)...) @@ -9018,12 +9014,12 @@ func Validate_Tag( // to declarative validation rules in the API schema. func Validate_TagStatus( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.TagStatus) (errs field.ErrorList) { + obj, oldObj *v1.TagStatus) (errs field.ErrorList) { - { // field ateapipb.TagStatus.Snapshot + { // field v1.TagStatus.Snapshot fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Snapshot, + obj, oldObj *v1.Snapshot, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9042,12 +9038,12 @@ func Validate_TagStatus( func() { // cohort = "durable_snapshot" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "durable_snapshot", - func(o *ateapipb.Snapshot) *ateapipb.SnapshotStorage { return o.DurableSnapshot }, ateDeepEqual, validate.RequiredPointer).MarkShortCircuit(); len(e) != 0 { + func(o *v1.Snapshot) *v1.SnapshotStorage { return o.DurableSnapshot }, ateDeepEqual, validate.RequiredPointer).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "durable_snapshot", - func(o *ateapipb.Snapshot) *ateapipb.SnapshotStorage { return o.DurableSnapshot }, ateDeepEqual, validate.OptionalPointer).MarkShortCircuit(); len(e) != 0 { + func(o *v1.Snapshot) *v1.SnapshotStorage { return o.DurableSnapshot }, ateDeepEqual, validate.OptionalPointer).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -9059,13 +9055,13 @@ func Validate_TagStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.TagStatus) *ateapipb.Snapshot { + func(oldObj *v1.TagStatus) *v1.Snapshot { return oldObj.Snapshot }) errs = append(errs, fn(fldPath.Child("snapshot"), obj.Snapshot, oldVal, oldObj != nil)...) } - { // field ateapipb.TagStatus.ActorTemplateUid + { // field v1.TagStatus.ActorTemplateUid fn := func( fldPath *field.Path, obj, oldObj *string, @@ -9091,7 +9087,7 @@ func Validate_TagStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.TagStatus) *string { + func(oldObj *v1.TagStatus) *string { return &oldObj.ActorTemplateUid }) errs = append(errs, fn(fldPath.Child("actor_template_uid"), &obj.ActorTemplateUid, oldVal, oldObj != nil)...) @@ -9104,9 +9100,9 @@ func Validate_TagStatus( // to declarative validation rules in the API schema. func Validate_TlsPassthroughRule( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.TlsPassthroughRule) (errs field.ErrorList) { + obj, oldObj *v1.TlsPassthroughRule) (errs field.ErrorList) { - { // field ateapipb.TlsPassthroughRule.Hostnames + { // field v1.TlsPassthroughRule.Hostnames fn := func( fldPath *field.Path, obj, oldObj []string, @@ -9141,16 +9137,16 @@ func Validate_TlsPassthroughRule( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.TlsPassthroughRule) []string { + func(oldObj *v1.TlsPassthroughRule) []string { return oldObj.Hostnames }) errs = append(errs, fn(fldPath.Child("hostnames"), obj.Hostnames, oldVal, oldObj != nil)...) } - { // field ateapipb.TlsPassthroughRule.Ports + { // field v1.TlsPassthroughRule.Ports fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Ports, + obj, oldObj *v1.Ports, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9172,7 +9168,7 @@ func Validate_TlsPassthroughRule( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.TlsPassthroughRule) *ateapipb.Ports { + func(oldObj *v1.TlsPassthroughRule) *v1.Ports { return oldObj.Ports }) errs = append(errs, fn(fldPath.Child("ports"), obj.Ports, oldVal, oldObj != nil)...) @@ -9185,9 +9181,9 @@ func Validate_TlsPassthroughRule( // to declarative validation rules in the API schema. func Validate_TrustBundleDataSource( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.TrustBundleDataSource) (errs field.ErrorList) { + obj, oldObj *v1.TrustBundleDataSource) (errs field.ErrorList) { - { // field ateapipb.TrustBundleDataSource.Names + { // field v1.TrustBundleDataSource.Names fn := func( fldPath *field.Path, obj, oldObj []string, @@ -9233,13 +9229,13 @@ func Validate_TrustBundleDataSource( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.TrustBundleDataSource) []string { + func(oldObj *v1.TrustBundleDataSource) []string { return oldObj.Names }) errs = append(errs, fn(fldPath.Child("names"), obj.Names, oldVal, oldObj != nil)...) } - { // field ateapipb.TrustBundleDataSource.Path + { // field v1.TrustBundleDataSource.Path fn := func( fldPath *field.Path, obj, oldObj *string, @@ -9272,7 +9268,7 @@ func Validate_TrustBundleDataSource( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.TrustBundleDataSource) *string { + func(oldObj *v1.TrustBundleDataSource) *string { return &oldObj.Path }) errs = append(errs, fn(fldPath.Child("path"), &obj.Path, oldVal, oldObj != nil)...) @@ -9285,17 +9281,17 @@ func Validate_TrustBundleDataSource( // to declarative validation rules in the API schema. func Validate_UpdateActorEgressPolicyRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.UpdateActorEgressPolicyRequest) (errs field.ErrorList) { + obj, oldObj *v1.UpdateActorEgressPolicyRequest) (errs field.ErrorList) { // custom validation if e := ValidateCustom_UpdateActorEgressPolicyRequest(ctx, op, fldPath, obj, oldObj); len(e) != 0 { errs = append(errs, e...) } - { // field ateapipb.UpdateActorEgressPolicyRequest.Actor + { // field v1.UpdateActorEgressPolicyRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9315,12 +9311,12 @@ func Validate_UpdateActorEgressPolicyRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.RequiredValue).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -9332,16 +9328,16 @@ func Validate_UpdateActorEgressPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.UpdateActorEgressPolicyRequest) *ateapipb.ObjectRef { + func(oldObj *v1.UpdateActorEgressPolicyRequest) *v1.ObjectRef { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) } - { // field ateapipb.UpdateActorEgressPolicyRequest.EgressPolicy + { // field v1.UpdateActorEgressPolicyRequest.EgressPolicy fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.EgressPolicy, + obj, oldObj *v1.EgressPolicy, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9363,7 +9359,7 @@ func Validate_UpdateActorEgressPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.UpdateActorEgressPolicyRequest) *ateapipb.EgressPolicy { + func(oldObj *v1.UpdateActorEgressPolicyRequest) *v1.EgressPolicy { return oldObj.EgressPolicy }) errs = append(errs, fn(fldPath.Child("egress_policy"), obj.EgressPolicy, oldVal, oldObj != nil)...) @@ -9376,12 +9372,12 @@ func Validate_UpdateActorEgressPolicyRequest( // to declarative validation rules in the API schema. func Validate_UpdateActorRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.UpdateActorRequest) (errs field.ErrorList) { + obj, oldObj *v1.UpdateActorRequest) (errs field.ErrorList) { - { // field ateapipb.UpdateActorRequest.Actor + { // field v1.UpdateActorRequest.Actor fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Actor, + obj, oldObj *v1.Actor, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9405,7 +9401,7 @@ func Validate_UpdateActorRequest( func() { // cohort = "metadata" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "metadata", - func(o *ateapipb.Actor) *ateapipb.ResourceMetadata { return o.Metadata }, ateDeepEqual, validate.RequiredPointer).MarkShortCircuit(); len(e) != 0 { + func(o *v1.Actor) *v1.ResourceMetadata { return o.Metadata }, ateDeepEqual, validate.RequiredPointer).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -9416,7 +9412,7 @@ func Validate_UpdateActorRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.UpdateActorRequest) *ateapipb.Actor { + func(oldObj *v1.UpdateActorRequest) *v1.Actor { return oldObj.Actor }) errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) @@ -9429,12 +9425,12 @@ func Validate_UpdateActorRequest( // to declarative validation rules in the API schema. func Validate_UpdateAtespaceAccessPolicyRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.UpdateAtespaceAccessPolicyRequest) (errs field.ErrorList) { + obj, oldObj *v1.UpdateAtespaceAccessPolicyRequest) (errs field.ErrorList) { - { // field ateapipb.UpdateAtespaceAccessPolicyRequest.Atespace + { // field v1.UpdateAtespaceAccessPolicyRequest.Atespace fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9454,16 +9450,16 @@ func Validate_UpdateAtespaceAccessPolicyRequest( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -9475,16 +9471,16 @@ func Validate_UpdateAtespaceAccessPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.UpdateAtespaceAccessPolicyRequest) *ateapipb.ObjectRef { + func(oldObj *v1.UpdateAtespaceAccessPolicyRequest) *v1.ObjectRef { return oldObj.Atespace }) errs = append(errs, fn(fldPath.Child("atespace"), obj.Atespace, oldVal, oldObj != nil)...) } - { // field ateapipb.UpdateAtespaceAccessPolicyRequest.AccessPolicy + { // field v1.UpdateAtespaceAccessPolicyRequest.AccessPolicy fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.AccessPolicy, + obj, oldObj *v1.AccessPolicy, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9506,7 +9502,7 @@ func Validate_UpdateAtespaceAccessPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.UpdateAtespaceAccessPolicyRequest) *ateapipb.AccessPolicy { + func(oldObj *v1.UpdateAtespaceAccessPolicyRequest) *v1.AccessPolicy { return oldObj.AccessPolicy }) errs = append(errs, fn(fldPath.Child("access_policy"), obj.AccessPolicy, oldVal, oldObj != nil)...) @@ -9519,12 +9515,12 @@ func Validate_UpdateAtespaceAccessPolicyRequest( // to declarative validation rules in the API schema. func Validate_UpdateGlobalAccessPolicyRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.UpdateGlobalAccessPolicyRequest) (errs field.ErrorList) { + obj, oldObj *v1.UpdateGlobalAccessPolicyRequest) (errs field.ErrorList) { - { // field ateapipb.UpdateGlobalAccessPolicyRequest.AccessPolicy + { // field v1.UpdateGlobalAccessPolicyRequest.AccessPolicy fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.AccessPolicy, + obj, oldObj *v1.AccessPolicy, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9546,7 +9542,7 @@ func Validate_UpdateGlobalAccessPolicyRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.UpdateGlobalAccessPolicyRequest) *ateapipb.AccessPolicy { + func(oldObj *v1.UpdateGlobalAccessPolicyRequest) *v1.AccessPolicy { return oldObj.AccessPolicy }) errs = append(errs, fn(fldPath.Child("access_policy"), obj.AccessPolicy, oldVal, oldObj != nil)...) @@ -9559,12 +9555,12 @@ func Validate_UpdateGlobalAccessPolicyRequest( // to declarative validation rules in the API schema. func Validate_UpdateTagRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.UpdateTagRequest) (errs field.ErrorList) { + obj, oldObj *v1.UpdateTagRequest) (errs field.ErrorList) { - { // field ateapipb.UpdateTagRequest.Tag + { // field v1.UpdateTagRequest.Tag fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Tag, + obj, oldObj *v1.Tag, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9588,7 +9584,7 @@ func Validate_UpdateTagRequest( func() { // cohort = "metadata" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "metadata", - func(o *ateapipb.Tag) *ateapipb.ResourceMetadata { return o.Metadata }, ateDeepEqual, validate.RequiredPointer).MarkShortCircuit(); len(e) != 0 { + func(o *v1.Tag) *v1.ResourceMetadata { return o.Metadata }, ateDeepEqual, validate.RequiredPointer).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -9599,7 +9595,7 @@ func Validate_UpdateTagRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.UpdateTagRequest) *ateapipb.Tag { + func(oldObj *v1.UpdateTagRequest) *v1.Tag { return oldObj.Tag }) errs = append(errs, fn(fldPath.Child("tag"), obj.Tag, oldVal, oldObj != nil)...) @@ -9612,12 +9608,12 @@ func Validate_UpdateTagRequest( // to declarative validation rules in the API schema. func Validate_UpdateWorkerRequest( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.UpdateWorkerRequest) (errs field.ErrorList) { + obj, oldObj *v1.UpdateWorkerRequest) (errs field.ErrorList) { - { // field ateapipb.UpdateWorkerRequest.Worker + { // field v1.UpdateWorkerRequest.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.Worker, + obj, oldObj *v1.Worker, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9641,7 +9637,7 @@ func Validate_UpdateWorkerRequest( func() { // cohort = "metadata" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "metadata", - func(o *ateapipb.Worker) *ateapipb.ResourceMetadata { return o.Metadata }, ateDeepEqual, validate.RequiredPointer).MarkShortCircuit(); len(e) != 0 { + func(o *v1.Worker) *v1.ResourceMetadata { return o.Metadata }, ateDeepEqual, validate.RequiredPointer).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -9652,7 +9648,7 @@ func Validate_UpdateWorkerRequest( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.UpdateWorkerRequest) *ateapipb.Worker { + func(oldObj *v1.UpdateWorkerRequest) *v1.Worker { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) @@ -9665,9 +9661,9 @@ func Validate_UpdateWorkerRequest( // to declarative validation rules in the API schema. func Validate_VersionedSandboxCompat( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.VersionedSandboxCompat) (errs field.ErrorList) { + obj, oldObj *v1.VersionedSandboxCompat) (errs field.ErrorList) { - { // field ateapipb.VersionedSandboxCompat.SchemaVersion + { // field v1.VersionedSandboxCompat.SchemaVersion fn := func( fldPath *field.Path, obj, oldObj *string, @@ -9693,16 +9689,16 @@ func Validate_VersionedSandboxCompat( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.VersionedSandboxCompat) *string { + func(oldObj *v1.VersionedSandboxCompat) *string { return &oldObj.SchemaVersion }) errs = append(errs, fn(fldPath.Child("schema_version"), &obj.SchemaVersion, oldVal, oldObj != nil)...) } - { // field ateapipb.VersionedSandboxCompat.Attributes + { // field v1.VersionedSandboxCompat.Attributes fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.AttributeEntry, + obj, oldObj []*v1.AttributeEntry, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9712,7 +9708,7 @@ func Validate_VersionedSandboxCompat( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.AttributeEntry](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.AttributeEntry](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -9729,18 +9725,18 @@ func Validate_VersionedSandboxCompat( } // lists with map semantics require unique keys if e := validate.PtrSliceUnique(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.AttributeEntry, b *ateapipb.AttributeEntry) bool { return a.Key == b.Key }); len(e) != 0 { + func(a *v1.AttributeEntry, b *v1.AttributeEntry) bool { return a.Key == b.Key }); len(e) != 0 { errs = append(errs, e...) } // iterate the list and call the type's validation function if e := validate.EachPtrSliceVal(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.AttributeEntry, b *ateapipb.AttributeEntry) bool { return a.Key == b.Key }, ateDeepEqual, Validate_AttributeEntry); len(e) != 0 { + func(a *v1.AttributeEntry, b *v1.AttributeEntry) bool { return a.Key == b.Key }, ateDeepEqual, Validate_AttributeEntry); len(e) != 0 { errs = append(errs, e...) } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.VersionedSandboxCompat) []*ateapipb.AttributeEntry { + func(oldObj *v1.VersionedSandboxCompat) []*v1.AttributeEntry { return oldObj.Attributes }) errs = append(errs, fn(fldPath.Child("attributes"), obj.Attributes, oldVal, oldObj != nil)...) @@ -9749,34 +9745,34 @@ func Validate_VersionedSandboxCompat( return errs } -var unionMembershipFor_go_ate_dev_substrate_pkg_proto_ateapipb_Volume_ = validate.NewUnionMembership(validate.NewUnionMember("durable_dir"), validate.NewUnionMember("external"), validate.NewUnionMember("system_info"), validate.NewUnionMember("image")) +var unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_Volume_ = validate.NewUnionMembership(validate.NewUnionMember("durable_dir"), validate.NewUnionMember("external"), validate.NewUnionMember("system_info"), validate.NewUnionMember("image")) // Validate_Volume validates an instance of Volume according // to declarative validation rules in the API schema. func Validate_Volume( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.Volume) (errs field.ErrorList) { + obj, oldObj *v1.Volume) (errs field.ErrorList) { - if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_pkg_proto_ateapipb_Volume_, - func(obj *ateapipb.Volume) bool { + if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_Volume_, + func(obj *v1.Volume) bool { if obj == nil { return false } return obj.DurableDir != nil }, - func(obj *ateapipb.Volume) bool { + func(obj *v1.Volume) bool { if obj == nil { return false } return obj.External != nil }, - func(obj *ateapipb.Volume) bool { + func(obj *v1.Volume) bool { if obj == nil { return false } return obj.SystemInfo != nil }, - func(obj *ateapipb.Volume) bool { + func(obj *v1.Volume) bool { if obj == nil { return false } @@ -9785,7 +9781,7 @@ func Validate_Volume( errs = append(errs, e...) } - { // field ateapipb.Volume.Name + { // field v1.Volume.Name fn := func( fldPath *field.Path, obj, oldObj *string, @@ -9811,16 +9807,16 @@ func Validate_Volume( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Volume) *string { + func(oldObj *v1.Volume) *string { return &oldObj.Name }) errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) } - { // field ateapipb.Volume.DurableDir + { // field v1.Volume.DurableDir fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.DurableDirVolumeSource, + obj, oldObj *v1.DurableDirVolumeSource, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9839,16 +9835,16 @@ func Validate_Volume( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Volume) *ateapipb.DurableDirVolumeSource { + func(oldObj *v1.Volume) *v1.DurableDirVolumeSource { return oldObj.DurableDir }) errs = append(errs, fn(fldPath.Child("durable_dir"), obj.DurableDir, oldVal, oldObj != nil)...) } - { // field ateapipb.Volume.External + { // field v1.Volume.External fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ExternalVolumeSource, + obj, oldObj *v1.ExternalVolumeSource, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9876,16 +9872,16 @@ func Validate_Volume( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Volume) *ateapipb.ExternalVolumeSource { + func(oldObj *v1.Volume) *v1.ExternalVolumeSource { return oldObj.External }) errs = append(errs, fn(fldPath.Child("external"), obj.External, oldVal, oldObj != nil)...) } - { // field ateapipb.Volume.SystemInfo + { // field v1.Volume.SystemInfo fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.SystemInfoVolumeSource, + obj, oldObj *v1.SystemInfoVolumeSource, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9906,16 +9902,16 @@ func Validate_Volume( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Volume) *ateapipb.SystemInfoVolumeSource { + func(oldObj *v1.Volume) *v1.SystemInfoVolumeSource { return oldObj.SystemInfo }) errs = append(errs, fn(fldPath.Child("system_info"), obj.SystemInfo, oldVal, oldObj != nil)...) } - { // field ateapipb.Volume.Image + { // field v1.Volume.Image fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ImageVolumeSource, + obj, oldObj *v1.ImageVolumeSource, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -9936,7 +9932,7 @@ func Validate_Volume( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Volume) *ateapipb.ImageVolumeSource { + func(oldObj *v1.Volume) *v1.ImageVolumeSource { return oldObj.Image }) errs = append(errs, fn(fldPath.Child("image"), obj.Image, oldVal, oldObj != nil)...) @@ -9949,9 +9945,9 @@ func Validate_Volume( // to declarative validation rules in the API schema. func Validate_VolumeMount( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.VolumeMount) (errs field.ErrorList) { + obj, oldObj *v1.VolumeMount) (errs field.ErrorList) { - { // field ateapipb.VolumeMount.Name + { // field v1.VolumeMount.Name fn := func( fldPath *field.Path, obj, oldObj *string, @@ -9977,13 +9973,13 @@ func Validate_VolumeMount( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.VolumeMount) *string { + func(oldObj *v1.VolumeMount) *string { return &oldObj.Name }) errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) } - { // field ateapipb.VolumeMount.MountPath + { // field v1.VolumeMount.MountPath fn := func( fldPath *field.Path, obj, oldObj *string, @@ -10013,7 +10009,7 @@ func Validate_VolumeMount( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.VolumeMount) *string { + func(oldObj *v1.VolumeMount) *string { return &oldObj.MountPath }) errs = append(errs, fn(fldPath.Child("mount_path"), &obj.MountPath, oldVal, oldObj != nil)...) @@ -10026,12 +10022,12 @@ func Validate_VolumeMount( // to declarative validation rules in the API schema. func Validate_WakeupProbe( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.WakeupProbe) (errs field.ErrorList) { + obj, oldObj *v1.WakeupProbe) (errs field.ErrorList) { - { // field ateapipb.WakeupProbe.HttpGet + { // field v1.WakeupProbe.HttpGet fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.HttpGetAction, + obj, oldObj *v1.HttpGetAction, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -10053,13 +10049,13 @@ func Validate_WakeupProbe( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WakeupProbe) *ateapipb.HttpGetAction { + func(oldObj *v1.WakeupProbe) *v1.HttpGetAction { return oldObj.HttpGet }) errs = append(errs, fn(fldPath.Child("http_get"), obj.HttpGet, oldVal, oldObj != nil)...) } - { // field ateapipb.WakeupProbe.TimeoutSeconds + { // field v1.WakeupProbe.TimeoutSeconds fn := func( fldPath *field.Path, obj, oldObj *int32, @@ -10088,7 +10084,7 @@ func Validate_WakeupProbe( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WakeupProbe) *int32 { + func(oldObj *v1.WakeupProbe) *int32 { return &oldObj.TimeoutSeconds }) errs = append(errs, fn(fldPath.Child("timeout_seconds"), &obj.TimeoutSeconds, oldVal, oldObj != nil)...) @@ -10101,12 +10097,12 @@ func Validate_WakeupProbe( // to declarative validation rules in the API schema. func Validate_Worker( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.Worker) (errs field.ErrorList) { + obj, oldObj *v1.Worker) (errs field.ErrorList) { - { // field ateapipb.Worker.Metadata + { // field v1.Worker.Metadata fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ResourceMetadata, + obj, oldObj *v1.ResourceMetadata, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -10126,20 +10122,20 @@ func Validate_Worker( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.Immutable).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.Immutable).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -10151,13 +10147,13 @@ func Validate_Worker( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Worker) *ateapipb.ResourceMetadata { + func(oldObj *v1.Worker) *v1.ResourceMetadata { return oldObj.Metadata }) errs = append(errs, fn(fldPath.Child("metadata"), obj.Metadata, oldVal, oldObj != nil)...) } - { // field ateapipb.Worker.WorkerNamespace + { // field v1.Worker.WorkerNamespace fn := func( fldPath *field.Path, obj, oldObj *string, @@ -10187,13 +10183,13 @@ func Validate_Worker( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Worker) *string { + func(oldObj *v1.Worker) *string { return &oldObj.WorkerNamespace }) errs = append(errs, fn(fldPath.Child("worker_namespace"), &obj.WorkerNamespace, oldVal, oldObj != nil)...) } - { // field ateapipb.Worker.WorkerPool + { // field v1.Worker.WorkerPool fn := func( fldPath *field.Path, obj, oldObj *string, @@ -10223,13 +10219,13 @@ func Validate_Worker( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Worker) *string { + func(oldObj *v1.Worker) *string { return &oldObj.WorkerPool }) errs = append(errs, fn(fldPath.Child("worker_pool"), &obj.WorkerPool, oldVal, oldObj != nil)...) } - { // field ateapipb.Worker.WorkerPod + { // field v1.Worker.WorkerPod fn := func( fldPath *field.Path, obj, oldObj *string, @@ -10259,13 +10255,13 @@ func Validate_Worker( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Worker) *string { + func(oldObj *v1.Worker) *string { return &oldObj.WorkerPod }) errs = append(errs, fn(fldPath.Child("worker_pod"), &obj.WorkerPod, oldVal, oldObj != nil)...) } - { // field ateapipb.Worker.WorkerPodUid + { // field v1.Worker.WorkerPodUid fn := func( fldPath *field.Path, obj, oldObj *string, @@ -10295,13 +10291,13 @@ func Validate_Worker( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Worker) *string { + func(oldObj *v1.Worker) *string { return &oldObj.WorkerPodUid }) errs = append(errs, fn(fldPath.Child("worker_pod_uid"), &obj.WorkerPodUid, oldVal, oldObj != nil)...) } - { // field ateapipb.Worker.NodeName + { // field v1.Worker.NodeName fn := func( fldPath *field.Path, obj, oldObj *string, @@ -10331,13 +10327,13 @@ func Validate_Worker( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Worker) *string { + func(oldObj *v1.Worker) *string { return &oldObj.NodeName }) errs = append(errs, fn(fldPath.Child("node_name"), &obj.NodeName, oldVal, oldObj != nil)...) } - { // field ateapipb.Worker.WorkerSpiffeId + { // field v1.Worker.WorkerSpiffeId fn := func( fldPath *field.Path, obj, oldObj *string, @@ -10370,13 +10366,13 @@ func Validate_Worker( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Worker) *string { + func(oldObj *v1.Worker) *string { return &oldObj.WorkerSpiffeId }) errs = append(errs, fn(fldPath.Child("worker_spiffe_id"), &obj.WorkerSpiffeId, oldVal, oldObj != nil)...) } - { // field ateapipb.Worker.Labels + { // field v1.Worker.Labels fn := func( fldPath *field.Path, obj, oldObj map[string]string, @@ -10408,16 +10404,16 @@ func Validate_Worker( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Worker) map[string]string { + func(oldObj *v1.Worker) map[string]string { return oldObj.Labels }) errs = append(errs, fn(fldPath.Child("labels"), obj.Labels, oldVal, oldObj != nil)...) } - { // field ateapipb.Worker.Status + { // field v1.Worker.Status fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.WorkerStatus, + obj, oldObj *v1.WorkerStatus, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -10438,7 +10434,7 @@ func Validate_Worker( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.Worker) *ateapipb.WorkerStatus { + func(oldObj *v1.Worker) *v1.WorkerStatus { return oldObj.Status }) errs = append(errs, fn(fldPath.Child("status"), obj.Status, oldVal, oldObj != nil)...) @@ -10451,12 +10447,12 @@ func Validate_Worker( // to declarative validation rules in the API schema. func Validate_WorkerAssignment( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.WorkerAssignment) (errs field.ErrorList) { + obj, oldObj *v1.WorkerAssignment) (errs field.ErrorList) { - { // field ateapipb.WorkerAssignment.Worker + { // field v1.WorkerAssignment.Worker fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ObjectRef, + obj, oldObj *v1.ObjectRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -10480,16 +10476,16 @@ func Validate_WorkerAssignment( func() { // cohort = "atespace" earlyReturn := false if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", - func(o *ateapipb.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -10501,13 +10497,13 @@ func Validate_WorkerAssignment( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerAssignment) *ateapipb.ObjectRef { + func(oldObj *v1.WorkerAssignment) *v1.ObjectRef { return oldObj.Worker }) errs = append(errs, fn(fldPath.Child("worker"), obj.Worker, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerAssignment.WorkerNamespace + { // field v1.WorkerAssignment.WorkerNamespace fn := func( fldPath *field.Path, obj, oldObj *string, @@ -10538,13 +10534,13 @@ func Validate_WorkerAssignment( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerAssignment) *string { + func(oldObj *v1.WorkerAssignment) *string { return &oldObj.WorkerNamespace }) errs = append(errs, fn(fldPath.Child("worker_namespace"), &obj.WorkerNamespace, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerAssignment.WorkerPool + { // field v1.WorkerAssignment.WorkerPool fn := func( fldPath *field.Path, obj, oldObj *string, @@ -10575,13 +10571,13 @@ func Validate_WorkerAssignment( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerAssignment) *string { + func(oldObj *v1.WorkerAssignment) *string { return &oldObj.WorkerPool }) errs = append(errs, fn(fldPath.Child("worker_pool"), &obj.WorkerPool, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerAssignment.WorkerPod + { // field v1.WorkerAssignment.WorkerPod fn := func( fldPath *field.Path, obj, oldObj *string, @@ -10612,13 +10608,13 @@ func Validate_WorkerAssignment( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerAssignment) *string { + func(oldObj *v1.WorkerAssignment) *string { return &oldObj.WorkerPod }) errs = append(errs, fn(fldPath.Child("worker_pod"), &obj.WorkerPod, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerAssignment.WorkerPodUid + { // field v1.WorkerAssignment.WorkerPodUid fn := func( fldPath *field.Path, obj, oldObj *string, @@ -10649,13 +10645,13 @@ func Validate_WorkerAssignment( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerAssignment) *string { + func(oldObj *v1.WorkerAssignment) *string { return &oldObj.WorkerPodUid }) errs = append(errs, fn(fldPath.Child("worker_pod_uid"), &obj.WorkerPodUid, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerAssignment.WorkerPodIps + { // field v1.WorkerAssignment.WorkerPodIps fn := func( fldPath *field.Path, obj, oldObj []string, @@ -10686,13 +10682,13 @@ func Validate_WorkerAssignment( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerAssignment) []string { + func(oldObj *v1.WorkerAssignment) []string { return oldObj.WorkerPodIps }) errs = append(errs, fn(fldPath.Child("worker_pod_ips"), obj.WorkerPodIps, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerAssignment.NodeName + { // field v1.WorkerAssignment.NodeName fn := func( fldPath *field.Path, obj, oldObj *string, @@ -10723,13 +10719,13 @@ func Validate_WorkerAssignment( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerAssignment) *string { + func(oldObj *v1.WorkerAssignment) *string { return &oldObj.NodeName }) errs = append(errs, fn(fldPath.Child("node_name"), &obj.NodeName, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerAssignment.WorkerEpoch + { // field v1.WorkerAssignment.WorkerEpoch fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -10754,16 +10750,16 @@ func Validate_WorkerAssignment( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerAssignment) *int64 { + func(oldObj *v1.WorkerAssignment) *int64 { return &oldObj.WorkerEpoch }) errs = append(errs, fn(fldPath.Child("worker_epoch"), &obj.WorkerEpoch, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerAssignment.SandboxRuntime + { // field v1.WorkerAssignment.SandboxRuntime fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.ActorSandboxRuntime, + obj, oldObj *v1.ActorSandboxRuntime, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -10788,13 +10784,13 @@ func Validate_WorkerAssignment( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerAssignment) *ateapipb.ActorSandboxRuntime { + func(oldObj *v1.WorkerAssignment) *v1.ActorSandboxRuntime { return oldObj.SandboxRuntime }) errs = append(errs, fn(fldPath.Child("sandbox_runtime"), obj.SandboxRuntime, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerAssignment.WorkerSpiffeId + { // field v1.WorkerAssignment.WorkerSpiffeId fn := func( fldPath *field.Path, obj, oldObj *string, @@ -10828,7 +10824,7 @@ func Validate_WorkerAssignment( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerAssignment) *string { + func(oldObj *v1.WorkerAssignment) *string { return &oldObj.WorkerSpiffeId }) errs = append(errs, fn(fldPath.Child("worker_spiffe_id"), &obj.WorkerSpiffeId, oldVal, oldObj != nil)...) @@ -10841,9 +10837,9 @@ func Validate_WorkerAssignment( // to declarative validation rules in the API schema. func Validate_WorkerResources( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.WorkerResources) (errs field.ErrorList) { + obj, oldObj *v1.WorkerResources) (errs field.ErrorList) { - { // field ateapipb.WorkerResources.CpuMillicores + { // field v1.WorkerResources.CpuMillicores fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -10871,13 +10867,13 @@ func Validate_WorkerResources( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerResources) *int64 { + func(oldObj *v1.WorkerResources) *int64 { return &oldObj.CpuMillicores }) errs = append(errs, fn(fldPath.Child("cpu_millicores"), &obj.CpuMillicores, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerResources.MemoryBytes + { // field v1.WorkerResources.MemoryBytes fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -10902,13 +10898,13 @@ func Validate_WorkerResources( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerResources) *int64 { + func(oldObj *v1.WorkerResources) *int64 { return &oldObj.MemoryBytes }) errs = append(errs, fn(fldPath.Child("memory_bytes"), &obj.MemoryBytes, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerResources.Actors + { // field v1.WorkerResources.Actors fn := func( fldPath *field.Path, obj, oldObj *int32, @@ -10933,7 +10929,7 @@ func Validate_WorkerResources( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerResources) *int32 { + func(oldObj *v1.WorkerResources) *int32 { return &oldObj.Actors }) errs = append(errs, fn(fldPath.Child("actors"), &obj.Actors, oldVal, oldObj != nil)...) @@ -10946,9 +10942,9 @@ func Validate_WorkerResources( // to declarative validation rules in the API schema. func Validate_WorkerSandboxClass( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.WorkerSandboxClass) (errs field.ErrorList) { + obj, oldObj *v1.WorkerSandboxClass) (errs field.ErrorList) { - { // field ateapipb.WorkerSandboxClass.SandboxClass + { // field v1.WorkerSandboxClass.SandboxClass fn := func( fldPath *field.Path, obj, oldObj *string, @@ -10978,16 +10974,16 @@ func Validate_WorkerSandboxClass( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerSandboxClass) *string { + func(oldObj *v1.WorkerSandboxClass) *string { return &oldObj.SandboxClass }) errs = append(errs, fn(fldPath.Child("sandbox_class"), &obj.SandboxClass, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerSandboxClass.DefaultRuntime + { // field v1.WorkerSandboxClass.DefaultRuntime fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.WorkerSandboxRuntime, + obj, oldObj *v1.WorkerSandboxRuntime, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -11009,16 +11005,16 @@ func Validate_WorkerSandboxClass( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerSandboxClass) *ateapipb.WorkerSandboxRuntime { + func(oldObj *v1.WorkerSandboxClass) *v1.WorkerSandboxRuntime { return oldObj.DefaultRuntime }) errs = append(errs, fn(fldPath.Child("default_runtime"), obj.DefaultRuntime, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerSandboxClass.RestorableRuntimes + { // field v1.WorkerSandboxClass.RestorableRuntimes fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.WorkerSandboxRuntime, + obj, oldObj []*v1.WorkerSandboxRuntime, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -11028,7 +11024,7 @@ func Validate_WorkerSandboxClass( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.WorkerSandboxRuntime](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.WorkerSandboxRuntime](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -11049,7 +11045,7 @@ func Validate_WorkerSandboxClass( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerSandboxClass) []*ateapipb.WorkerSandboxRuntime { + func(oldObj *v1.WorkerSandboxClass) []*v1.WorkerSandboxRuntime { return oldObj.RestorableRuntimes }) errs = append(errs, fn(fldPath.Child("restorable_runtimes"), obj.RestorableRuntimes, oldVal, oldObj != nil)...) @@ -11062,12 +11058,12 @@ func Validate_WorkerSandboxClass( // to declarative validation rules in the API schema. func Validate_WorkerSandboxRuntime( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.WorkerSandboxRuntime) (errs field.ErrorList) { + obj, oldObj *v1.WorkerSandboxRuntime) (errs field.ErrorList) { - { // field ateapipb.WorkerSandboxRuntime.Version + { // field v1.WorkerSandboxRuntime.Version fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.VersionedSandboxCompat, + obj, oldObj *v1.VersionedSandboxCompat, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -11089,7 +11085,7 @@ func Validate_WorkerSandboxRuntime( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerSandboxRuntime) *ateapipb.VersionedSandboxCompat { + func(oldObj *v1.WorkerSandboxRuntime) *v1.VersionedSandboxCompat { return oldObj.Version }) errs = append(errs, fn(fldPath.Child("version"), obj.Version, oldVal, oldObj != nil)...) @@ -11102,12 +11098,12 @@ func Validate_WorkerSandboxRuntime( // to declarative validation rules in the API schema. func Validate_WorkerStatus( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.WorkerStatus) (errs field.ErrorList) { + obj, oldObj *v1.WorkerStatus) (errs field.ErrorList) { - { // field ateapipb.WorkerStatus.State + { // field v1.WorkerStatus.State fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.WorkerState, + obj, oldObj *v1.WorkerState, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -11133,16 +11129,16 @@ func Validate_WorkerStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerStatus) *ateapipb.WorkerState { + func(oldObj *v1.WorkerStatus) *v1.WorkerState { return &oldObj.State }) errs = append(errs, fn(fldPath.Child("state"), &obj.State, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerStatus.Capacity + { // field v1.WorkerStatus.Capacity fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.WorkerResources, + obj, oldObj *v1.WorkerResources, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -11163,16 +11159,16 @@ func Validate_WorkerStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerStatus) *ateapipb.WorkerResources { + func(oldObj *v1.WorkerStatus) *v1.WorkerResources { return oldObj.Capacity }) errs = append(errs, fn(fldPath.Child("capacity"), obj.Capacity, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerStatus.Allocated + { // field v1.WorkerStatus.Allocated fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.WorkerResources, + obj, oldObj *v1.WorkerResources, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -11193,13 +11189,13 @@ func Validate_WorkerStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerStatus) *ateapipb.WorkerResources { + func(oldObj *v1.WorkerStatus) *v1.WorkerResources { return oldObj.Allocated }) errs = append(errs, fn(fldPath.Child("allocated"), obj.Allocated, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerStatus.ObservedEpoch + { // field v1.WorkerStatus.ObservedEpoch fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -11224,16 +11220,16 @@ func Validate_WorkerStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerStatus) *int64 { + func(oldObj *v1.WorkerStatus) *int64 { return &oldObj.ObservedEpoch }) errs = append(errs, fn(fldPath.Child("observed_epoch"), &obj.ObservedEpoch, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerStatus.SandboxClasses + { // field v1.WorkerStatus.SandboxClasses fn := func( fldPath *field.Path, - obj, oldObj []*ateapipb.WorkerSandboxClass, + obj, oldObj []*v1.WorkerSandboxClass, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -11243,7 +11239,7 @@ func Validate_WorkerStatus( } // call field-attached validations earlyReturn := false - if e := validate.PtrSliceNoNils[ateapipb.WorkerSandboxClass](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[v1.WorkerSandboxClass](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -11259,28 +11255,24 @@ func Validate_WorkerStatus( } // lists with map semantics require unique keys if e := validate.PtrSliceUnique(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.WorkerSandboxClass, b *ateapipb.WorkerSandboxClass) bool { - return a.SandboxClass == b.SandboxClass - }); len(e) != 0 { + func(a *v1.WorkerSandboxClass, b *v1.WorkerSandboxClass) bool { return a.SandboxClass == b.SandboxClass }); len(e) != 0 { errs = append(errs, e...) } // iterate the list and call the type's validation function if e := validate.EachPtrSliceVal(ctx, op, fldPath, obj, oldObj, - func(a *ateapipb.WorkerSandboxClass, b *ateapipb.WorkerSandboxClass) bool { - return a.SandboxClass == b.SandboxClass - }, ateDeepEqual, Validate_WorkerSandboxClass); len(e) != 0 { + func(a *v1.WorkerSandboxClass, b *v1.WorkerSandboxClass) bool { return a.SandboxClass == b.SandboxClass }, ateDeepEqual, Validate_WorkerSandboxClass); len(e) != 0 { errs = append(errs, e...) } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerStatus) []*ateapipb.WorkerSandboxClass { + func(oldObj *v1.WorkerStatus) []*v1.WorkerSandboxClass { return oldObj.SandboxClasses }) errs = append(errs, fn(fldPath.Child("sandbox_classes"), obj.SandboxClasses, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerStatus.Ips + { // field v1.WorkerStatus.Ips fn := func( fldPath *field.Path, obj, oldObj []string, @@ -11310,13 +11302,13 @@ func Validate_WorkerStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerStatus) []string { + func(oldObj *v1.WorkerStatus) []string { return oldObj.Ips }) errs = append(errs, fn(fldPath.Child("ips"), obj.Ips, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerStatus.IssuedEpoch + { // field v1.WorkerStatus.IssuedEpoch fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -11341,13 +11333,13 @@ func Validate_WorkerStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerStatus) *int64 { + func(oldObj *v1.WorkerStatus) *int64 { return &oldObj.IssuedEpoch }) errs = append(errs, fn(fldPath.Child("issued_epoch"), &obj.IssuedEpoch, oldVal, oldObj != nil)...) } - { // field ateapipb.WorkerStatus.RegisteredEpoch + { // field v1.WorkerStatus.RegisteredEpoch fn := func( fldPath *field.Path, obj, oldObj *int64, @@ -11372,7 +11364,7 @@ func Validate_WorkerStatus( return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.WorkerStatus) *int64 { + func(oldObj *v1.WorkerStatus) *int64 { return &oldObj.RegisteredEpoch }) errs = append(errs, fn(fldPath.Child("registered_epoch"), &obj.RegisteredEpoch, oldVal, oldObj != nil)...) diff --git a/cmd/ateapi/internal/authz/interceptor_test.go b/cmd/ateapi/internal/authz/interceptor_test.go index adc5ab63b1..33b140000b 100644 --- a/cmd/ateapi/internal/authz/interceptor_test.go +++ b/cmd/ateapi/internal/authz/interceptor_test.go @@ -18,9 +18,9 @@ import ( "context" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/principal" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/codes" ) @@ -68,64 +68,64 @@ func TestUnaryServerInterceptor_QuickRejectionAndDispatch(t *testing.T) { }{ { name: "CreateAtespace denied before handler", - fullMethod: ateapipb.Control_CreateAtespace_FullMethodName, - req: &ateapipb.CreateAtespaceRequest{Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "team1"}}}, + fullMethod: ateapi.Control_CreateAtespace_FullMethodName, + req: &ateapi.CreateAtespaceRequest{Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "team1"}}}, ctx: deniedCtx, wantCode: codes.PermissionDenied, wantHandler: false, }, { name: "CreateAtespace allowed", - fullMethod: ateapipb.Control_CreateAtespace_FullMethodName, - req: &ateapipb.CreateAtespaceRequest{Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "team1"}}}, + fullMethod: ateapi.Control_CreateAtespace_FullMethodName, + req: &ateapi.CreateAtespaceRequest{Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "team1"}}}, ctx: allowedCtx, wantCode: codes.OK, wantHandler: true, }, { name: "ListAtespaces denied before handler", - fullMethod: ateapipb.Control_ListAtespaces_FullMethodName, - req: &ateapipb.ListAtespacesRequest{}, + fullMethod: ateapi.Control_ListAtespaces_FullMethodName, + req: &ateapi.ListAtespacesRequest{}, ctx: deniedCtx, wantCode: codes.PermissionDenied, wantHandler: false, }, { name: "ListAtespaces allowed", - fullMethod: ateapipb.Control_ListAtespaces_FullMethodName, - req: &ateapipb.ListAtespacesRequest{}, + fullMethod: ateapi.Control_ListAtespaces_FullMethodName, + req: &ateapi.ListAtespacesRequest{}, ctx: allowedCtx, wantCode: codes.OK, wantHandler: true, }, { name: "GetAtespace denied before handler", - fullMethod: ateapipb.Control_GetAtespace_FullMethodName, - req: &ateapipb.GetAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "team1"}}, + fullMethod: ateapi.Control_GetAtespace_FullMethodName, + req: &ateapi.GetAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "team1"}}, ctx: deniedCtx, wantCode: codes.PermissionDenied, wantHandler: false, }, { name: "GetAtespace allowed", - fullMethod: ateapipb.Control_GetAtespace_FullMethodName, - req: &ateapipb.GetAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "team1"}}, + fullMethod: ateapi.Control_GetAtespace_FullMethodName, + req: &ateapi.GetAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "team1"}}, ctx: allowedCtx, wantCode: codes.OK, wantHandler: true, }, { name: "DeleteAtespace denied before handler", - fullMethod: ateapipb.Control_DeleteAtespace_FullMethodName, - req: &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "team1"}}, + fullMethod: ateapi.Control_DeleteAtespace_FullMethodName, + req: &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "team1"}}, ctx: deniedCtx, wantCode: codes.PermissionDenied, wantHandler: false, }, { name: "DeleteAtespace allowed", - fullMethod: ateapipb.Control_DeleteAtespace_FullMethodName, - req: &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "team1"}}, + fullMethod: ateapi.Control_DeleteAtespace_FullMethodName, + req: &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "team1"}}, ctx: allowedCtx, wantCode: codes.OK, wantHandler: true, @@ -154,8 +154,8 @@ func TestUnaryServerInterceptor_MalformedRequestRequiresPrincipalThenFailsClosed interceptor := UnaryServerInterceptor(authorizer) // 1. Unauthenticated caller with empty atespace name -> Unauthenticated - _, err := interceptor(context.Background(), &ateapipb.GetAtespaceRequest{}, &grpc.UnaryServerInfo{ - FullMethod: ateapipb.Control_GetAtespace_FullMethodName, + _, err := interceptor(context.Background(), &ateapi.GetAtespaceRequest{}, &grpc.UnaryServerInfo{ + FullMethod: ateapi.Control_GetAtespace_FullMethodName, }, func(ctx context.Context, req any) (any, error) { t.Fatal("handler must not be invoked for unauthenticated request") return nil, nil @@ -171,8 +171,8 @@ func TestUnaryServerInterceptor_MalformedRequestRequiresPrincipalThenFailsClosed Kind: principal.KindJWT, }) for _, name := range []string{"", "team\n1"} { - _, err = interceptor(authCtx, &ateapipb.GetAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: name}}, &grpc.UnaryServerInfo{ - FullMethod: ateapipb.Control_GetAtespace_FullMethodName, + _, err = interceptor(authCtx, &ateapi.GetAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: name}}, &grpc.UnaryServerInfo{ + FullMethod: ateapi.Control_GetAtespace_FullMethodName, }, func(ctx context.Context, req any) (any, error) { t.Fatalf("handler must not be invoked for atespace name %q", name) return nil, nil @@ -184,7 +184,7 @@ func TestUnaryServerInterceptor_MalformedRequestRequiresPrincipalThenFailsClosed // 3. Unexpected request type for a registered RPC -> fails closed with codes.Internal without calling handler _, err = interceptor(authCtx, "wrong-type", &grpc.UnaryServerInfo{ - FullMethod: ateapipb.Control_GetAtespace_FullMethodName, + FullMethod: ateapi.Control_GetAtespace_FullMethodName, }, func(ctx context.Context, req any) (any, error) { t.Fatal("handler must not be invoked when request type assertion fails") return nil, nil @@ -198,7 +198,7 @@ func TestUnaryServerInterceptor_MalformedRequestRequiresPrincipalThenFailsClosed // An RPC with no rule is denied, and an RPC its handler authorizes passes // through. Neither reaches OpenFGA, so the authorizer is nil. func TestUnaryServerInterceptor_UnregisteredAndHandlerAuthorizedRPCs(t *testing.T) { - const unregistered = "/ateapi.Control/NotARealMethod" + const unregistered = "/substrate.ateapi.v1.Control/NotARealMethod" aliceCtx := principal.InjectContext(context.Background(), principal.PrincipalInfo{ ID: "alice@example.com", Kind: principal.KindJWT, @@ -212,10 +212,10 @@ func TestUnaryServerInterceptor_UnregisteredAndHandlerAuthorizedRPCs(t *testing. }{ {"unregistered RPC is denied", aliceCtx, unregistered, codes.PermissionDenied}, {"unregistered RPC is denied without a principal", context.Background(), unregistered, codes.PermissionDenied}, - {"RegisterWorker passes", context.Background(), ateapipb.WorkerService_RegisterWorker_FullMethodName, codes.OK}, - {"RequestActorSuspend passes", context.Background(), ateapipb.WorkerService_RequestActorSuspend_FullMethodName, codes.OK}, - {"MintWorkerActorCertificate passes", context.Background(), ateapipb.WorkerService_MintWorkerActorCertificate_FullMethodName, codes.OK}, - {"MintWorkerActorJwt passes", context.Background(), ateapipb.WorkerService_MintWorkerActorJwt_FullMethodName, codes.OK}, + {"RegisterWorker passes", context.Background(), ateapi.WorkerService_RegisterWorker_FullMethodName, codes.OK}, + {"RequestActorSuspend passes", context.Background(), ateapi.WorkerService_RequestActorSuspend_FullMethodName, codes.OK}, + {"MintWorkerActorCertificate passes", context.Background(), ateapi.WorkerService_MintWorkerActorCertificate_FullMethodName, codes.OK}, + {"MintWorkerActorJwt passes", context.Background(), ateapi.WorkerService_MintWorkerActorJwt_FullMethodName, codes.OK}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { @@ -268,35 +268,35 @@ func TestUnaryServerInterceptor_ActorAndTemplateChecks(t *testing.T) { fullMethod string req any } - local := &ateapipb.ObjectRef{Atespace: "team-a", Name: "tmpl"} - shared := &ateapipb.ObjectRef{Atespace: "shared", Name: "tmpl"} - actor := &ateapipb.ObjectRef{Atespace: "team-a", Name: "runner"} - actorWithTemplate := func(template *ateapipb.ObjectRef) *ateapipb.Actor { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actor.GetAtespace(), Name: actor.GetName()}, + local := &ateapi.ObjectRef{Atespace: "team-a", Name: "tmpl"} + shared := &ateapi.ObjectRef{Atespace: "shared", Name: "tmpl"} + actor := &ateapi.ObjectRef{Atespace: "team-a", Name: "runner"} + actorWithTemplate := func(template *ateapi.ObjectRef) *ateapi.Actor { + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actor.GetAtespace(), Name: actor.GetName()}, ActorTemplate: template, } } - createActor := func(template *ateapipb.ObjectRef) rpcCall { - return rpcCall{ateapipb.Control_CreateActor_FullMethodName, &ateapipb.CreateActorRequest{Actor: actorWithTemplate(template)}} + createActor := func(template *ateapi.ObjectRef) rpcCall { + return rpcCall{ateapi.Control_CreateActor_FullMethodName, &ateapi.CreateActorRequest{Actor: actorWithTemplate(template)}} } - updateActor := func(template *ateapipb.ObjectRef) rpcCall { - return rpcCall{ateapipb.Control_UpdateActor_FullMethodName, &ateapipb.UpdateActorRequest{Actor: actorWithTemplate(template)}} + updateActor := func(template *ateapi.ObjectRef) rpcCall { + return rpcCall{ateapi.Control_UpdateActor_FullMethodName, &ateapi.UpdateActorRequest{Actor: actorWithTemplate(template)}} } - getActor := rpcCall{ateapipb.Control_GetActor_FullMethodName, &ateapipb.GetActorRequest{Actor: actor}} - deleteActor := rpcCall{ateapipb.Control_DeleteActor_FullMethodName, &ateapipb.DeleteActorRequest{Actor: actor}} + getActor := rpcCall{ateapi.Control_GetActor_FullMethodName, &ateapi.GetActorRequest{Actor: actor}} + deleteActor := rpcCall{ateapi.Control_DeleteActor_FullMethodName, &ateapi.DeleteActorRequest{Actor: actor}} listActors := func(atespace string) rpcCall { - return rpcCall{ateapipb.Control_ListActors_FullMethodName, &ateapipb.ListActorsRequest{Atespace: atespace}} + return rpcCall{ateapi.Control_ListActors_FullMethodName, &ateapi.ListActorsRequest{Atespace: atespace}} } - createTemplate := rpcCall{ateapipb.Control_CreateActorTemplate_FullMethodName, &ateapipb.CreateActorTemplateRequest{ - ActorTemplate: &ateapipb.ActorTemplate{Metadata: &ateapipb.ResourceMetadata{Atespace: local.GetAtespace(), Name: local.GetName()}}, + createTemplate := rpcCall{ateapi.Control_CreateActorTemplate_FullMethodName, &ateapi.CreateActorTemplateRequest{ + ActorTemplate: &ateapi.ActorTemplate{Metadata: &ateapi.ResourceMetadata{Atespace: local.GetAtespace(), Name: local.GetName()}}, }} - getTemplate := func(template *ateapipb.ObjectRef) rpcCall { - return rpcCall{ateapipb.Control_GetActorTemplate_FullMethodName, &ateapipb.GetActorTemplateRequest{ActorTemplate: template}} + getTemplate := func(template *ateapi.ObjectRef) rpcCall { + return rpcCall{ateapi.Control_GetActorTemplate_FullMethodName, &ateapi.GetActorTemplateRequest{ActorTemplate: template}} } - deleteTemplate := rpcCall{ateapipb.Control_DeleteActorTemplate_FullMethodName, &ateapipb.DeleteActorTemplateRequest{ActorTemplate: local}} + deleteTemplate := rpcCall{ateapi.Control_DeleteActorTemplate_FullMethodName, &ateapi.DeleteActorTemplateRequest{ActorTemplate: local}} listTemplates := func(atespace string) rpcCall { - return rpcCall{ateapipb.Control_ListActorTemplates_FullMethodName, &ateapipb.ListActorTemplatesRequest{Atespace: atespace}} + return rpcCall{ateapi.Control_ListActorTemplates_FullMethodName, &ateapi.ListActorTemplatesRequest{Atespace: atespace}} } tests := []struct { @@ -413,51 +413,51 @@ func TestUnaryServerInterceptor_LifecycleEgressWorkerAndTagChecks(t *testing.T) fullMethod string req any } - actor := &ateapipb.ObjectRef{Atespace: "team-a", Name: "runner"} - worker := &ateapipb.ObjectRef{Name: "w-1"} - resume := rpcCall{ateapipb.Control_ResumeActor_FullMethodName, &ateapipb.ResumeActorRequest{Actor: actor}} - suspend := rpcCall{ateapipb.Control_SuspendActor_FullMethodName, &ateapipb.SuspendActorRequest{Actor: actor}} - revert := rpcCall{ateapipb.Control_RevertActor_FullMethodName, &ateapipb.RevertActorRequest{Actor: actor}} - getEgress := rpcCall{ateapipb.Control_GetActorEgressPolicy_FullMethodName, &ateapipb.GetActorEgressPolicyRequest{Actor: actor}} - createEgress := rpcCall{ateapipb.Control_CreateActorEgressPolicy_FullMethodName, &ateapipb.CreateActorEgressPolicyRequest{Actor: actor}} - updateEgress := rpcCall{ateapipb.Control_UpdateActorEgressPolicy_FullMethodName, &ateapipb.UpdateActorEgressPolicyRequest{Actor: actor}} - deleteEgress := rpcCall{ateapipb.Control_DeleteActorEgressPolicy_FullMethodName, &ateapipb.DeleteActorEgressPolicyRequest{Actor: actor}} - createWorker := rpcCall{ateapipb.Control_CreateWorker_FullMethodName, &ateapipb.CreateWorkerRequest{}} - listWorkers := rpcCall{ateapipb.Control_ListWorkers_FullMethodName, &ateapipb.ListWorkersRequest{}} - getWorker := rpcCall{ateapipb.Control_GetWorker_FullMethodName, &ateapipb.GetWorkerRequest{Worker: worker}} - updateWorker := rpcCall{ateapipb.Control_UpdateWorker_FullMethodName, &ateapipb.UpdateWorkerRequest{Worker: &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: worker.GetName()}, + actor := &ateapi.ObjectRef{Atespace: "team-a", Name: "runner"} + worker := &ateapi.ObjectRef{Name: "w-1"} + resume := rpcCall{ateapi.Control_ResumeActor_FullMethodName, &ateapi.ResumeActorRequest{Actor: actor}} + suspend := rpcCall{ateapi.Control_SuspendActor_FullMethodName, &ateapi.SuspendActorRequest{Actor: actor}} + revert := rpcCall{ateapi.Control_RevertActor_FullMethodName, &ateapi.RevertActorRequest{Actor: actor}} + getEgress := rpcCall{ateapi.Control_GetActorEgressPolicy_FullMethodName, &ateapi.GetActorEgressPolicyRequest{Actor: actor}} + createEgress := rpcCall{ateapi.Control_CreateActorEgressPolicy_FullMethodName, &ateapi.CreateActorEgressPolicyRequest{Actor: actor}} + updateEgress := rpcCall{ateapi.Control_UpdateActorEgressPolicy_FullMethodName, &ateapi.UpdateActorEgressPolicyRequest{Actor: actor}} + deleteEgress := rpcCall{ateapi.Control_DeleteActorEgressPolicy_FullMethodName, &ateapi.DeleteActorEgressPolicyRequest{Actor: actor}} + createWorker := rpcCall{ateapi.Control_CreateWorker_FullMethodName, &ateapi.CreateWorkerRequest{}} + listWorkers := rpcCall{ateapi.Control_ListWorkers_FullMethodName, &ateapi.ListWorkersRequest{}} + getWorker := rpcCall{ateapi.Control_GetWorker_FullMethodName, &ateapi.GetWorkerRequest{Worker: worker}} + updateWorker := rpcCall{ateapi.Control_UpdateWorker_FullMethodName, &ateapi.UpdateWorkerRequest{Worker: &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: worker.GetName()}, }}} - deleteWorker := rpcCall{ateapipb.Control_DeleteWorker_FullMethodName, &ateapipb.DeleteWorkerRequest{Worker: worker}} - drainWorker := rpcCall{ateapipb.Control_DrainWorker_FullMethodName, &ateapipb.DrainWorkerRequest{Worker: worker}} - markAvailable := rpcCall{ateapipb.Control_MarkWorkerAvailable_FullMethodName, &ateapipb.MarkWorkerAvailableRequest{Worker: worker}} - markUnavailable := rpcCall{ateapipb.Control_MarkWorkerUnavailable_FullMethodName, &ateapipb.MarkWorkerUnavailableRequest{Worker: worker}} - listAssignments := rpcCall{ateapipb.Control_ListWorkerActorAssignments_FullMethodName, &ateapipb.ListWorkerActorAssignmentsRequest{Worker: worker}} - tag := &ateapipb.ObjectRef{Atespace: "team-a", Name: "v1"} - createTag := rpcCall{ateapipb.Control_CreateTag_FullMethodName, &ateapipb.CreateTagRequest{Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "v1"}, + deleteWorker := rpcCall{ateapi.Control_DeleteWorker_FullMethodName, &ateapi.DeleteWorkerRequest{Worker: worker}} + drainWorker := rpcCall{ateapi.Control_DrainWorker_FullMethodName, &ateapi.DrainWorkerRequest{Worker: worker}} + markAvailable := rpcCall{ateapi.Control_MarkWorkerAvailable_FullMethodName, &ateapi.MarkWorkerAvailableRequest{Worker: worker}} + markUnavailable := rpcCall{ateapi.Control_MarkWorkerUnavailable_FullMethodName, &ateapi.MarkWorkerUnavailableRequest{Worker: worker}} + listAssignments := rpcCall{ateapi.Control_ListWorkerActorAssignments_FullMethodName, &ateapi.ListWorkerActorAssignmentsRequest{Worker: worker}} + tag := &ateapi.ObjectRef{Atespace: "team-a", Name: "v1"} + createTag := rpcCall{ateapi.Control_CreateTag_FullMethodName, &ateapi.CreateTagRequest{Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "v1"}, SourceActor: actor, }}} // A tag in team-b of an actor in team-a. - createCrossTag := rpcCall{ateapipb.Control_CreateTag_FullMethodName, &ateapipb.CreateTagRequest{Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-b", Name: "v1"}, + createCrossTag := rpcCall{ateapi.Control_CreateTag_FullMethodName, &ateapi.CreateTagRequest{Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-b", Name: "v1"}, SourceActor: actor, }}} - getTag := rpcCall{ateapipb.Control_GetTag_FullMethodName, &ateapipb.GetTagRequest{Tag: tag}} - listTags := rpcCall{ateapipb.Control_ListTags_FullMethodName, &ateapipb.ListTagsRequest{Atespace: "team-a"}} - listAllTags := rpcCall{ateapipb.Control_ListTags_FullMethodName, &ateapipb.ListTagsRequest{}} - updateTag := rpcCall{ateapipb.Control_UpdateTag_FullMethodName, &ateapipb.UpdateTagRequest{Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "v1"}, + getTag := rpcCall{ateapi.Control_GetTag_FullMethodName, &ateapi.GetTagRequest{Tag: tag}} + listTags := rpcCall{ateapi.Control_ListTags_FullMethodName, &ateapi.ListTagsRequest{Atespace: "team-a"}} + listAllTags := rpcCall{ateapi.Control_ListTags_FullMethodName, &ateapi.ListTagsRequest{}} + updateTag := rpcCall{ateapi.Control_UpdateTag_FullMethodName, &ateapi.UpdateTagRequest{Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "v1"}, }}} - deleteTag := rpcCall{ateapipb.Control_DeleteTag_FullMethodName, &ateapipb.DeleteTagRequest{Tag: tag}} - mintJWT := rpcCall{ateapipb.Control_MintActorJwt_FullMethodName, &ateapipb.MintActorJwtRequest{Actor: actor}} - mintCert := rpcCall{ateapipb.Control_MintActorCertificate_FullMethodName, &ateapipb.MintActorCertificateRequest{Actor: actor}} + deleteTag := rpcCall{ateapi.Control_DeleteTag_FullMethodName, &ateapi.DeleteTagRequest{Tag: tag}} + mintJWT := rpcCall{ateapi.Control_MintActorJwt_FullMethodName, &ateapi.MintActorJwtRequest{Actor: actor}} + mintCert := rpcCall{ateapi.Control_MintActorCertificate_FullMethodName, &ateapi.MintActorCertificateRequest{Actor: actor}} // cloneTag creates an actor in atespace from team-a's tag v1, with a // template in that same atespace so only the tag check can differ. - cloneTag := func(atespace string, sourceTag *ateapipb.ObjectRef) rpcCall { - return rpcCall{ateapipb.Control_CreateActor_FullMethodName, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: "clone"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: atespace, Name: "tmpl"}, + cloneTag := func(atespace string, sourceTag *ateapi.ObjectRef) rpcCall { + return rpcCall{ateapi.Control_CreateActor_FullMethodName, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: "clone"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: atespace, Name: "tmpl"}, SourceTag: sourceTag, }}} } @@ -606,29 +606,29 @@ func TestUnaryServerInterceptor_SystemPrincipals(t *testing.T) { fullMethod string req any } - actor := &ateapipb.ObjectRef{Atespace: "team-a", Name: "runner"} - worker := &ateapipb.ObjectRef{Name: "w-1"} - getActor := rpcCall{ateapipb.Control_GetActor_FullMethodName, &ateapipb.GetActorRequest{Actor: actor}} - deleteActor := rpcCall{ateapipb.Control_DeleteActor_FullMethodName, &ateapipb.DeleteActorRequest{Actor: actor}} - listAllActors := rpcCall{ateapipb.Control_ListActors_FullMethodName, &ateapipb.ListActorsRequest{}} - listAtespaces := rpcCall{ateapipb.Control_ListAtespaces_FullMethodName, &ateapipb.ListAtespacesRequest{}} - resume := rpcCall{ateapipb.Control_ResumeActor_FullMethodName, &ateapipb.ResumeActorRequest{Actor: actor}} - suspend := rpcCall{ateapipb.Control_SuspendActor_FullMethodName, &ateapipb.SuspendActorRequest{Actor: actor}} - getEgress := rpcCall{ateapipb.Control_GetActorEgressPolicy_FullMethodName, &ateapipb.GetActorEgressPolicyRequest{Actor: actor}} - updateEgress := rpcCall{ateapipb.Control_UpdateActorEgressPolicy_FullMethodName, &ateapipb.UpdateActorEgressPolicyRequest{Actor: actor}} - createWorker := rpcCall{ateapipb.Control_CreateWorker_FullMethodName, &ateapipb.CreateWorkerRequest{}} - listWorkers := rpcCall{ateapipb.Control_ListWorkers_FullMethodName, &ateapipb.ListWorkersRequest{}} - getWorker := rpcCall{ateapipb.Control_GetWorker_FullMethodName, &ateapipb.GetWorkerRequest{Worker: worker}} - updateWorker := rpcCall{ateapipb.Control_UpdateWorker_FullMethodName, &ateapipb.UpdateWorkerRequest{Worker: &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: worker.GetName()}, + actor := &ateapi.ObjectRef{Atespace: "team-a", Name: "runner"} + worker := &ateapi.ObjectRef{Name: "w-1"} + getActor := rpcCall{ateapi.Control_GetActor_FullMethodName, &ateapi.GetActorRequest{Actor: actor}} + deleteActor := rpcCall{ateapi.Control_DeleteActor_FullMethodName, &ateapi.DeleteActorRequest{Actor: actor}} + listAllActors := rpcCall{ateapi.Control_ListActors_FullMethodName, &ateapi.ListActorsRequest{}} + listAtespaces := rpcCall{ateapi.Control_ListAtespaces_FullMethodName, &ateapi.ListAtespacesRequest{}} + resume := rpcCall{ateapi.Control_ResumeActor_FullMethodName, &ateapi.ResumeActorRequest{Actor: actor}} + suspend := rpcCall{ateapi.Control_SuspendActor_FullMethodName, &ateapi.SuspendActorRequest{Actor: actor}} + getEgress := rpcCall{ateapi.Control_GetActorEgressPolicy_FullMethodName, &ateapi.GetActorEgressPolicyRequest{Actor: actor}} + updateEgress := rpcCall{ateapi.Control_UpdateActorEgressPolicy_FullMethodName, &ateapi.UpdateActorEgressPolicyRequest{Actor: actor}} + createWorker := rpcCall{ateapi.Control_CreateWorker_FullMethodName, &ateapi.CreateWorkerRequest{}} + listWorkers := rpcCall{ateapi.Control_ListWorkers_FullMethodName, &ateapi.ListWorkersRequest{}} + getWorker := rpcCall{ateapi.Control_GetWorker_FullMethodName, &ateapi.GetWorkerRequest{Worker: worker}} + updateWorker := rpcCall{ateapi.Control_UpdateWorker_FullMethodName, &ateapi.UpdateWorkerRequest{Worker: &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: worker.GetName()}, }}} - deleteWorker := rpcCall{ateapipb.Control_DeleteWorker_FullMethodName, &ateapipb.DeleteWorkerRequest{Worker: worker}} - drainWorker := rpcCall{ateapipb.Control_DrainWorker_FullMethodName, &ateapipb.DrainWorkerRequest{Worker: worker}} - markAvailable := rpcCall{ateapipb.Control_MarkWorkerAvailable_FullMethodName, &ateapipb.MarkWorkerAvailableRequest{Worker: worker}} - markUnavailable := rpcCall{ateapipb.Control_MarkWorkerUnavailable_FullMethodName, &ateapipb.MarkWorkerUnavailableRequest{Worker: worker}} - listAssignments := rpcCall{ateapipb.Control_ListWorkerActorAssignments_FullMethodName, &ateapipb.ListWorkerActorAssignmentsRequest{Worker: worker}} - mintJWT := rpcCall{ateapipb.Control_MintActorJwt_FullMethodName, &ateapipb.MintActorJwtRequest{Actor: actor}} - mintCert := rpcCall{ateapipb.Control_MintActorCertificate_FullMethodName, &ateapipb.MintActorCertificateRequest{Actor: actor}} + deleteWorker := rpcCall{ateapi.Control_DeleteWorker_FullMethodName, &ateapi.DeleteWorkerRequest{Worker: worker}} + drainWorker := rpcCall{ateapi.Control_DrainWorker_FullMethodName, &ateapi.DrainWorkerRequest{Worker: worker}} + markAvailable := rpcCall{ateapi.Control_MarkWorkerAvailable_FullMethodName, &ateapi.MarkWorkerAvailableRequest{Worker: worker}} + markUnavailable := rpcCall{ateapi.Control_MarkWorkerUnavailable_FullMethodName, &ateapi.MarkWorkerUnavailableRequest{Worker: worker}} + listAssignments := rpcCall{ateapi.Control_ListWorkerActorAssignments_FullMethodName, &ateapi.ListWorkerActorAssignmentsRequest{Worker: worker}} + mintJWT := rpcCall{ateapi.Control_MintActorJwt_FullMethodName, &ateapi.MintActorJwtRequest{Actor: actor}} + mintCert := rpcCall{ateapi.Control_MintActorCertificate_FullMethodName, &ateapi.MintActorCertificateRequest{Actor: actor}} mtls := func(id string) principal.PrincipalInfo { return principal.PrincipalInfo{ID: id, Kind: principal.KindMTLS} diff --git a/cmd/ateapi/internal/authz/policy_manager.go b/cmd/ateapi/internal/authz/policy_manager.go index 99a9d11f81..888928d753 100644 --- a/cmd/ateapi/internal/authz/policy_manager.go +++ b/cmd/ateapi/internal/authz/policy_manager.go @@ -22,7 +22,7 @@ import ( "github.com/jackc/pgx/v5" openfgav1 "github.com/openfga/api/proto/openfga/v1" "github.com/openfga/openfga/pkg/server" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/protobuf/types/known/wrapperspb" ) @@ -40,13 +40,13 @@ type PolicyManager struct { // ReconcileGlobalBindings reconciles the OpenFGA role bindings on global:root // within tx. The tuple changes commit or roll back with tx. -func (m *PolicyManager) ReconcileGlobalBindings(ctx context.Context, tx pgx.Tx, bindings []*ateapipb.Binding) error { +func (m *PolicyManager) ReconcileGlobalBindings(ctx context.Context, tx pgx.Tx, bindings []*ateapi.Binding) error { return m.reconcileBindings(ctx, tx, GlobalRootObject, bindings) } // ReconcileAtespaceBindings reconciles the OpenFGA role bindings on an atespace // within tx. The tuple changes commit or roll back with tx. -func (m *PolicyManager) ReconcileAtespaceBindings(ctx context.Context, tx pgx.Tx, name string, bindings []*ateapipb.Binding) error { +func (m *PolicyManager) ReconcileAtespaceBindings(ctx context.Context, tx pgx.Tx, name string, bindings []*ateapi.Binding) error { return m.reconcileBindings(ctx, tx, AtespaceObject(name), bindings) } @@ -115,7 +115,7 @@ func (m *PolicyManager) readObjectTuples(ctx context.Context, obj string) ([]*op // reconcileBindings diffs the existing OpenFGA tuples on obj against // desiredBindings and writes only the net additions and deletions in batches // within tx, leaving unchanged (relation, user) tuples untouched. -func (m *PolicyManager) reconcileBindings(ctx context.Context, tx pgx.Tx, obj string, desiredBindings []*ateapipb.Binding) error { +func (m *PolicyManager) reconcileBindings(ctx context.Context, tx pgx.Tx, obj string, desiredBindings []*ateapi.Binding) error { if tx == nil { return ErrNilTransaction } diff --git a/cmd/ateapi/internal/authz/registry.go b/cmd/ateapi/internal/authz/registry.go index 531d915a7c..3c8affb82f 100644 --- a/cmd/ateapi/internal/authz/registry.go +++ b/cmd/ateapi/internal/authz/registry.go @@ -17,9 +17,9 @@ package authz import ( "slices" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "k8s.io/apimachinery/pkg/util/validation/field" ) @@ -88,8 +88,8 @@ func onWorker(relation, name string, fldPath *field.Path) ([]check, field.ErrorL return []check{{relation: relation, object: WorkerObject(name)}}, nil } -// resourceRef identifies an atespaced resource. Both *ateapipb.ObjectRef and -// *ateapipb.ResourceMetadata satisfy it, including as nil pointers. +// resourceRef identifies an atespaced resource. Both *ateapi.ObjectRef and +// *ateapi.ResourceMetadata satisfy it, including as nil pointers. type resourceRef interface { GetAtespace() string GetName() string @@ -125,7 +125,7 @@ func onTag(relation string, ref resourceRef, fldPath *field.Path) ([]check, fiel // onSourceTag checks can_use_tag on the tag an actor is created from, if the // request names one. -func onSourceTag(ref *ateapipb.ObjectRef, fldPath *field.Path) ([]check, field.ErrorList) { +func onSourceTag(ref *ateapi.ObjectRef, fldPath *field.Path) ([]check, field.ErrorList) { if ref == nil { return nil, nil } @@ -164,53 +164,53 @@ func inHandler(how string) rpcRule { // from it. var defaultRPCPermissions = map[string]rpcRule{ // Atespaces. - ateapipb.Control_CreateAtespace_FullMethodName: rule(checksOf(func(*ateapipb.CreateAtespaceRequest) ([]check, field.ErrorList) { + ateapi.Control_CreateAtespace_FullMethodName: rule(checksOf(func(*ateapi.CreateAtespaceRequest) ([]check, field.ErrorList) { return onGlobal(RelationCanCreateAtespace) })), - ateapipb.Control_ListAtespaces_FullMethodName: rule(checksOf(func(*ateapipb.ListAtespacesRequest) ([]check, field.ErrorList) { + ateapi.Control_ListAtespaces_FullMethodName: rule(checksOf(func(*ateapi.ListAtespacesRequest) ([]check, field.ErrorList) { return onGlobal(RelationCanListAtespaces) })), - ateapipb.Control_GetAtespace_FullMethodName: rule(checksOf(func(r *ateapipb.GetAtespaceRequest) ([]check, field.ErrorList) { + ateapi.Control_GetAtespace_FullMethodName: rule(checksOf(func(r *ateapi.GetAtespaceRequest) ([]check, field.ErrorList) { return onAtespace(RelationCanGet, r.GetAtespace().GetName(), field.NewPath("atespace", "name")) })), - ateapipb.Control_DeleteAtespace_FullMethodName: rule(checksOf(func(r *ateapipb.DeleteAtespaceRequest) ([]check, field.ErrorList) { + ateapi.Control_DeleteAtespace_FullMethodName: rule(checksOf(func(r *ateapi.DeleteAtespaceRequest) ([]check, field.ErrorList) { return onAtespace(RelationCanDelete, r.GetAtespace().GetName(), field.NewPath("atespace", "name")) })), // Access policies. - ateapipb.Control_GetGlobalAccessPolicy_FullMethodName: rule(checksOf(func(*ateapipb.GetGlobalAccessPolicyRequest) ([]check, field.ErrorList) { + ateapi.Control_GetGlobalAccessPolicy_FullMethodName: rule(checksOf(func(*ateapi.GetGlobalAccessPolicyRequest) ([]check, field.ErrorList) { return onGlobal(RelationCanGetAccessPolicy) })), - ateapipb.Control_CreateGlobalAccessPolicy_FullMethodName: rule(checksOf(func(*ateapipb.CreateGlobalAccessPolicyRequest) ([]check, field.ErrorList) { + ateapi.Control_CreateGlobalAccessPolicy_FullMethodName: rule(checksOf(func(*ateapi.CreateGlobalAccessPolicyRequest) ([]check, field.ErrorList) { return onGlobal(RelationCanCreateAccessPolicy) })), - ateapipb.Control_UpdateGlobalAccessPolicy_FullMethodName: rule(checksOf(func(*ateapipb.UpdateGlobalAccessPolicyRequest) ([]check, field.ErrorList) { + ateapi.Control_UpdateGlobalAccessPolicy_FullMethodName: rule(checksOf(func(*ateapi.UpdateGlobalAccessPolicyRequest) ([]check, field.ErrorList) { return onGlobal(RelationCanUpdateAccessPolicy) })), - ateapipb.Control_GetAtespaceAccessPolicy_FullMethodName: rule(checksOf(func(r *ateapipb.GetAtespaceAccessPolicyRequest) ([]check, field.ErrorList) { + ateapi.Control_GetAtespaceAccessPolicy_FullMethodName: rule(checksOf(func(r *ateapi.GetAtespaceAccessPolicyRequest) ([]check, field.ErrorList) { return onAtespace(RelationCanGetAccessPolicy, r.GetAtespace().GetName(), field.NewPath("atespace", "name")) })), - ateapipb.Control_CreateAtespaceAccessPolicy_FullMethodName: rule(checksOf(func(r *ateapipb.CreateAtespaceAccessPolicyRequest) ([]check, field.ErrorList) { + ateapi.Control_CreateAtespaceAccessPolicy_FullMethodName: rule(checksOf(func(r *ateapi.CreateAtespaceAccessPolicyRequest) ([]check, field.ErrorList) { return onAtespace(RelationCanCreateAccessPolicy, r.GetAtespace().GetName(), field.NewPath("atespace", "name")) })), - ateapipb.Control_UpdateAtespaceAccessPolicy_FullMethodName: rule(checksOf(func(r *ateapipb.UpdateAtespaceAccessPolicyRequest) ([]check, field.ErrorList) { + ateapi.Control_UpdateAtespaceAccessPolicy_FullMethodName: rule(checksOf(func(r *ateapi.UpdateAtespaceAccessPolicyRequest) ([]check, field.ErrorList) { return onAtespace(RelationCanUpdateAccessPolicy, r.GetAtespace().GetName(), field.NewPath("atespace", "name")) })), - ateapipb.Control_DeleteAtespaceAccessPolicy_FullMethodName: rule(checksOf(func(r *ateapipb.DeleteAtespaceAccessPolicyRequest) ([]check, field.ErrorList) { + ateapi.Control_DeleteAtespaceAccessPolicy_FullMethodName: rule(checksOf(func(r *ateapi.DeleteAtespaceAccessPolicyRequest) ([]check, field.ErrorList) { return onAtespace(RelationCanDeleteAccessPolicy, r.GetAtespace().GetName(), field.NewPath("atespace", "name")) })), // Actor templates. - ateapipb.Control_CreateActorTemplate_FullMethodName: rule(checksOf(func(r *ateapipb.CreateActorTemplateRequest) ([]check, field.ErrorList) { + ateapi.Control_CreateActorTemplate_FullMethodName: rule(checksOf(func(r *ateapi.CreateActorTemplateRequest) ([]check, field.ErrorList) { return onAtespace(RelationCanCreateActorTemplate, r.GetActorTemplate().GetMetadata().GetAtespace(), field.NewPath("actor_template", "metadata", "atespace")) })), - ateapipb.Control_GetActorTemplate_FullMethodName: rule(checksOf(func(r *ateapipb.GetActorTemplateRequest) ([]check, field.ErrorList) { + ateapi.Control_GetActorTemplate_FullMethodName: rule(checksOf(func(r *ateapi.GetActorTemplateRequest) ([]check, field.ErrorList) { return onActorTemplate(RelationCanGet, r.GetActorTemplate(), field.NewPath("actor_template")) })), - ateapipb.Control_ListActorTemplates_FullMethodName: rule(checksOf(func(r *ateapipb.ListActorTemplatesRequest) ([]check, field.ErrorList) { + ateapi.Control_ListActorTemplates_FullMethodName: rule(checksOf(func(r *ateapi.ListActorTemplatesRequest) ([]check, field.ErrorList) { return onAtespaceOrGlobal(RelationCanListActorTemplates, r.GetAtespace(), field.NewPath("atespace")) })), - ateapipb.Control_DeleteActorTemplate_FullMethodName: rule(checksOf(func(r *ateapipb.DeleteActorTemplateRequest) ([]check, field.ErrorList) { + ateapi.Control_DeleteActorTemplate_FullMethodName: rule(checksOf(func(r *ateapi.DeleteActorTemplateRequest) ([]check, field.ErrorList) { return onActorTemplate(RelationCanDelete, r.GetActorTemplate(), field.NewPath("actor_template")) })), @@ -218,87 +218,87 @@ var defaultRPCPermissions = map[string]rpcRule{ // the actor template it runs, which may live in another atespace. Creating // one from an explicit source tag also requires can_use_tag on that tag; // the handler checks the tag's scope, completion and template. - ateapipb.Control_CreateActor_FullMethodName: rule(checksOf(func(r *ateapipb.CreateActorRequest) ([]check, field.ErrorList) { + ateapi.Control_CreateActor_FullMethodName: rule(checksOf(func(r *ateapi.CreateActorRequest) ([]check, field.ErrorList) { actorChecks, actorErrs := onAtespace(RelationCanCreateActor, r.GetActor().GetMetadata().GetAtespace(), field.NewPath("actor", "metadata", "atespace")) templateChecks, templateErrs := onActorTemplate(RelationCanUseTemplate, r.GetActor().GetActorTemplate(), field.NewPath("actor", "actor_template")) checks, errs := both(actorChecks, actorErrs, templateChecks, templateErrs) tagChecks, tagErrs := onSourceTag(r.GetActor().GetSourceTag(), field.NewPath("actor", "source_tag")) return both(checks, errs, tagChecks, tagErrs) })), - ateapipb.Control_GetActor_FullMethodName: rule(checksOf(func(r *ateapipb.GetActorRequest) ([]check, field.ErrorList) { + ateapi.Control_GetActor_FullMethodName: rule(checksOf(func(r *ateapi.GetActorRequest) ([]check, field.ErrorList) { return onActor(RelationCanGet, r.GetActor(), field.NewPath("actor")) })), - ateapipb.Control_ListActors_FullMethodName: rule(checksOf(func(r *ateapipb.ListActorsRequest) ([]check, field.ErrorList) { + ateapi.Control_ListActors_FullMethodName: rule(checksOf(func(r *ateapi.ListActorsRequest) ([]check, field.ErrorList) { return onAtespaceOrGlobal(RelationCanListActors, r.GetAtespace(), field.NewPath("atespace")) })), - ateapipb.Control_UpdateActor_FullMethodName: rule(checksOf(func(r *ateapipb.UpdateActorRequest) ([]check, field.ErrorList) { + ateapi.Control_UpdateActor_FullMethodName: rule(checksOf(func(r *ateapi.UpdateActorRequest) ([]check, field.ErrorList) { actorChecks, actorErrs := onActor(RelationCanUpdate, r.GetActor().GetMetadata(), field.NewPath("actor", "metadata")) templateChecks, templateErrs := onActorTemplate(RelationCanUseTemplate, r.GetActor().GetActorTemplate(), field.NewPath("actor", "actor_template")) return both(actorChecks, actorErrs, templateChecks, templateErrs) })), - ateapipb.Control_DeleteActor_FullMethodName: rule(checksOf(func(r *ateapipb.DeleteActorRequest) ([]check, field.ErrorList) { + ateapi.Control_DeleteActor_FullMethodName: rule(checksOf(func(r *ateapi.DeleteActorRequest) ([]check, field.ErrorList) { return onActor(RelationCanDelete, r.GetActor(), field.NewPath("actor")) })), // Actor lifecycle. - ateapipb.Control_ResumeActor_FullMethodName: rule(checksOf(func(r *ateapipb.ResumeActorRequest) ([]check, field.ErrorList) { + ateapi.Control_ResumeActor_FullMethodName: rule(checksOf(func(r *ateapi.ResumeActorRequest) ([]check, field.ErrorList) { return onActor(RelationCanResume, r.GetActor(), field.NewPath("actor")) })), - ateapipb.Control_SuspendActor_FullMethodName: rule(checksOf(func(r *ateapipb.SuspendActorRequest) ([]check, field.ErrorList) { + ateapi.Control_SuspendActor_FullMethodName: rule(checksOf(func(r *ateapi.SuspendActorRequest) ([]check, field.ErrorList) { return onActor(RelationCanSuspend, r.GetActor(), field.NewPath("actor")) })), - ateapipb.Control_RevertActor_FullMethodName: rule(checksOf(func(r *ateapipb.RevertActorRequest) ([]check, field.ErrorList) { + ateapi.Control_RevertActor_FullMethodName: rule(checksOf(func(r *ateapi.RevertActorRequest) ([]check, field.ErrorList) { return onActor(RelationCanRevert, r.GetActor(), field.NewPath("actor")) })), // Actor egress policies. - ateapipb.Control_GetActorEgressPolicy_FullMethodName: rule(checksOf(func(r *ateapipb.GetActorEgressPolicyRequest) ([]check, field.ErrorList) { + ateapi.Control_GetActorEgressPolicy_FullMethodName: rule(checksOf(func(r *ateapi.GetActorEgressPolicyRequest) ([]check, field.ErrorList) { return onActor(RelationCanGetEgressPolicy, r.GetActor(), field.NewPath("actor")) })), - ateapipb.Control_CreateActorEgressPolicy_FullMethodName: rule(checksOf(func(r *ateapipb.CreateActorEgressPolicyRequest) ([]check, field.ErrorList) { + ateapi.Control_CreateActorEgressPolicy_FullMethodName: rule(checksOf(func(r *ateapi.CreateActorEgressPolicyRequest) ([]check, field.ErrorList) { return onActor(RelationCanCreateEgressPolicy, r.GetActor(), field.NewPath("actor")) })), - ateapipb.Control_UpdateActorEgressPolicy_FullMethodName: rule(checksOf(func(r *ateapipb.UpdateActorEgressPolicyRequest) ([]check, field.ErrorList) { + ateapi.Control_UpdateActorEgressPolicy_FullMethodName: rule(checksOf(func(r *ateapi.UpdateActorEgressPolicyRequest) ([]check, field.ErrorList) { return onActor(RelationCanUpdateEgressPolicy, r.GetActor(), field.NewPath("actor")) })), - ateapipb.Control_DeleteActorEgressPolicy_FullMethodName: rule(checksOf(func(r *ateapipb.DeleteActorEgressPolicyRequest) ([]check, field.ErrorList) { + ateapi.Control_DeleteActorEgressPolicy_FullMethodName: rule(checksOf(func(r *ateapi.DeleteActorEgressPolicyRequest) ([]check, field.ErrorList) { return onActor(RelationCanDeleteEgressPolicy, r.GetActor(), field.NewPath("actor")) })), // Workers. - ateapipb.Control_CreateWorker_FullMethodName: rule(checksOf(func(*ateapipb.CreateWorkerRequest) ([]check, field.ErrorList) { + ateapi.Control_CreateWorker_FullMethodName: rule(checksOf(func(*ateapi.CreateWorkerRequest) ([]check, field.ErrorList) { return onGlobal(RelationCanCreateWorker) })), - ateapipb.Control_ListWorkers_FullMethodName: rule(checksOf(func(*ateapipb.ListWorkersRequest) ([]check, field.ErrorList) { + ateapi.Control_ListWorkers_FullMethodName: rule(checksOf(func(*ateapi.ListWorkersRequest) ([]check, field.ErrorList) { return onGlobal(RelationCanListWorkers) })), - ateapipb.Control_GetWorker_FullMethodName: rule(checksOf(func(r *ateapipb.GetWorkerRequest) ([]check, field.ErrorList) { + ateapi.Control_GetWorker_FullMethodName: rule(checksOf(func(r *ateapi.GetWorkerRequest) ([]check, field.ErrorList) { return onWorker(RelationCanGet, r.GetWorker().GetName(), field.NewPath("worker", "name")) })), - ateapipb.Control_UpdateWorker_FullMethodName: rule(checksOf(func(r *ateapipb.UpdateWorkerRequest) ([]check, field.ErrorList) { + ateapi.Control_UpdateWorker_FullMethodName: rule(checksOf(func(r *ateapi.UpdateWorkerRequest) ([]check, field.ErrorList) { return onWorker(RelationCanUpdate, r.GetWorker().GetMetadata().GetName(), field.NewPath("worker", "metadata", "name")) })), - ateapipb.Control_DeleteWorker_FullMethodName: rule(checksOf(func(r *ateapipb.DeleteWorkerRequest) ([]check, field.ErrorList) { + ateapi.Control_DeleteWorker_FullMethodName: rule(checksOf(func(r *ateapi.DeleteWorkerRequest) ([]check, field.ErrorList) { return onWorker(RelationCanDelete, r.GetWorker().GetName(), field.NewPath("worker", "name")) })), - ateapipb.Control_DrainWorker_FullMethodName: rule(checksOf(func(r *ateapipb.DrainWorkerRequest) ([]check, field.ErrorList) { + ateapi.Control_DrainWorker_FullMethodName: rule(checksOf(func(r *ateapi.DrainWorkerRequest) ([]check, field.ErrorList) { return onWorker(RelationCanDrain, r.GetWorker().GetName(), field.NewPath("worker", "name")) })), - ateapipb.Control_MarkWorkerAvailable_FullMethodName: rule(checksOf(func(r *ateapipb.MarkWorkerAvailableRequest) ([]check, field.ErrorList) { + ateapi.Control_MarkWorkerAvailable_FullMethodName: rule(checksOf(func(r *ateapi.MarkWorkerAvailableRequest) ([]check, field.ErrorList) { return onWorker(RelationCanUpdate, r.GetWorker().GetName(), field.NewPath("worker", "name")) })), - ateapipb.Control_MarkWorkerUnavailable_FullMethodName: rule(checksOf(func(r *ateapipb.MarkWorkerUnavailableRequest) ([]check, field.ErrorList) { + ateapi.Control_MarkWorkerUnavailable_FullMethodName: rule(checksOf(func(r *ateapi.MarkWorkerUnavailableRequest) ([]check, field.ErrorList) { return onWorker(RelationCanUpdate, r.GetWorker().GetName(), field.NewPath("worker", "name")) })), - ateapipb.Control_ListWorkerActorAssignments_FullMethodName: rule(checksOf(func(r *ateapipb.ListWorkerActorAssignmentsRequest) ([]check, field.ErrorList) { + ateapi.Control_ListWorkerActorAssignments_FullMethodName: rule(checksOf(func(r *ateapi.ListWorkerActorAssignmentsRequest) ([]check, field.ErrorList) { return onWorker(RelationCanListActorAssignments, r.GetWorker().GetName(), field.NewPath("worker", "name")) })), // Actor identity credentials. - ateapipb.Control_MintActorJwt_FullMethodName: rule(checksOf(func(r *ateapipb.MintActorJwtRequest) ([]check, field.ErrorList) { + ateapi.Control_MintActorJwt_FullMethodName: rule(checksOf(func(r *ateapi.MintActorJwtRequest) ([]check, field.ErrorList) { return onActor(RelationCanMintActorJWT, r.GetActor(), field.NewPath("actor")) })), - ateapipb.Control_MintActorCertificate_FullMethodName: rule(checksOf(func(r *ateapipb.MintActorCertificateRequest) ([]check, field.ErrorList) { + ateapi.Control_MintActorCertificate_FullMethodName: rule(checksOf(func(r *ateapi.MintActorCertificateRequest) ([]check, field.ErrorList) { return onActor(RelationCanMintActorCertificate, r.GetActor(), field.NewPath("actor")) })), @@ -308,30 +308,30 @@ var defaultRPCPermissions = map[string]rpcRule{ // // TODO: Creating and publishing tags expose an actor's data; see the TODO // on type tag in model.fga. - ateapipb.Control_CreateTag_FullMethodName: rule(checksOf(func(r *ateapipb.CreateTagRequest) ([]check, field.ErrorList) { + ateapi.Control_CreateTag_FullMethodName: rule(checksOf(func(r *ateapi.CreateTagRequest) ([]check, field.ErrorList) { return onAtespace(RelationCanCreateTag, r.GetTag().GetSourceActor().GetAtespace(), field.NewPath("tag", "source_actor", "atespace")) })), - ateapipb.Control_GetTag_FullMethodName: rule(checksOf(func(r *ateapipb.GetTagRequest) ([]check, field.ErrorList) { + ateapi.Control_GetTag_FullMethodName: rule(checksOf(func(r *ateapi.GetTagRequest) ([]check, field.ErrorList) { return onTag(RelationCanGet, r.GetTag(), field.NewPath("tag")) })), - ateapipb.Control_ListTags_FullMethodName: rule(checksOf(func(r *ateapipb.ListTagsRequest) ([]check, field.ErrorList) { + ateapi.Control_ListTags_FullMethodName: rule(checksOf(func(r *ateapi.ListTagsRequest) ([]check, field.ErrorList) { return onAtespaceOrGlobal(RelationCanListTags, r.GetAtespace(), field.NewPath("atespace")) })), - ateapipb.Control_UpdateTag_FullMethodName: rule(checksOf(func(r *ateapipb.UpdateTagRequest) ([]check, field.ErrorList) { + ateapi.Control_UpdateTag_FullMethodName: rule(checksOf(func(r *ateapi.UpdateTagRequest) ([]check, field.ErrorList) { return onTag(RelationCanUpdate, r.GetTag().GetMetadata(), field.NewPath("tag", "metadata")) })), - ateapipb.Control_DeleteTag_FullMethodName: rule(checksOf(func(r *ateapipb.DeleteTagRequest) ([]check, field.ErrorList) { + ateapi.Control_DeleteTag_FullMethodName: rule(checksOf(func(r *ateapi.DeleteTagRequest) ([]check, field.ErrorList) { return onTag(RelationCanDelete, r.GetTag(), field.NewPath("tag")) })), // WorkerService is served only to atelet, which each handler // authenticates by its mTLS SPIFFE ID. - ateapipb.WorkerService_AcquireWorkerEpoch_FullMethodName: inHandler("ateletauth: caller is atelet on the Worker's node"), - ateapipb.WorkerService_RegisterWorker_FullMethodName: inHandler("ateletauth: caller is atelet on the Worker's node"), - ateapipb.WorkerService_SetWorkerSandboxRuntimes_FullMethodName: inHandler("ateletauth: caller is atelet on the Worker's node"), - ateapipb.WorkerService_ReportActorCrashed_FullMethodName: inHandler("ateletauth: caller is atelet on the node of the Worker hosting the Actor"), - ateapipb.WorkerService_RequestActorSuspend_FullMethodName: inHandler("ateletauth: caller is atelet on the node of the Worker hosting the Actor"), - ateapipb.WorkerService_MintWorkerActorCertificate_FullMethodName: inHandler("ateletauth: caller is atelet on the node of the Worker the Actor is assigned to"), - ateapipb.WorkerService_MintWorkerActorJwt_FullMethodName: inHandler("ateletauth: caller is atelet on the node hosting the Actor"), - ateapipb.WorkerService_ReportActorSnapshotState_FullMethodName: inHandler("ateletauth: caller is atelet on the node the Actor is placed on or holds a local snapshot of it"), + ateapi.WorkerService_AcquireWorkerEpoch_FullMethodName: inHandler("ateletauth: caller is atelet on the Worker's node"), + ateapi.WorkerService_RegisterWorker_FullMethodName: inHandler("ateletauth: caller is atelet on the Worker's node"), + ateapi.WorkerService_SetWorkerSandboxRuntimes_FullMethodName: inHandler("ateletauth: caller is atelet on the Worker's node"), + ateapi.WorkerService_ReportActorCrashed_FullMethodName: inHandler("ateletauth: caller is atelet on the node of the Worker hosting the Actor"), + ateapi.WorkerService_RequestActorSuspend_FullMethodName: inHandler("ateletauth: caller is atelet on the node of the Worker hosting the Actor"), + ateapi.WorkerService_MintWorkerActorCertificate_FullMethodName: inHandler("ateletauth: caller is atelet on the node of the Worker the Actor is assigned to"), + ateapi.WorkerService_MintWorkerActorJwt_FullMethodName: inHandler("ateletauth: caller is atelet on the node hosting the Actor"), + ateapi.WorkerService_ReportActorSnapshotState_FullMethodName: inHandler("ateletauth: caller is atelet on the node the Actor is placed on or holds a local snapshot of it"), } diff --git a/cmd/ateapi/internal/authz/registry_test.go b/cmd/ateapi/internal/authz/registry_test.go index b6821ca7d3..53487c2797 100644 --- a/cmd/ateapi/internal/authz/registry_test.go +++ b/cmd/ateapi/internal/authz/registry_test.go @@ -19,18 +19,18 @@ import ( "strings" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/apierror" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" ) func TestDefaultRPCPermissions(t *testing.T) { - actorRef := &ateapipb.ObjectRef{Atespace: "team-a", Name: "runner"} - actorMeta := &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "runner"} - localTemplate := &ateapipb.ObjectRef{Atespace: "team-a", Name: "tmpl"} - sharedTemplate := &ateapipb.ObjectRef{Atespace: "shared", Name: "tmpl"} - workerRef := &ateapipb.ObjectRef{Name: "w-1"} - tagRef := &ateapipb.ObjectRef{Atespace: "team-a", Name: "v1"} + actorRef := &ateapi.ObjectRef{Atespace: "team-a", Name: "runner"} + actorMeta := &ateapi.ResourceMetadata{Atespace: "team-a", Name: "runner"} + localTemplate := &ateapi.ObjectRef{Atespace: "team-a", Name: "tmpl"} + sharedTemplate := &ateapi.ObjectRef{Atespace: "shared", Name: "tmpl"} + workerRef := &ateapi.ObjectRef{Name: "w-1"} + tagRef := &ateapi.ObjectRef{Atespace: "team-a", Name: "v1"} tests := []struct { name string @@ -41,68 +41,68 @@ func TestDefaultRPCPermissions(t *testing.T) { // Atespaces. { name: "CreateAtespace", - fullMethod: ateapipb.Control_CreateAtespace_FullMethodName, - req: &ateapipb.CreateAtespaceRequest{}, + fullMethod: ateapi.Control_CreateAtespace_FullMethodName, + req: &ateapi.CreateAtespaceRequest{}, want: []check{{RelationCanCreateAtespace, GlobalRootObject}}, }, { name: "ListAtespaces", - fullMethod: ateapipb.Control_ListAtespaces_FullMethodName, - req: &ateapipb.ListAtespacesRequest{}, + fullMethod: ateapi.Control_ListAtespaces_FullMethodName, + req: &ateapi.ListAtespacesRequest{}, want: []check{{RelationCanListAtespaces, GlobalRootObject}}, }, { name: "GetAtespace", - fullMethod: ateapipb.Control_GetAtespace_FullMethodName, - req: &ateapipb.GetAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}}, + fullMethod: ateapi.Control_GetAtespace_FullMethodName, + req: &ateapi.GetAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}}, want: []check{{RelationCanGet, "atespace:team-a"}}, }, { name: "DeleteAtespace", - fullMethod: ateapipb.Control_DeleteAtespace_FullMethodName, - req: &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}}, + fullMethod: ateapi.Control_DeleteAtespace_FullMethodName, + req: &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}}, want: []check{{RelationCanDelete, "atespace:team-a"}}, }, // Actor templates. { name: "CreateActorTemplate", - fullMethod: ateapipb.Control_CreateActorTemplate_FullMethodName, - req: &ateapipb.CreateActorTemplateRequest{ActorTemplate: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "tmpl"}, + fullMethod: ateapi.Control_CreateActorTemplate_FullMethodName, + req: &ateapi.CreateActorTemplateRequest{ActorTemplate: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "tmpl"}, }}, want: []check{{RelationCanCreateActorTemplate, "atespace:team-a"}}, }, { name: "GetActorTemplate", - fullMethod: ateapipb.Control_GetActorTemplate_FullMethodName, - req: &ateapipb.GetActorTemplateRequest{ActorTemplate: localTemplate}, + fullMethod: ateapi.Control_GetActorTemplate_FullMethodName, + req: &ateapi.GetActorTemplateRequest{ActorTemplate: localTemplate}, want: []check{{RelationCanGet, "actor_template:team-a/tmpl"}}, }, { name: "ListActorTemplates in an atespace", - fullMethod: ateapipb.Control_ListActorTemplates_FullMethodName, - req: &ateapipb.ListActorTemplatesRequest{Atespace: "team-a"}, + fullMethod: ateapi.Control_ListActorTemplates_FullMethodName, + req: &ateapi.ListActorTemplatesRequest{Atespace: "team-a"}, want: []check{{RelationCanListActorTemplates, "atespace:team-a"}}, }, { name: "ListActorTemplates across all atespaces", - fullMethod: ateapipb.Control_ListActorTemplates_FullMethodName, - req: &ateapipb.ListActorTemplatesRequest{}, + fullMethod: ateapi.Control_ListActorTemplates_FullMethodName, + req: &ateapi.ListActorTemplatesRequest{}, want: []check{{RelationCanListActorTemplates, GlobalRootObject}}, }, { name: "DeleteActorTemplate", - fullMethod: ateapipb.Control_DeleteActorTemplate_FullMethodName, - req: &ateapipb.DeleteActorTemplateRequest{ActorTemplate: localTemplate}, + fullMethod: ateapi.Control_DeleteActorTemplate_FullMethodName, + req: &ateapi.DeleteActorTemplateRequest{ActorTemplate: localTemplate}, want: []check{{RelationCanDelete, "actor_template:team-a/tmpl"}}, }, // Actors. { name: "CreateActor checks the atespace and the template", - fullMethod: ateapipb.Control_CreateActor_FullMethodName, - req: &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{Metadata: actorMeta, ActorTemplate: sharedTemplate}}, + fullMethod: ateapi.Control_CreateActor_FullMethodName, + req: &ateapi.CreateActorRequest{Actor: &ateapi.Actor{Metadata: actorMeta, ActorTemplate: sharedTemplate}}, want: []check{ {RelationCanCreateActor, "atespace:team-a"}, {RelationCanUseTemplate, "actor_template:shared/tmpl"}, @@ -110,11 +110,11 @@ func TestDefaultRPCPermissions(t *testing.T) { }, { name: "CreateActor from a tag also checks the tag", - fullMethod: ateapipb.Control_CreateActor_FullMethodName, - req: &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ + fullMethod: ateapi.Control_CreateActor_FullMethodName, + req: &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ Metadata: actorMeta, ActorTemplate: sharedTemplate, - SourceTag: &ateapipb.ObjectRef{Atespace: "team-b", Name: "v1"}, + SourceTag: &ateapi.ObjectRef{Atespace: "team-b", Name: "v1"}, }}, want: []check{ {RelationCanCreateActor, "atespace:team-a"}, @@ -124,11 +124,11 @@ func TestDefaultRPCPermissions(t *testing.T) { }, { name: "CreateActor from a template tag checks the tag", - fullMethod: ateapipb.Control_CreateActor_FullMethodName, - req: &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ + fullMethod: ateapi.Control_CreateActor_FullMethodName, + req: &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ Metadata: actorMeta, ActorTemplate: sharedTemplate, - SourceTag: &ateapipb.ObjectRef{Atespace: "shared", Name: "0b5c7d4e-golden"}, + SourceTag: &ateapi.ObjectRef{Atespace: "shared", Name: "0b5c7d4e-golden"}, }}, want: []check{ {RelationCanCreateActor, "atespace:team-a"}, @@ -138,26 +138,26 @@ func TestDefaultRPCPermissions(t *testing.T) { }, { name: "GetActor", - fullMethod: ateapipb.Control_GetActor_FullMethodName, - req: &ateapipb.GetActorRequest{Actor: actorRef}, + fullMethod: ateapi.Control_GetActor_FullMethodName, + req: &ateapi.GetActorRequest{Actor: actorRef}, want: []check{{RelationCanGet, "actor:team-a/runner"}}, }, { name: "ListActors in an atespace", - fullMethod: ateapipb.Control_ListActors_FullMethodName, - req: &ateapipb.ListActorsRequest{Atespace: "team-a"}, + fullMethod: ateapi.Control_ListActors_FullMethodName, + req: &ateapi.ListActorsRequest{Atespace: "team-a"}, want: []check{{RelationCanListActors, "atespace:team-a"}}, }, { name: "ListActors across all atespaces", - fullMethod: ateapipb.Control_ListActors_FullMethodName, - req: &ateapipb.ListActorsRequest{}, + fullMethod: ateapi.Control_ListActors_FullMethodName, + req: &ateapi.ListActorsRequest{}, want: []check{{RelationCanListActors, GlobalRootObject}}, }, { name: "UpdateActor checks the actor and the template", - fullMethod: ateapipb.Control_UpdateActor_FullMethodName, - req: &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{Metadata: actorMeta, ActorTemplate: sharedTemplate}}, + fullMethod: ateapi.Control_UpdateActor_FullMethodName, + req: &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{Metadata: actorMeta, ActorTemplate: sharedTemplate}}, want: []check{ {RelationCanUpdate, "actor:team-a/runner"}, {RelationCanUseTemplate, "actor_template:shared/tmpl"}, @@ -165,169 +165,169 @@ func TestDefaultRPCPermissions(t *testing.T) { }, { name: "DeleteActor", - fullMethod: ateapipb.Control_DeleteActor_FullMethodName, - req: &ateapipb.DeleteActorRequest{Actor: actorRef}, + fullMethod: ateapi.Control_DeleteActor_FullMethodName, + req: &ateapi.DeleteActorRequest{Actor: actorRef}, want: []check{{RelationCanDelete, "actor:team-a/runner"}}, }, // Actor lifecycle. { name: "ResumeActor", - fullMethod: ateapipb.Control_ResumeActor_FullMethodName, - req: &ateapipb.ResumeActorRequest{Actor: actorRef}, + fullMethod: ateapi.Control_ResumeActor_FullMethodName, + req: &ateapi.ResumeActorRequest{Actor: actorRef}, want: []check{{RelationCanResume, "actor:team-a/runner"}}, }, { name: "SuspendActor", - fullMethod: ateapipb.Control_SuspendActor_FullMethodName, - req: &ateapipb.SuspendActorRequest{Actor: actorRef}, + fullMethod: ateapi.Control_SuspendActor_FullMethodName, + req: &ateapi.SuspendActorRequest{Actor: actorRef}, want: []check{{RelationCanSuspend, "actor:team-a/runner"}}, }, { name: "RevertActor", - fullMethod: ateapipb.Control_RevertActor_FullMethodName, - req: &ateapipb.RevertActorRequest{Actor: actorRef}, + fullMethod: ateapi.Control_RevertActor_FullMethodName, + req: &ateapi.RevertActorRequest{Actor: actorRef}, want: []check{{RelationCanRevert, "actor:team-a/runner"}}, }, // Actor egress policies. { name: "GetActorEgressPolicy", - fullMethod: ateapipb.Control_GetActorEgressPolicy_FullMethodName, - req: &ateapipb.GetActorEgressPolicyRequest{Actor: actorRef}, + fullMethod: ateapi.Control_GetActorEgressPolicy_FullMethodName, + req: &ateapi.GetActorEgressPolicyRequest{Actor: actorRef}, want: []check{{RelationCanGetEgressPolicy, "actor:team-a/runner"}}, }, { name: "CreateActorEgressPolicy", - fullMethod: ateapipb.Control_CreateActorEgressPolicy_FullMethodName, - req: &ateapipb.CreateActorEgressPolicyRequest{Actor: actorRef}, + fullMethod: ateapi.Control_CreateActorEgressPolicy_FullMethodName, + req: &ateapi.CreateActorEgressPolicyRequest{Actor: actorRef}, want: []check{{RelationCanCreateEgressPolicy, "actor:team-a/runner"}}, }, { name: "UpdateActorEgressPolicy", - fullMethod: ateapipb.Control_UpdateActorEgressPolicy_FullMethodName, - req: &ateapipb.UpdateActorEgressPolicyRequest{Actor: actorRef}, + fullMethod: ateapi.Control_UpdateActorEgressPolicy_FullMethodName, + req: &ateapi.UpdateActorEgressPolicyRequest{Actor: actorRef}, want: []check{{RelationCanUpdateEgressPolicy, "actor:team-a/runner"}}, }, { name: "DeleteActorEgressPolicy", - fullMethod: ateapipb.Control_DeleteActorEgressPolicy_FullMethodName, - req: &ateapipb.DeleteActorEgressPolicyRequest{Actor: actorRef}, + fullMethod: ateapi.Control_DeleteActorEgressPolicy_FullMethodName, + req: &ateapi.DeleteActorEgressPolicyRequest{Actor: actorRef}, want: []check{{RelationCanDeleteEgressPolicy, "actor:team-a/runner"}}, }, // Workers. { name: "CreateWorker", - fullMethod: ateapipb.Control_CreateWorker_FullMethodName, - req: &ateapipb.CreateWorkerRequest{}, + fullMethod: ateapi.Control_CreateWorker_FullMethodName, + req: &ateapi.CreateWorkerRequest{}, want: []check{{RelationCanCreateWorker, GlobalRootObject}}, }, { name: "ListWorkers", - fullMethod: ateapipb.Control_ListWorkers_FullMethodName, - req: &ateapipb.ListWorkersRequest{}, + fullMethod: ateapi.Control_ListWorkers_FullMethodName, + req: &ateapi.ListWorkersRequest{}, want: []check{{RelationCanListWorkers, GlobalRootObject}}, }, { name: "GetWorker", - fullMethod: ateapipb.Control_GetWorker_FullMethodName, - req: &ateapipb.GetWorkerRequest{Worker: workerRef}, + fullMethod: ateapi.Control_GetWorker_FullMethodName, + req: &ateapi.GetWorkerRequest{Worker: workerRef}, want: []check{{RelationCanGet, "worker:w-1"}}, }, { name: "UpdateWorker", - fullMethod: ateapipb.Control_UpdateWorker_FullMethodName, - req: &ateapipb.UpdateWorkerRequest{Worker: &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "w-1"}, + fullMethod: ateapi.Control_UpdateWorker_FullMethodName, + req: &ateapi.UpdateWorkerRequest{Worker: &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "w-1"}, }}, want: []check{{RelationCanUpdate, "worker:w-1"}}, }, { name: "DeleteWorker", - fullMethod: ateapipb.Control_DeleteWorker_FullMethodName, - req: &ateapipb.DeleteWorkerRequest{Worker: workerRef}, + fullMethod: ateapi.Control_DeleteWorker_FullMethodName, + req: &ateapi.DeleteWorkerRequest{Worker: workerRef}, want: []check{{RelationCanDelete, "worker:w-1"}}, }, { name: "DrainWorker", - fullMethod: ateapipb.Control_DrainWorker_FullMethodName, - req: &ateapipb.DrainWorkerRequest{Worker: workerRef}, + fullMethod: ateapi.Control_DrainWorker_FullMethodName, + req: &ateapi.DrainWorkerRequest{Worker: workerRef}, want: []check{{RelationCanDrain, "worker:w-1"}}, }, { name: "MarkWorkerAvailable", - fullMethod: ateapipb.Control_MarkWorkerAvailable_FullMethodName, - req: &ateapipb.MarkWorkerAvailableRequest{Worker: workerRef}, + fullMethod: ateapi.Control_MarkWorkerAvailable_FullMethodName, + req: &ateapi.MarkWorkerAvailableRequest{Worker: workerRef}, want: []check{{RelationCanUpdate, "worker:w-1"}}, }, { name: "MarkWorkerUnavailable", - fullMethod: ateapipb.Control_MarkWorkerUnavailable_FullMethodName, - req: &ateapipb.MarkWorkerUnavailableRequest{Worker: workerRef}, + fullMethod: ateapi.Control_MarkWorkerUnavailable_FullMethodName, + req: &ateapi.MarkWorkerUnavailableRequest{Worker: workerRef}, want: []check{{RelationCanUpdate, "worker:w-1"}}, }, { name: "ListWorkerActorAssignments", - fullMethod: ateapipb.Control_ListWorkerActorAssignments_FullMethodName, - req: &ateapipb.ListWorkerActorAssignmentsRequest{Worker: workerRef}, + fullMethod: ateapi.Control_ListWorkerActorAssignments_FullMethodName, + req: &ateapi.ListWorkerActorAssignmentsRequest{Worker: workerRef}, want: []check{{RelationCanListActorAssignments, "worker:w-1"}}, }, // Actor identity credentials. { name: "MintActorJWT", - fullMethod: ateapipb.Control_MintActorJwt_FullMethodName, - req: &ateapipb.MintActorJwtRequest{Actor: actorRef}, + fullMethod: ateapi.Control_MintActorJwt_FullMethodName, + req: &ateapi.MintActorJwtRequest{Actor: actorRef}, want: []check{{RelationCanMintActorJWT, "actor:team-a/runner"}}, }, { name: "MintActorCertificate", - fullMethod: ateapipb.Control_MintActorCertificate_FullMethodName, - req: &ateapipb.MintActorCertificateRequest{Actor: actorRef}, + fullMethod: ateapi.Control_MintActorCertificate_FullMethodName, + req: &ateapi.MintActorCertificateRequest{Actor: actorRef}, want: []check{{RelationCanMintActorCertificate, "actor:team-a/runner"}}, }, // Tags. { name: "CreateTag checks its source actor's atespace", - fullMethod: ateapipb.Control_CreateTag_FullMethodName, - req: &ateapipb.CreateTagRequest{Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "other", Name: "v1"}, + fullMethod: ateapi.Control_CreateTag_FullMethodName, + req: &ateapi.CreateTagRequest{Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: "other", Name: "v1"}, SourceActor: actorRef, }}, want: []check{{RelationCanCreateTag, "atespace:team-a"}}, }, { name: "GetTag", - fullMethod: ateapipb.Control_GetTag_FullMethodName, - req: &ateapipb.GetTagRequest{Tag: tagRef}, + fullMethod: ateapi.Control_GetTag_FullMethodName, + req: &ateapi.GetTagRequest{Tag: tagRef}, want: []check{{RelationCanGet, "tag:team-a/v1"}}, }, { name: "ListTags in an atespace", - fullMethod: ateapipb.Control_ListTags_FullMethodName, - req: &ateapipb.ListTagsRequest{Atespace: "team-a"}, + fullMethod: ateapi.Control_ListTags_FullMethodName, + req: &ateapi.ListTagsRequest{Atespace: "team-a"}, want: []check{{RelationCanListTags, "atespace:team-a"}}, }, { name: "ListTags across all atespaces", - fullMethod: ateapipb.Control_ListTags_FullMethodName, - req: &ateapipb.ListTagsRequest{}, + fullMethod: ateapi.Control_ListTags_FullMethodName, + req: &ateapi.ListTagsRequest{}, want: []check{{RelationCanListTags, GlobalRootObject}}, }, { name: "UpdateTag", - fullMethod: ateapipb.Control_UpdateTag_FullMethodName, - req: &ateapipb.UpdateTagRequest{Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "v1"}, + fullMethod: ateapi.Control_UpdateTag_FullMethodName, + req: &ateapi.UpdateTagRequest{Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "v1"}, }}, want: []check{{RelationCanUpdate, "tag:team-a/v1"}}, }, { name: "DeleteTag", - fullMethod: ateapipb.Control_DeleteTag_FullMethodName, - req: &ateapipb.DeleteTagRequest{Tag: tagRef}, + fullMethod: ateapi.Control_DeleteTag_FullMethodName, + req: &ateapi.DeleteTagRequest{Tag: tagRef}, want: []check{{RelationCanDelete, "tag:team-a/v1"}}, }, } @@ -352,8 +352,8 @@ func TestDefaultRPCPermissions(t *testing.T) { // A request missing an identifier a check needs, or naming a resource with an // invalid name, is rejected rather than having that check skipped. func TestDefaultRPCPermissions_MalformedIdentifierFailsClosed(t *testing.T) { - actorMeta := &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "runner"} - template := &ateapipb.ObjectRef{Atespace: "shared", Name: "tmpl"} + actorMeta := &ateapi.ResourceMetadata{Atespace: "team-a", Name: "runner"} + template := &ateapi.ObjectRef{Atespace: "shared", Name: "tmpl"} tests := []struct { name string @@ -363,291 +363,291 @@ func TestDefaultRPCPermissions_MalformedIdentifierFailsClosed(t *testing.T) { }{ { name: "GetAtespace without a name", - fullMethod: ateapipb.Control_GetAtespace_FullMethodName, - req: &ateapipb.GetAtespaceRequest{}, + fullMethod: ateapi.Control_GetAtespace_FullMethodName, + req: &ateapi.GetAtespaceRequest{}, wantField: "atespace.name", }, { name: "DeleteAtespace with an invalid name", - fullMethod: ateapipb.Control_DeleteAtespace_FullMethodName, - req: &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "Team A"}}, + fullMethod: ateapi.Control_DeleteAtespace_FullMethodName, + req: &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "Team A"}}, wantField: "atespace.name", }, { name: "GetAtespaceAccessPolicy without an atespace", - fullMethod: ateapipb.Control_GetAtespaceAccessPolicy_FullMethodName, - req: &ateapipb.GetAtespaceAccessPolicyRequest{}, + fullMethod: ateapi.Control_GetAtespaceAccessPolicy_FullMethodName, + req: &ateapi.GetAtespaceAccessPolicyRequest{}, wantField: "atespace.name", }, { name: "UpdateAtespaceAccessPolicy with an invalid atespace", - fullMethod: ateapipb.Control_UpdateAtespaceAccessPolicy_FullMethodName, - req: &ateapipb.UpdateAtespaceAccessPolicyRequest{Atespace: &ateapipb.ObjectRef{Name: "Team-A"}}, + fullMethod: ateapi.Control_UpdateAtespaceAccessPolicy_FullMethodName, + req: &ateapi.UpdateAtespaceAccessPolicyRequest{Atespace: &ateapi.ObjectRef{Name: "Team-A"}}, wantField: "atespace.name", }, { name: "CreateActorTemplate without an atespace", - fullMethod: ateapipb.Control_CreateActorTemplate_FullMethodName, - req: &ateapipb.CreateActorTemplateRequest{}, + fullMethod: ateapi.Control_CreateActorTemplate_FullMethodName, + req: &ateapi.CreateActorTemplateRequest{}, wantField: "actor_template.metadata.atespace", }, { name: "GetActorTemplate with a name containing a tab", - fullMethod: ateapipb.Control_GetActorTemplate_FullMethodName, - req: &ateapipb.GetActorTemplateRequest{ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "a\tb"}}, + fullMethod: ateapi.Control_GetActorTemplate_FullMethodName, + req: &ateapi.GetActorTemplateRequest{ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "a\tb"}}, wantField: "actor_template.name", }, { name: "ListActorTemplates with an invalid atespace", - fullMethod: ateapipb.Control_ListActorTemplates_FullMethodName, - req: &ateapipb.ListActorTemplatesRequest{Atespace: "team/a"}, + fullMethod: ateapi.Control_ListActorTemplates_FullMethodName, + req: &ateapi.ListActorTemplatesRequest{Atespace: "team/a"}, wantField: "atespace", }, { name: "DeleteActorTemplate without an atespace", - fullMethod: ateapipb.Control_DeleteActorTemplate_FullMethodName, - req: &ateapipb.DeleteActorTemplateRequest{ActorTemplate: &ateapipb.ObjectRef{Name: "tmpl"}}, + fullMethod: ateapi.Control_DeleteActorTemplate_FullMethodName, + req: &ateapi.DeleteActorTemplateRequest{ActorTemplate: &ateapi.ObjectRef{Name: "tmpl"}}, wantField: "actor_template.atespace", }, { name: "CreateActor without an actor", - fullMethod: ateapipb.Control_CreateActor_FullMethodName, - req: &ateapipb.CreateActorRequest{}, + fullMethod: ateapi.Control_CreateActor_FullMethodName, + req: &ateapi.CreateActorRequest{}, wantField: "actor.metadata.atespace", }, { name: "CreateActor without a template", - fullMethod: ateapipb.Control_CreateActor_FullMethodName, - req: &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{Metadata: actorMeta}}, + fullMethod: ateapi.Control_CreateActor_FullMethodName, + req: &ateapi.CreateActorRequest{Actor: &ateapi.Actor{Metadata: actorMeta}}, wantField: "actor.actor_template.atespace", }, { name: "CreateActor with a template missing its atespace", - fullMethod: ateapipb.Control_CreateActor_FullMethodName, - req: &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ + fullMethod: ateapi.Control_CreateActor_FullMethodName, + req: &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ Metadata: actorMeta, - ActorTemplate: &ateapipb.ObjectRef{Name: "tmpl"}, + ActorTemplate: &ateapi.ObjectRef{Name: "tmpl"}, }}, wantField: "actor.actor_template.atespace", }, { name: "CreateActor with an invalid template atespace", - fullMethod: ateapipb.Control_CreateActor_FullMethodName, - req: &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ + fullMethod: ateapi.Control_CreateActor_FullMethodName, + req: &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ Metadata: actorMeta, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "shared/x", Name: "tmpl"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "shared/x", Name: "tmpl"}, }}, wantField: "actor.actor_template.atespace", }, { name: "CreateActor with a source tag missing its name", - fullMethod: ateapipb.Control_CreateActor_FullMethodName, - req: &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ + fullMethod: ateapi.Control_CreateActor_FullMethodName, + req: &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ Metadata: actorMeta, ActorTemplate: template, - SourceTag: &ateapipb.ObjectRef{Atespace: "team-b"}, + SourceTag: &ateapi.ObjectRef{Atespace: "team-b"}, }}, wantField: "actor.source_tag.name", }, { name: "CreateActor with a source tag missing its atespace", - fullMethod: ateapipb.Control_CreateActor_FullMethodName, - req: &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ + fullMethod: ateapi.Control_CreateActor_FullMethodName, + req: &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ Metadata: actorMeta, ActorTemplate: template, - SourceTag: &ateapipb.ObjectRef{Name: "v1"}, + SourceTag: &ateapi.ObjectRef{Name: "v1"}, }}, wantField: "actor.source_tag.atespace", }, { name: "GetActor without a name", - fullMethod: ateapipb.Control_GetActor_FullMethodName, - req: &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "team-a"}}, + fullMethod: ateapi.Control_GetActor_FullMethodName, + req: &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: "team-a"}}, wantField: "actor.name", }, { name: "ListActors with an over-long atespace", - fullMethod: ateapipb.Control_ListActors_FullMethodName, - req: &ateapipb.ListActorsRequest{Atespace: strings.Repeat("a", 64)}, + fullMethod: ateapi.Control_ListActors_FullMethodName, + req: &ateapi.ListActorsRequest{Atespace: strings.Repeat("a", 64)}, wantField: "atespace", }, { name: "UpdateActor without metadata", - fullMethod: ateapipb.Control_UpdateActor_FullMethodName, - req: &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{ActorTemplate: template}}, + fullMethod: ateapi.Control_UpdateActor_FullMethodName, + req: &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ActorTemplate: template}}, wantField: "actor.metadata.atespace", }, { name: "UpdateActor with metadata missing its atespace", - fullMethod: ateapipb.Control_UpdateActor_FullMethodName, - req: &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "runner"}, + fullMethod: ateapi.Control_UpdateActor_FullMethodName, + req: &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "runner"}, ActorTemplate: template, }}, wantField: "actor.metadata.atespace", }, { name: "UpdateActor without a template", - fullMethod: ateapipb.Control_UpdateActor_FullMethodName, - req: &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{Metadata: actorMeta}}, + fullMethod: ateapi.Control_UpdateActor_FullMethodName, + req: &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{Metadata: actorMeta}}, wantField: "actor.actor_template.name", }, { name: "UpdateActor with an invalid template atespace", - fullMethod: ateapipb.Control_UpdateActor_FullMethodName, - req: &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{ + fullMethod: ateapi.Control_UpdateActor_FullMethodName, + req: &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ Metadata: actorMeta, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "Shared", Name: "tmpl"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "Shared", Name: "tmpl"}, }}, wantField: "actor.actor_template.atespace", }, { name: "DeleteActor with an invalid atespace", - fullMethod: ateapipb.Control_DeleteActor_FullMethodName, - req: &ateapipb.DeleteActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "team:a", Name: "runner"}}, + fullMethod: ateapi.Control_DeleteActor_FullMethodName, + req: &ateapi.DeleteActorRequest{Actor: &ateapi.ObjectRef{Atespace: "team:a", Name: "runner"}}, wantField: "actor.atespace", }, { name: "SuspendActor without an actor", - fullMethod: ateapipb.Control_SuspendActor_FullMethodName, - req: &ateapipb.SuspendActorRequest{}, + fullMethod: ateapi.Control_SuspendActor_FullMethodName, + req: &ateapi.SuspendActorRequest{}, wantField: "actor.atespace", }, { name: "ResumeActor with an invalid name", - fullMethod: ateapipb.Control_ResumeActor_FullMethodName, - req: &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "Runner"}}, + fullMethod: ateapi.Control_ResumeActor_FullMethodName, + req: &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "Runner"}}, wantField: "actor.name", }, { name: "SuspendActor without a name", - fullMethod: ateapipb.Control_SuspendActor_FullMethodName, - req: &ateapipb.SuspendActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "team-a"}}, + fullMethod: ateapi.Control_SuspendActor_FullMethodName, + req: &ateapi.SuspendActorRequest{Actor: &ateapi.ObjectRef{Atespace: "team-a"}}, wantField: "actor.name", }, { name: "RevertActor with an invalid atespace", - fullMethod: ateapipb.Control_RevertActor_FullMethodName, - req: &ateapipb.RevertActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "team/a", Name: "runner"}}, + fullMethod: ateapi.Control_RevertActor_FullMethodName, + req: &ateapi.RevertActorRequest{Actor: &ateapi.ObjectRef{Atespace: "team/a", Name: "runner"}}, wantField: "actor.atespace", }, { name: "GetActorEgressPolicy without an atespace", - fullMethod: ateapipb.Control_GetActorEgressPolicy_FullMethodName, - req: &ateapipb.GetActorEgressPolicyRequest{Actor: &ateapipb.ObjectRef{Name: "runner"}}, + fullMethod: ateapi.Control_GetActorEgressPolicy_FullMethodName, + req: &ateapi.GetActorEgressPolicyRequest{Actor: &ateapi.ObjectRef{Name: "runner"}}, wantField: "actor.atespace", }, { name: "CreateActorEgressPolicy without an actor", - fullMethod: ateapipb.Control_CreateActorEgressPolicy_FullMethodName, - req: &ateapipb.CreateActorEgressPolicyRequest{}, + fullMethod: ateapi.Control_CreateActorEgressPolicy_FullMethodName, + req: &ateapi.CreateActorEgressPolicyRequest{}, wantField: "actor.atespace", }, { name: "UpdateActorEgressPolicy with an invalid name", - fullMethod: ateapipb.Control_UpdateActorEgressPolicy_FullMethodName, - req: &ateapipb.UpdateActorEgressPolicyRequest{Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "a b"}}, + fullMethod: ateapi.Control_UpdateActorEgressPolicy_FullMethodName, + req: &ateapi.UpdateActorEgressPolicyRequest{Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "a b"}}, wantField: "actor.name", }, { name: "DeleteActorEgressPolicy without a name", - fullMethod: ateapipb.Control_DeleteActorEgressPolicy_FullMethodName, - req: &ateapipb.DeleteActorEgressPolicyRequest{Actor: &ateapipb.ObjectRef{Atespace: "team-a"}}, + fullMethod: ateapi.Control_DeleteActorEgressPolicy_FullMethodName, + req: &ateapi.DeleteActorEgressPolicyRequest{Actor: &ateapi.ObjectRef{Atespace: "team-a"}}, wantField: "actor.name", }, { name: "GetWorker without a worker", - fullMethod: ateapipb.Control_GetWorker_FullMethodName, - req: &ateapipb.GetWorkerRequest{}, + fullMethod: ateapi.Control_GetWorker_FullMethodName, + req: &ateapi.GetWorkerRequest{}, wantField: "worker.name", }, { name: "UpdateWorker without metadata", - fullMethod: ateapipb.Control_UpdateWorker_FullMethodName, - req: &ateapipb.UpdateWorkerRequest{Worker: &ateapipb.Worker{}}, + fullMethod: ateapi.Control_UpdateWorker_FullMethodName, + req: &ateapi.UpdateWorkerRequest{Worker: &ateapi.Worker{}}, wantField: "worker.metadata.name", }, { name: "DeleteWorker with an invalid name", - fullMethod: ateapipb.Control_DeleteWorker_FullMethodName, - req: &ateapipb.DeleteWorkerRequest{Worker: &ateapipb.ObjectRef{Name: "w/1"}}, + fullMethod: ateapi.Control_DeleteWorker_FullMethodName, + req: &ateapi.DeleteWorkerRequest{Worker: &ateapi.ObjectRef{Name: "w/1"}}, wantField: "worker.name", }, { name: "DrainWorker with an over-long name", - fullMethod: ateapipb.Control_DrainWorker_FullMethodName, - req: &ateapipb.DrainWorkerRequest{Worker: &ateapipb.ObjectRef{Name: strings.Repeat("w", 64)}}, + fullMethod: ateapi.Control_DrainWorker_FullMethodName, + req: &ateapi.DrainWorkerRequest{Worker: &ateapi.ObjectRef{Name: strings.Repeat("w", 64)}}, wantField: "worker.name", }, { name: "MarkWorkerAvailable without a name", - fullMethod: ateapipb.Control_MarkWorkerAvailable_FullMethodName, - req: &ateapipb.MarkWorkerAvailableRequest{Worker: &ateapipb.ObjectRef{}}, + fullMethod: ateapi.Control_MarkWorkerAvailable_FullMethodName, + req: &ateapi.MarkWorkerAvailableRequest{Worker: &ateapi.ObjectRef{}}, wantField: "worker.name", }, { name: "MarkWorkerUnavailable with an invalid name", - fullMethod: ateapipb.Control_MarkWorkerUnavailable_FullMethodName, - req: &ateapipb.MarkWorkerUnavailableRequest{Worker: &ateapipb.ObjectRef{Name: "w/1"}}, + fullMethod: ateapi.Control_MarkWorkerUnavailable_FullMethodName, + req: &ateapi.MarkWorkerUnavailableRequest{Worker: &ateapi.ObjectRef{Name: "w/1"}}, wantField: "worker.name", }, { name: "ListWorkerActorAssignments without a name", - fullMethod: ateapipb.Control_ListWorkerActorAssignments_FullMethodName, - req: &ateapipb.ListWorkerActorAssignmentsRequest{Worker: &ateapipb.ObjectRef{}}, + fullMethod: ateapi.Control_ListWorkerActorAssignments_FullMethodName, + req: &ateapi.ListWorkerActorAssignmentsRequest{Worker: &ateapi.ObjectRef{}}, wantField: "worker.name", }, { name: "MintActorJWT without an actor", - fullMethod: ateapipb.Control_MintActorJwt_FullMethodName, - req: &ateapipb.MintActorJwtRequest{}, + fullMethod: ateapi.Control_MintActorJwt_FullMethodName, + req: &ateapi.MintActorJwtRequest{}, wantField: "actor.atespace", }, { name: "MintActorCertificate with an invalid name", - fullMethod: ateapipb.Control_MintActorCertificate_FullMethodName, - req: &ateapipb.MintActorCertificateRequest{Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "a/b"}}, + fullMethod: ateapi.Control_MintActorCertificate_FullMethodName, + req: &ateapi.MintActorCertificateRequest{Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "a/b"}}, wantField: "actor.name", }, { name: "CreateTag without a source actor", - fullMethod: ateapipb.Control_CreateTag_FullMethodName, - req: &ateapipb.CreateTagRequest{Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "v1"}, + fullMethod: ateapi.Control_CreateTag_FullMethodName, + req: &ateapi.CreateTagRequest{Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "v1"}, }}, wantField: "tag.source_actor.atespace", }, { name: "CreateTag with an invalid source actor atespace", - fullMethod: ateapipb.Control_CreateTag_FullMethodName, - req: &ateapipb.CreateTagRequest{Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "v1"}, - SourceActor: &ateapipb.ObjectRef{Atespace: "Team-A", Name: "runner"}, + fullMethod: ateapi.Control_CreateTag_FullMethodName, + req: &ateapi.CreateTagRequest{Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "v1"}, + SourceActor: &ateapi.ObjectRef{Atespace: "Team-A", Name: "runner"}, }}, wantField: "tag.source_actor.atespace", }, { name: "GetTag without an atespace", - fullMethod: ateapipb.Control_GetTag_FullMethodName, - req: &ateapipb.GetTagRequest{Tag: &ateapipb.ObjectRef{Name: "v1"}}, + fullMethod: ateapi.Control_GetTag_FullMethodName, + req: &ateapi.GetTagRequest{Tag: &ateapi.ObjectRef{Name: "v1"}}, wantField: "tag.atespace", }, { name: "ListTags with an invalid atespace", - fullMethod: ateapipb.Control_ListTags_FullMethodName, - req: &ateapipb.ListTagsRequest{Atespace: "Team-A"}, + fullMethod: ateapi.Control_ListTags_FullMethodName, + req: &ateapi.ListTagsRequest{Atespace: "Team-A"}, wantField: "atespace", }, { name: "UpdateTag without metadata", - fullMethod: ateapipb.Control_UpdateTag_FullMethodName, - req: &ateapipb.UpdateTagRequest{Tag: &ateapipb.Tag{}}, + fullMethod: ateapi.Control_UpdateTag_FullMethodName, + req: &ateapi.UpdateTagRequest{Tag: &ateapi.Tag{}}, wantField: "tag.metadata.atespace", }, { name: "DeleteTag without a name", - fullMethod: ateapipb.Control_DeleteTag_FullMethodName, - req: &ateapipb.DeleteTagRequest{Tag: &ateapipb.ObjectRef{Atespace: "team-a"}}, + fullMethod: ateapi.Control_DeleteTag_FullMethodName, + req: &ateapi.DeleteTagRequest{Tag: &ateapi.ObjectRef{Atespace: "team-a"}}, wantField: "tag.name", }, } @@ -684,7 +684,7 @@ func TestDefaultRPCPermissions_UnexpectedRequestTypeFailsClosed(t *testing.T) { // ateapi.proto. func TestDefaultRPCPermissions_CoversEveryServedRPC(t *testing.T) { served := map[string]bool{} - services := ateapipb.File_ateapi_proto.Services() + services := ateapi.File_api_ateapi_v1_ateapi_proto.Services() for i := range services.Len() { sd := services.Get(i) methods := sd.Methods() diff --git a/cmd/ateapi/internal/controlapi/access_policy.go b/cmd/ateapi/internal/controlapi/access_policy.go index 226bbd7578..e95c602a47 100644 --- a/cmd/ateapi/internal/controlapi/access_policy.go +++ b/cmd/ateapi/internal/controlapi/access_policy.go @@ -19,17 +19,17 @@ import ( "errors" "fmt" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/defaults" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" "k8s.io/apimachinery/pkg/util/validation/field" ) -func (s *RPCService) CreateGlobalAccessPolicy(ctx context.Context, req *ateapipb.CreateGlobalAccessPolicyRequest) (*ateapipb.AccessPolicy, error) { +func (s *RPCService) CreateGlobalAccessPolicy(ctx context.Context, req *ateapi.CreateGlobalAccessPolicyRequest) (*ateapi.AccessPolicy, error) { policy := req.GetAccessPolicy() if policy != nil { scrubResourceMetadataForCreate(policy.Metadata) @@ -41,19 +41,19 @@ func (s *RPCService) CreateGlobalAccessPolicy(ctx context.Context, req *ateapipb return s.impl.CreateGlobalAccessPolicy(ctx, policy) } -func (s *ServiceImpl) CreateGlobalAccessPolicy(ctx context.Context, policy *ateapipb.AccessPolicy) (*ateapipb.AccessPolicy, error) { +func (s *ServiceImpl) CreateGlobalAccessPolicy(ctx context.Context, policy *ateapi.AccessPolicy) (*ateapi.AccessPolicy, error) { created, err := s.store.CreateGlobalAccessPolicy(ctx, policy) return mapAccessPolicyWrite(created, err) } -func (s *RPCService) GetGlobalAccessPolicy(ctx context.Context, req *ateapipb.GetGlobalAccessPolicyRequest) (*ateapipb.AccessPolicy, error) { +func (s *RPCService) GetGlobalAccessPolicy(ctx context.Context, req *ateapi.GetGlobalAccessPolicyRequest) (*ateapi.AccessPolicy, error) { if errs := apivalidation.ValidateGetGlobalAccessPolicyRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } return s.impl.GetGlobalAccessPolicy(ctx) } -func (s *ServiceImpl) GetGlobalAccessPolicy(ctx context.Context) (*ateapipb.AccessPolicy, error) { +func (s *ServiceImpl) GetGlobalAccessPolicy(ctx context.Context) (*ateapi.AccessPolicy, error) { policy, err := s.store.GetGlobalAccessPolicy(ctx) if err != nil { if errors.Is(err, store.ErrNotFound) { @@ -64,7 +64,7 @@ func (s *ServiceImpl) GetGlobalAccessPolicy(ctx context.Context) (*ateapipb.Acce return policy, nil } -func (s *RPCService) UpdateGlobalAccessPolicy(ctx context.Context, req *ateapipb.UpdateGlobalAccessPolicyRequest) (*ateapipb.AccessPolicy, error) { +func (s *RPCService) UpdateGlobalAccessPolicy(ctx context.Context, req *ateapi.UpdateGlobalAccessPolicyRequest) (*ateapi.AccessPolicy, error) { policy := req.GetAccessPolicy() if policy != nil { scrubResourceMetadataForUpdate(policy.Metadata) @@ -75,9 +75,9 @@ func (s *RPCService) UpdateGlobalAccessPolicy(ctx context.Context, req *ateapipb return s.impl.UpdateGlobalAccessPolicy(ctx, store.PreconditionFrom(policy), replaceAccessPolicy(policy)) } -func (s *ServiceImpl) UpdateGlobalAccessPolicy(ctx context.Context, precondition store.Precondition, mutate func(*ateapipb.AccessPolicy) error) (*ateapipb.AccessPolicy, error) { - updated, err := s.store.UpdateGlobalAccessPolicy(ctx, precondition, func(toUpdate *ateapipb.AccessPolicy) error { - oldVal := proto.Clone(toUpdate).(*ateapipb.AccessPolicy) +func (s *ServiceImpl) UpdateGlobalAccessPolicy(ctx context.Context, precondition store.Precondition, mutate func(*ateapi.AccessPolicy) error) (*ateapi.AccessPolicy, error) { + updated, err := s.store.UpdateGlobalAccessPolicy(ctx, precondition, func(toUpdate *ateapi.AccessPolicy) error { + oldVal := proto.Clone(toUpdate).(*ateapi.AccessPolicy) if err := mutate(toUpdate); err != nil { return err } @@ -87,7 +87,7 @@ func (s *ServiceImpl) UpdateGlobalAccessPolicy(ctx context.Context, precondition return mapAccessPolicyWrite(updated, err) } -func (s *RPCService) CreateAtespaceAccessPolicy(ctx context.Context, req *ateapipb.CreateAtespaceAccessPolicyRequest) (*ateapipb.AccessPolicy, error) { +func (s *RPCService) CreateAtespaceAccessPolicy(ctx context.Context, req *ateapi.CreateAtespaceAccessPolicyRequest) (*ateapi.AccessPolicy, error) { policy := req.GetAccessPolicy() if policy != nil { scrubResourceMetadataForCreate(policy.Metadata) @@ -99,19 +99,19 @@ func (s *RPCService) CreateAtespaceAccessPolicy(ctx context.Context, req *ateapi return s.impl.CreateAtespaceAccessPolicy(ctx, req.GetAtespace().GetName(), policy) } -func (s *ServiceImpl) CreateAtespaceAccessPolicy(ctx context.Context, name string, policy *ateapipb.AccessPolicy) (*ateapipb.AccessPolicy, error) { +func (s *ServiceImpl) CreateAtespaceAccessPolicy(ctx context.Context, name string, policy *ateapi.AccessPolicy) (*ateapi.AccessPolicy, error) { created, err := s.store.CreateAtespaceAccessPolicy(ctx, name, policy) return mapAccessPolicyWrite(created, err) } -func (s *RPCService) GetAtespaceAccessPolicy(ctx context.Context, req *ateapipb.GetAtespaceAccessPolicyRequest) (*ateapipb.AccessPolicy, error) { +func (s *RPCService) GetAtespaceAccessPolicy(ctx context.Context, req *ateapi.GetAtespaceAccessPolicyRequest) (*ateapi.AccessPolicy, error) { if errs := apivalidation.ValidateGetAtespaceAccessPolicyRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } return s.impl.GetAtespaceAccessPolicy(ctx, req.GetAtespace().GetName()) } -func (s *ServiceImpl) GetAtespaceAccessPolicy(ctx context.Context, name string) (*ateapipb.AccessPolicy, error) { +func (s *ServiceImpl) GetAtespaceAccessPolicy(ctx context.Context, name string) (*ateapi.AccessPolicy, error) { policy, err := s.store.GetAtespaceAccessPolicy(ctx, name) if err != nil { if errors.Is(err, store.ErrNotFound) { @@ -122,7 +122,7 @@ func (s *ServiceImpl) GetAtespaceAccessPolicy(ctx context.Context, name string) return policy, nil } -func (s *RPCService) UpdateAtespaceAccessPolicy(ctx context.Context, req *ateapipb.UpdateAtespaceAccessPolicyRequest) (*ateapipb.AccessPolicy, error) { +func (s *RPCService) UpdateAtespaceAccessPolicy(ctx context.Context, req *ateapi.UpdateAtespaceAccessPolicyRequest) (*ateapi.AccessPolicy, error) { policy := req.GetAccessPolicy() if policy != nil { scrubResourceMetadataForUpdate(policy.Metadata) @@ -133,9 +133,9 @@ func (s *RPCService) UpdateAtespaceAccessPolicy(ctx context.Context, req *ateapi return s.impl.UpdateAtespaceAccessPolicy(ctx, req.GetAtespace().GetName(), store.PreconditionFrom(policy), replaceAccessPolicy(policy)) } -func (s *ServiceImpl) UpdateAtespaceAccessPolicy(ctx context.Context, name string, precondition store.Precondition, mutate func(*ateapipb.AccessPolicy) error) (*ateapipb.AccessPolicy, error) { - updated, err := s.store.UpdateAtespaceAccessPolicy(ctx, name, precondition, func(toUpdate *ateapipb.AccessPolicy) error { - oldVal := proto.Clone(toUpdate).(*ateapipb.AccessPolicy) +func (s *ServiceImpl) UpdateAtespaceAccessPolicy(ctx context.Context, name string, precondition store.Precondition, mutate func(*ateapi.AccessPolicy) error) (*ateapi.AccessPolicy, error) { + updated, err := s.store.UpdateAtespaceAccessPolicy(ctx, name, precondition, func(toUpdate *ateapi.AccessPolicy) error { + oldVal := proto.Clone(toUpdate).(*ateapi.AccessPolicy) if err := mutate(toUpdate); err != nil { return err } @@ -145,20 +145,20 @@ func (s *ServiceImpl) UpdateAtespaceAccessPolicy(ctx context.Context, name strin return mapAccessPolicyWrite(updated, err) } -func (s *RPCService) DeleteAtespaceAccessPolicy(ctx context.Context, req *ateapipb.DeleteAtespaceAccessPolicyRequest) (*ateapipb.AccessPolicy, error) { +func (s *RPCService) DeleteAtespaceAccessPolicy(ctx context.Context, req *ateapi.DeleteAtespaceAccessPolicyRequest) (*ateapi.AccessPolicy, error) { if errs := apivalidation.ValidateDeleteAtespaceAccessPolicyRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } return s.impl.DeleteAtespaceAccessPolicy(ctx, req.GetAtespace().GetName(), toDeletePreconditions(req.GetOptions())) } -func (s *ServiceImpl) DeleteAtespaceAccessPolicy(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapipb.AccessPolicy, error) { +func (s *ServiceImpl) DeleteAtespaceAccessPolicy(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.AccessPolicy, error) { deleted, err := s.store.DeleteAtespaceAccessPolicy(ctx, name, precondition) return mapAccessPolicyWrite(deleted, err) } -func replaceAccessPolicy(policy *ateapipb.AccessPolicy) func(*ateapipb.AccessPolicy) error { - return func(toUpdate *ateapipb.AccessPolicy) error { +func replaceAccessPolicy(policy *ateapi.AccessPolicy) func(*ateapi.AccessPolicy) error { + return func(toUpdate *ateapi.AccessPolicy) error { metadata := toUpdate.GetMetadata() proto.Reset(toUpdate) proto.Merge(toUpdate, policy) @@ -168,7 +168,7 @@ func replaceAccessPolicy(policy *ateapipb.AccessPolicy) func(*ateapipb.AccessPol } } -func mapAccessPolicyWrite(policy *ateapipb.AccessPolicy, err error) (*ateapipb.AccessPolicy, error) { +func mapAccessPolicyWrite(policy *ateapi.AccessPolicy, err error) (*ateapi.AccessPolicy, error) { switch { case err == nil: return policy, nil diff --git a/cmd/ateapi/internal/controlapi/access_policy_test.go b/cmd/ateapi/internal/controlapi/access_policy_test.go index 81c29864d3..b612ce8ab3 100644 --- a/cmd/ateapi/internal/controlapi/access_policy_test.go +++ b/cmd/ateapi/internal/controlapi/access_policy_test.go @@ -19,12 +19,12 @@ import ( "strings" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/authz" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/principal" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/codes" ) @@ -65,32 +65,32 @@ func TestAccessPolicy_GlobalAndAtespaceGovernance(t *testing.T) { invoke := func(c context.Context, method string, req any, handler func(context.Context, any) (any, error)) (any, error) { return interceptor(c, req, &grpc.UnaryServerInfo{FullMethod: method}, handler) } - getGlobal := func(c context.Context) (*ateapipb.AccessPolicy, error) { - got, err := invoke(c, ateapipb.Control_GetGlobalAccessPolicy_FullMethodName, &ateapipb.GetGlobalAccessPolicyRequest{Name: resources.SingletonName}, func(c context.Context, r any) (any, error) { - return svc.GetGlobalAccessPolicy(c, r.(*ateapipb.GetGlobalAccessPolicyRequest)) + getGlobal := func(c context.Context) (*ateapi.AccessPolicy, error) { + got, err := invoke(c, ateapi.Control_GetGlobalAccessPolicy_FullMethodName, &ateapi.GetGlobalAccessPolicyRequest{Name: resources.SingletonName}, func(c context.Context, r any) (any, error) { + return svc.GetGlobalAccessPolicy(c, r.(*ateapi.GetGlobalAccessPolicyRequest)) }) if err != nil { return nil, err } - return got.(*ateapipb.AccessPolicy), nil + return got.(*ateapi.AccessPolicy), nil } - createGlobal := func(c context.Context, req *ateapipb.CreateGlobalAccessPolicyRequest) (*ateapipb.AccessPolicy, error) { - got, err := invoke(c, ateapipb.Control_CreateGlobalAccessPolicy_FullMethodName, req, func(c context.Context, r any) (any, error) { - return svc.CreateGlobalAccessPolicy(c, r.(*ateapipb.CreateGlobalAccessPolicyRequest)) + createGlobal := func(c context.Context, req *ateapi.CreateGlobalAccessPolicyRequest) (*ateapi.AccessPolicy, error) { + got, err := invoke(c, ateapi.Control_CreateGlobalAccessPolicy_FullMethodName, req, func(c context.Context, r any) (any, error) { + return svc.CreateGlobalAccessPolicy(c, r.(*ateapi.CreateGlobalAccessPolicyRequest)) }) if err != nil { return nil, err } - return got.(*ateapipb.AccessPolicy), nil + return got.(*ateapi.AccessPolicy), nil } - updateGlobal := func(c context.Context, req *ateapipb.UpdateGlobalAccessPolicyRequest) (*ateapipb.AccessPolicy, error) { - got, err := invoke(c, ateapipb.Control_UpdateGlobalAccessPolicy_FullMethodName, req, func(c context.Context, r any) (any, error) { - return svc.UpdateGlobalAccessPolicy(c, r.(*ateapipb.UpdateGlobalAccessPolicyRequest)) + updateGlobal := func(c context.Context, req *ateapi.UpdateGlobalAccessPolicyRequest) (*ateapi.AccessPolicy, error) { + got, err := invoke(c, ateapi.Control_UpdateGlobalAccessPolicy_FullMethodName, req, func(c context.Context, r any) (any, error) { + return svc.UpdateGlobalAccessPolicy(c, r.(*ateapi.UpdateGlobalAccessPolicyRequest)) }) if err != nil { return nil, err } - return got.(*ateapipb.AccessPolicy), nil + return got.(*ateapi.AccessPolicy), nil } // 1. No global policy exists at startup. Alice (bootstrap owner) is @@ -104,10 +104,10 @@ func TestAccessPolicy_GlobalAndAtespaceGovernance(t *testing.T) { // 2. CreateGlobalAccessPolicy: Bob is denied; Alice creates a policy that // does not list her, granting Dave owner and Bob viewer. - createGlobalReq := &ateapipb.CreateGlobalAccessPolicyRequest{ - AccessPolicy: &ateapipb.AccessPolicy{ - Metadata: &ateapipb.ResourceMetadata{Name: "default"}, - Bindings: []*ateapipb.Binding{ + createGlobalReq := &ateapi.CreateGlobalAccessPolicyRequest{ + AccessPolicy: &ateapi.AccessPolicy{ + Metadata: &ateapi.ResourceMetadata{Name: "default"}, + Bindings: []*ateapi.Binding{ {Role: authz.RoleOwner, Members: []string{"user:dave@example.com"}}, {Role: authz.RoleViewer, Members: []string{"user:bob@example.com"}}, }, @@ -131,10 +131,10 @@ func TestAccessPolicy_GlobalAndAtespaceGovernance(t *testing.T) { if _, err := getGlobal(bobCtx); err != nil { t.Fatalf("expected Bob (global viewer) to be allowed GetGlobalAccessPolicy, got %v", err) } - updateGlobalReq := &ateapipb.UpdateGlobalAccessPolicyRequest{ - AccessPolicy: &ateapipb.AccessPolicy{ + updateGlobalReq := &ateapi.UpdateGlobalAccessPolicyRequest{ + AccessPolicy: &ateapi.AccessPolicy{ Metadata: globalPol.GetMetadata(), - Bindings: []*ateapipb.Binding{ + Bindings: []*ateapi.Binding{ {Role: authz.RoleOwner, Members: []string{"user:dave@example.com"}}, {Role: authz.RoleViewer, Members: []string{"user:bob@example.com", "user:charlie@example.com"}}, }, @@ -158,8 +158,8 @@ func TestAccessPolicy_GlobalAndAtespaceGovernance(t *testing.T) { // 5. Empty bindings are allowed and revoke every stored grant. Alice keeps // access as a bootstrap owner, so nobody is locked out. - emptied, err := updateGlobal(aliceCtx, &ateapipb.UpdateGlobalAccessPolicyRequest{ - AccessPolicy: &ateapipb.AccessPolicy{Metadata: updatedGlobal.GetMetadata()}, + emptied, err := updateGlobal(aliceCtx, &ateapi.UpdateGlobalAccessPolicyRequest{ + AccessPolicy: &ateapi.AccessPolicy{Metadata: updatedGlobal.GetMetadata()}, }) if err != nil { t.Fatalf("UpdateGlobalAccessPolicy with empty bindings failed: %v", err) @@ -180,10 +180,10 @@ func TestAccessPolicy_GlobalAndAtespaceGovernance(t *testing.T) { // A bootstrap owner may also be listed in the stored policy; the // contextual grant then duplicates a stored tuple, which must not break // the check. - withAlice, err := updateGlobal(aliceCtx, &ateapipb.UpdateGlobalAccessPolicyRequest{ - AccessPolicy: &ateapipb.AccessPolicy{ + withAlice, err := updateGlobal(aliceCtx, &ateapi.UpdateGlobalAccessPolicyRequest{ + AccessPolicy: &ateapi.AccessPolicy{ Metadata: emptied.GetMetadata(), - Bindings: []*ateapipb.Binding{{Role: authz.RoleOwner, Members: []string{"user:alice@example.com"}}}, + Bindings: []*ateapi.Binding{{Role: authz.RoleOwner, Members: []string{"user:alice@example.com"}}}, }, }) if err != nil { @@ -202,16 +202,16 @@ func TestAccessPolicy_GlobalAndAtespaceGovernance(t *testing.T) { } restartedInterceptor := authz.UnaryServerInterceptor(restarted) getGlobalAfterRestart := func(c context.Context) error { - _, err := restartedInterceptor(c, &ateapipb.GetGlobalAccessPolicyRequest{Name: resources.SingletonName}, &grpc.UnaryServerInfo{FullMethod: ateapipb.Control_GetGlobalAccessPolicy_FullMethodName}, func(c context.Context, r any) (any, error) { - return svc.GetGlobalAccessPolicy(c, r.(*ateapipb.GetGlobalAccessPolicyRequest)) + _, err := restartedInterceptor(c, &ateapi.GetGlobalAccessPolicyRequest{Name: resources.SingletonName}, &grpc.UnaryServerInfo{FullMethod: ateapi.Control_GetGlobalAccessPolicy_FullMethodName}, func(c context.Context, r any) (any, error) { + return svc.GetGlobalAccessPolicy(c, r.(*ateapi.GetGlobalAccessPolicyRequest)) }) return err } if err := getGlobalAfterRestart(aliceCtx); err != nil { t.Fatalf("expected Alice allowed through her stored grant after removal from bootstrap owners, got %v", err) } - if _, err := updateGlobal(aliceCtx, &ateapipb.UpdateGlobalAccessPolicyRequest{ - AccessPolicy: &ateapipb.AccessPolicy{Metadata: withAlice.GetMetadata()}, + if _, err := updateGlobal(aliceCtx, &ateapi.UpdateGlobalAccessPolicyRequest{ + AccessPolicy: &ateapi.AccessPolicy{Metadata: withAlice.GetMetadata()}, }); err != nil { t.Fatalf("UpdateGlobalAccessPolicy removing Alice failed: %v", err) } @@ -226,45 +226,45 @@ func TestAccessPolicy_GlobalAndAtespaceGovernance(t *testing.T) { // atespace from her bootstrap global owner grant. CreateAtespace does not // create an AccessPolicy row; GetAtespaceAccessPolicy returns NotFound // until CreateAtespaceAccessPolicy is called. - createSpaceReq := &ateapipb.CreateAtespaceRequest{ - Atespace: &ateapipb.Atespace{ - Metadata: &ateapipb.ResourceMetadata{Name: "team-alpha"}, + createSpaceReq := &ateapi.CreateAtespaceRequest{ + Atespace: &ateapi.Atespace{ + Metadata: &ateapi.ResourceMetadata{Name: "team-alpha"}, }, } - if _, err := invoke(aliceCtx, ateapipb.Control_CreateAtespace_FullMethodName, createSpaceReq, func(c context.Context, r any) (any, error) { - return svc.CreateAtespace(c, r.(*ateapipb.CreateAtespaceRequest)) + if _, err := invoke(aliceCtx, ateapi.Control_CreateAtespace_FullMethodName, createSpaceReq, func(c context.Context, r any) (any, error) { + return svc.CreateAtespace(c, r.(*ateapi.CreateAtespaceRequest)) }); err != nil { t.Fatalf("CreateAtespace(team-alpha) failed: %v", err) } - getSpacePolReq := &ateapipb.GetAtespaceAccessPolicyRequest{ - Atespace: &ateapipb.ObjectRef{Name: "team-alpha"}, + getSpacePolReq := &ateapi.GetAtespaceAccessPolicyRequest{ + Atespace: &ateapi.ObjectRef{Name: "team-alpha"}, Name: resources.SingletonName, } - if _, err := invoke(aliceCtx, ateapipb.Control_GetAtespaceAccessPolicy_FullMethodName, getSpacePolReq, func(c context.Context, r any) (any, error) { - return svc.GetAtespaceAccessPolicy(c, r.(*ateapipb.GetAtespaceAccessPolicyRequest)) + if _, err := invoke(aliceCtx, ateapi.Control_GetAtespaceAccessPolicy_FullMethodName, getSpacePolReq, func(c context.Context, r any) (any, error) { + return svc.GetAtespaceAccessPolicy(c, r.(*ateapi.GetAtespaceAccessPolicyRequest)) }); apierror.Code(err) != codes.NotFound { t.Fatalf("expected NotFound before CreateAtespaceAccessPolicy, got %v", err) } // 8. CreateAtespaceAccessPolicy: Alice creates team-alpha's policy granting Charlie editor. - createSpacePolReq := &ateapipb.CreateAtespaceAccessPolicyRequest{ - Atespace: &ateapipb.ObjectRef{Name: "team-alpha"}, - AccessPolicy: &ateapipb.AccessPolicy{ - Metadata: &ateapipb.ResourceMetadata{Name: "default"}, - Bindings: []*ateapipb.Binding{ + createSpacePolReq := &ateapi.CreateAtespaceAccessPolicyRequest{ + Atespace: &ateapi.ObjectRef{Name: "team-alpha"}, + AccessPolicy: &ateapi.AccessPolicy{ + Metadata: &ateapi.ResourceMetadata{Name: "default"}, + Bindings: []*ateapi.Binding{ {Role: authz.RoleOwner, Members: []string{"user:alice@example.com"}}, {Role: authz.RoleEditor, Members: []string{"user:charlie@example.com"}}, }, }, } - createdSpacePolAny, err := invoke(aliceCtx, ateapipb.Control_CreateAtespaceAccessPolicy_FullMethodName, createSpacePolReq, func(c context.Context, r any) (any, error) { - return svc.CreateAtespaceAccessPolicy(c, r.(*ateapipb.CreateAtespaceAccessPolicyRequest)) + createdSpacePolAny, err := invoke(aliceCtx, ateapi.Control_CreateAtespaceAccessPolicy_FullMethodName, createSpacePolReq, func(c context.Context, r any) (any, error) { + return svc.CreateAtespaceAccessPolicy(c, r.(*ateapi.CreateAtespaceAccessPolicyRequest)) }) if err != nil { t.Fatalf("CreateAtespaceAccessPolicy(team-alpha) failed: %v", err) } - createdSpacePol := createdSpacePolAny.(*ateapipb.AccessPolicy) + createdSpacePol := createdSpacePolAny.(*ateapi.AccessPolicy) if createdSpacePol.GetMetadata().GetVersion() != 1 { t.Fatalf("expected Atespace policy version 1, got %d", createdSpacePol.GetMetadata().GetVersion()) } @@ -272,75 +272,75 @@ func TestAccessPolicy_GlobalAndAtespaceGovernance(t *testing.T) { // Charlie (editor on team-alpha) can GetAtespaceAccessPolicy (`can_get_access_policy`), // but is denied UpdateAtespaceAccessPolicy (`can_update_access_policy` requires owner) // and DeleteAtespaceAccessPolicy (`can_delete_access_policy` requires owner). - if _, err := invoke(charlieCtx, ateapipb.Control_GetAtespaceAccessPolicy_FullMethodName, getSpacePolReq, func(c context.Context, r any) (any, error) { - return svc.GetAtespaceAccessPolicy(c, r.(*ateapipb.GetAtespaceAccessPolicyRequest)) + if _, err := invoke(charlieCtx, ateapi.Control_GetAtespaceAccessPolicy_FullMethodName, getSpacePolReq, func(c context.Context, r any) (any, error) { + return svc.GetAtespaceAccessPolicy(c, r.(*ateapi.GetAtespaceAccessPolicyRequest)) }); err != nil { t.Fatalf("expected Charlie (atespace editor) allowed GetAtespaceAccessPolicy, got %v", err) } - updateSpacePolReq := &ateapipb.UpdateAtespaceAccessPolicyRequest{ - Atespace: &ateapipb.ObjectRef{Name: "team-alpha"}, - AccessPolicy: &ateapipb.AccessPolicy{ + updateSpacePolReq := &ateapi.UpdateAtespaceAccessPolicyRequest{ + Atespace: &ateapi.ObjectRef{Name: "team-alpha"}, + AccessPolicy: &ateapi.AccessPolicy{ Metadata: createdSpacePol.GetMetadata(), - Bindings: []*ateapipb.Binding{ + Bindings: []*ateapi.Binding{ {Role: authz.RoleOwner, Members: []string{"user:alice@example.com"}}, {Role: authz.RoleViewer, Members: []string{"user:charlie@example.com"}}, }, }, } - if _, err := invoke(charlieCtx, ateapipb.Control_UpdateAtespaceAccessPolicy_FullMethodName, updateSpacePolReq, func(c context.Context, r any) (any, error) { - return svc.UpdateAtespaceAccessPolicy(c, r.(*ateapipb.UpdateAtespaceAccessPolicyRequest)) + if _, err := invoke(charlieCtx, ateapi.Control_UpdateAtespaceAccessPolicy_FullMethodName, updateSpacePolReq, func(c context.Context, r any) (any, error) { + return svc.UpdateAtespaceAccessPolicy(c, r.(*ateapi.UpdateAtespaceAccessPolicyRequest)) }); apierror.Code(err) != codes.PermissionDenied { t.Fatalf("expected Charlie (atespace editor) denied UpdateAtespaceAccessPolicy, got %v", err) } - deleteSpacePolReq := &ateapipb.DeleteAtespaceAccessPolicyRequest{ - Atespace: &ateapipb.ObjectRef{Name: "team-alpha"}, + deleteSpacePolReq := &ateapi.DeleteAtespaceAccessPolicyRequest{ + Atespace: &ateapi.ObjectRef{Name: "team-alpha"}, Name: resources.SingletonName, } - if _, err := invoke(charlieCtx, ateapipb.Control_DeleteAtespaceAccessPolicy_FullMethodName, deleteSpacePolReq, func(c context.Context, r any) (any, error) { - return svc.DeleteAtespaceAccessPolicy(c, r.(*ateapipb.DeleteAtespaceAccessPolicyRequest)) + if _, err := invoke(charlieCtx, ateapi.Control_DeleteAtespaceAccessPolicy_FullMethodName, deleteSpacePolReq, func(c context.Context, r any) (any, error) { + return svc.DeleteAtespaceAccessPolicy(c, r.(*ateapi.DeleteAtespaceAccessPolicyRequest)) }); apierror.Code(err) != codes.PermissionDenied { t.Fatalf("expected Charlie (atespace editor) denied DeleteAtespaceAccessPolicy, got %v", err) } // 9. UpdateAtespaceAccessPolicy as Alice succeeds and bumps version to 2. - updatedSpacePolAny, err := invoke(aliceCtx, ateapipb.Control_UpdateAtespaceAccessPolicy_FullMethodName, updateSpacePolReq, func(c context.Context, r any) (any, error) { - return svc.UpdateAtespaceAccessPolicy(c, r.(*ateapipb.UpdateAtespaceAccessPolicyRequest)) + updatedSpacePolAny, err := invoke(aliceCtx, ateapi.Control_UpdateAtespaceAccessPolicy_FullMethodName, updateSpacePolReq, func(c context.Context, r any) (any, error) { + return svc.UpdateAtespaceAccessPolicy(c, r.(*ateapi.UpdateAtespaceAccessPolicyRequest)) }) if err != nil { t.Fatalf("UpdateAtespaceAccessPolicy(team-alpha) failed: %v", err) } - updatedSpacePol := updatedSpacePolAny.(*ateapipb.AccessPolicy) + updatedSpacePol := updatedSpacePolAny.(*ateapi.AccessPolicy) if updatedSpacePol.GetMetadata().GetVersion() != 2 { t.Fatalf("expected Atespace policy version 2, got %d", updatedSpacePol.GetMetadata().GetVersion()) } // 10. DeleteAtespaceAccessPolicy removes both the policy row and OpenFGA tuples. - if _, err := invoke(aliceCtx, ateapipb.Control_DeleteAtespaceAccessPolicy_FullMethodName, deleteSpacePolReq, func(c context.Context, r any) (any, error) { - return svc.DeleteAtespaceAccessPolicy(c, r.(*ateapipb.DeleteAtespaceAccessPolicyRequest)) + if _, err := invoke(aliceCtx, ateapi.Control_DeleteAtespaceAccessPolicy_FullMethodName, deleteSpacePolReq, func(c context.Context, r any) (any, error) { + return svc.DeleteAtespaceAccessPolicy(c, r.(*ateapi.DeleteAtespaceAccessPolicyRequest)) }); err != nil { t.Fatalf("DeleteAtespaceAccessPolicy(team-alpha) failed: %v", err) } // Charlie's tuple on team-alpha was removed, so Charlie can no longer GetAtespaceAccessPolicy. - if _, err := invoke(charlieCtx, ateapipb.Control_GetAtespaceAccessPolicy_FullMethodName, getSpacePolReq, func(c context.Context, r any) (any, error) { - return svc.GetAtespaceAccessPolicy(c, r.(*ateapipb.GetAtespaceAccessPolicyRequest)) + if _, err := invoke(charlieCtx, ateapi.Control_GetAtespaceAccessPolicy_FullMethodName, getSpacePolReq, func(c context.Context, r any) (any, error) { + return svc.GetAtespaceAccessPolicy(c, r.(*ateapi.GetAtespaceAccessPolicyRequest)) }); apierror.Code(err) != codes.PermissionDenied { t.Fatalf("expected Charlie denied after DeleteAtespaceAccessPolicy, got %v", err) } // 11. Recreate team-alpha's AccessPolicy; it gets a new UID, so an Update carrying // the old UID fails with Aborted (UID conflict). - recreatedPolAny, err := invoke(aliceCtx, ateapipb.Control_CreateAtespaceAccessPolicy_FullMethodName, createSpacePolReq, func(c context.Context, r any) (any, error) { - return svc.CreateAtespaceAccessPolicy(c, r.(*ateapipb.CreateAtespaceAccessPolicyRequest)) + recreatedPolAny, err := invoke(aliceCtx, ateapi.Control_CreateAtespaceAccessPolicy_FullMethodName, createSpacePolReq, func(c context.Context, r any) (any, error) { + return svc.CreateAtespaceAccessPolicy(c, r.(*ateapi.CreateAtespaceAccessPolicyRequest)) }) if err != nil { t.Fatalf("re-creating team-alpha access policy failed: %v", err) } - recreatedPol := recreatedPolAny.(*ateapipb.AccessPolicy) + recreatedPol := recreatedPolAny.(*ateapi.AccessPolicy) if recreatedPol.GetMetadata().GetUid() == createdSpacePol.GetMetadata().GetUid() { t.Fatalf("expected new UID on recreated access policy, got same UID %s", recreatedPol.GetMetadata().GetUid()) } - if _, err := invoke(aliceCtx, ateapipb.Control_UpdateAtespaceAccessPolicy_FullMethodName, updateSpacePolReq, func(c context.Context, r any) (any, error) { - return svc.UpdateAtespaceAccessPolicy(c, r.(*ateapipb.UpdateAtespaceAccessPolicyRequest)) + if _, err := invoke(aliceCtx, ateapi.Control_UpdateAtespaceAccessPolicy_FullMethodName, updateSpacePolReq, func(c context.Context, r any) (any, error) { + return svc.UpdateAtespaceAccessPolicy(c, r.(*ateapi.UpdateAtespaceAccessPolicyRequest)) }); apierror.Code(err) != codes.Aborted || !strings.Contains(err.Error(), "UID conflict") { t.Fatalf("expected Aborted UID conflict for UpdateAtespaceAccessPolicy with old UID, got %v", err) } diff --git a/cmd/ateapi/internal/controlapi/actor.go b/cmd/ateapi/internal/controlapi/actor.go index d212e93666..ecdef8e9f9 100644 --- a/cmd/ateapi/internal/controlapi/actor.go +++ b/cmd/ateapi/internal/controlapi/actor.go @@ -25,6 +25,7 @@ import ( "slices" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/defaults" "go.ate.dev/substrate/cmd/ateapi/internal/store" @@ -34,7 +35,6 @@ import ( "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/substratex509" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel/attribute" "google.golang.org/grpc/credentials" "google.golang.org/grpc/peer" @@ -43,7 +43,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" ) -func (s *RPCService) CreateActor(ctx context.Context, req *ateapipb.CreateActorRequest) (created *ateapipb.Actor, err error) { +func (s *RPCService) CreateActor(ctx context.Context, req *ateapi.CreateActorRequest) (created *ateapi.Actor, err error) { // First scrub any fields that users are not allowed to set, then fill the // defaults so validation sees the final resource state. inActor := req.Actor @@ -77,7 +77,7 @@ func (s *RPCService) CreateActor(ctx context.Context, req *ateapipb.CreateActorR return stored, err } -func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapipb.Actor) (*ateapipb.Actor, error) { +func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapi.Actor) (*ateapi.Actor, error) { // Check that the referenced ActorTemplate exists. // FIXME: This is not atomic and it is not a guarantee that the template // will still exist later. Checking it here produces a nice error UX, but @@ -102,7 +102,7 @@ func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapipb.Actor) } } } - var sourceTag *ateapipb.Tag + var sourceTag *ateapi.Tag if tagRef != nil { sourceTag, err = s.resolveTagSource(ctx, inActor.GetMetadata().GetAtespace(), tagRef, template) if err != nil { @@ -114,7 +114,7 @@ func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapipb.Actor) name := inActor.GetMetadata().GetName() // Volume creation is completed asynchronously after the actor is recorded. - var initVols []*ateapipb.ExternalVolumeStatus + var initVols []*ateapi.ExternalVolumeStatus if iv, err := initialExternalVolumes(ctx, s.storageClassLister, template); err != nil { return nil, err } else if preview.IsEnabledFor(ctx, preview.GateExternalVolumes) { @@ -129,8 +129,8 @@ func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapipb.Actor) // Verify that the result is properly valid before storing it. outActor := proto.CloneOf(inActor) - outActor.Status = &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + outActor.Status = &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, ExternalVolumes: externalVolumesStatus(initVols), } if sourceTag != nil { @@ -141,11 +141,11 @@ func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapipb.Actor) // there. snap := proto.CloneOf(sourceTag.GetStatus().GetSnapshot()) snap.Generation = 1 - snap.Owner = ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG + snap.Owner = ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG // The Actor is born with guest state, so stamp the template that state // was built on now rather than at the first resume. snap.ActorTemplateUid = sourceTag.GetStatus().GetActorTemplateUid() - outActor.Status.Snapshots = []*ateapipb.Snapshot{snap} + outActor.Status.Snapshots = []*ateapi.Snapshot{snap} outActor.Status.LastAssignedGeneration = 1 } if errs := apivalidation.ValidateActorUpdate(ctx, field.NewPath("actor"), outActor, inActor, true); len(errs) > 0 { @@ -174,7 +174,7 @@ func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapipb.Actor) // resolveTagSource resolves a CreateActor request's source tag // and checks that the tag is usable for creating an Actor in actorAtespace // from template. -func (s *ServiceImpl) resolveTagSource(ctx context.Context, actorAtespace string, tagRef *ateapipb.ObjectRef, template *ateapipb.ActorTemplate) (*ateapipb.Tag, error) { +func (s *ServiceImpl) resolveTagSource(ctx context.Context, actorAtespace string, tagRef *ateapi.ObjectRef, template *ateapi.ActorTemplate) (*ateapi.Tag, error) { tag, err := s.store.GetTag(ctx, resources.TagRefFromObjectRef(tagRef)) if errors.Is(err, store.ErrNotFound) { return nil, apierror.FailedPrecondition("Tag not found") @@ -183,18 +183,18 @@ func (s *ServiceImpl) resolveTagSource(ctx context.Context, actorAtespace string return nil, fmt.Errorf("while getting tag: %w", err) } switch tag.GetScope() { - case ateapipb.TagScope_TAG_SCOPE_ATESPACE: + case ateapi.TagScope_TAG_SCOPE_ATESPACE: if tag.GetMetadata().GetAtespace() != actorAtespace { return nil, apierror.FailedPrecondition("Tag is not published outside its Atespace") } - case ateapipb.TagScope_TAG_SCOPE_PUBLISHED: + case ateapi.TagScope_TAG_SCOPE_PUBLISHED: default: return nil, apierror.FailedPrecondition("source Tag has an invalid scope") } // TODO: Refuse a tag with delete_time set. DeleteTag may already have // collected its snapshot. // A tag might have an empty Snapshot URI if the tag creation failed or is ongoing. - if tagDurableSnapshotURI(tag, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) == "" { + if tagDurableSnapshotURI(tag, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) == "" { return nil, apierror.FailedPrecondition("source Tag is still being created or failed creation") } // TODO: Permit compatible VOLUMES snapshots when runtimes can extract portable data. @@ -204,7 +204,7 @@ func (s *ServiceImpl) resolveTagSource(ctx context.Context, actorAtespace string return tag, nil } -func (s *RPCService) GetActor(ctx context.Context, req *ateapipb.GetActorRequest) (*ateapipb.Actor, error) { +func (s *RPCService) GetActor(ctx context.Context, req *ateapi.GetActorRequest) (*ateapi.Actor, error) { if errs := apivalidation.ValidateGetActorRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -218,11 +218,11 @@ func (s *RPCService) GetActor(ctx context.Context, req *ateapipb.GetActorRequest return actor, nil } -func (s *ServiceImpl) GetActor(ctx context.Context, actorRef resources.ActorRef) (*ateapipb.Actor, error) { +func (s *ServiceImpl) GetActor(ctx context.Context, actorRef resources.ActorRef) (*ateapi.Actor, error) { return s.store.GetActor(ctx, actorRef) } -func (s *RPCService) ListActors(ctx context.Context, req *ateapipb.ListActorsRequest) (*ateapipb.ListActorsResponse, error) { +func (s *RPCService) ListActors(ctx context.Context, req *ateapi.ListActorsRequest) (*ateapi.ListActorsResponse, error) { if errs := apivalidation.ValidateListActorsRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -231,17 +231,17 @@ func (s *RPCService) ListActors(ctx context.Context, req *ateapipb.ListActorsReq if err != nil { return nil, mapListError(fmt.Errorf("while listing actors in db: %w", err)) } - return &ateapipb.ListActorsResponse{ + return &ateapi.ListActorsResponse{ Actors: page.Items, NextPageToken: page.NextPageToken, }, nil } -func (s *ServiceImpl) ListActors(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapipb.Actor], error) { +func (s *ServiceImpl) ListActors(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapi.Actor], error) { return s.store.ListActors(ctx, atespace, opts) } -func (s *RPCService) UpdateActor(ctx context.Context, req *ateapipb.UpdateActorRequest) (*ateapipb.Actor, error) { +func (s *RPCService) UpdateActor(ctx context.Context, req *ateapi.UpdateActorRequest) (*ateapi.Actor, error) { // First scrub any fields that users are not allowed to set. inActor := req.Actor if inActor != nil { // otherwise validation will flag it @@ -257,7 +257,7 @@ func (s *RPCService) UpdateActor(ctx context.Context, req *ateapipb.UpdateActorR actorRef := resources.ActorRefFromActor(inActor) setSpanActorRefAttributes(ctx, actorRef) - storedActor, err := s.impl.UpdateActor(ctx, actorRef, store.PreconditionFrom(inActor), func(toUpdate *ateapipb.Actor) error { + storedActor, err := s.impl.UpdateActor(ctx, actorRef, store.PreconditionFrom(inActor), func(toUpdate *ateapi.Actor) error { // Status and Metadata are server-owned fields. status, metadata := toUpdate.GetStatus(), toUpdate.GetMetadata() // Whole-object replace: clear first, so a field the client left unset is @@ -280,8 +280,8 @@ func (s *RPCService) UpdateActor(ctx context.Context, req *ateapipb.UpdateActorR return storedActor, err } -func (s *ServiceImpl) UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(*ateapipb.Actor) error) (*ateapipb.Actor, error) { - storedActor, err := s.store.UpdateActor(ctx, actorRef, precondition, func(toUpdate *ateapipb.Actor) error { +func (s *ServiceImpl) UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(*ateapi.Actor) error) (*ateapi.Actor, error) { + storedActor, err := s.store.UpdateActor(ctx, actorRef, precondition, func(toUpdate *ateapi.Actor) error { // Apply the mutation function to the stored value. oldVal := proto.CloneOf(toUpdate) if err := mutate(toUpdate); err != nil { @@ -303,9 +303,9 @@ func (s *ServiceImpl) UpdateActor(ctx context.Context, actorRef resources.ActorR // the old template's. It must also store snapshots under the location // the actor's own already live in. if !proto.Equal(oldVal.GetActorTemplate(), newVal.GetActorTemplate()) { - if state := oldVal.GetStatus().GetState(); state != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if state := oldVal.GetStatus().GetState(); state != ateapi.ActorState_ACTOR_STATE_SUSPENDED { return apierror.FailedPrecondition( - "actor must be %s to change its actor template (got: %s)", ateapipb.ActorState_ACTOR_STATE_SUSPENDED, state) + "actor must be %s to change its actor template (got: %s)", ateapi.ActorState_ACTOR_STATE_SUSPENDED, state) } newTemplate, err := resolveActorTemplate(ctx, s.store, newVal) if err != nil { @@ -360,15 +360,15 @@ func (s *ServiceImpl) UpdateActor(ctx context.Context, actorRef resources.ActorR // volumes list must be identical, and containers present in both templates // must keep identical mounts, order included; containers added or removed by // the new template are unconstrained. -func validateTemplateVolumesUnchanged(oldTemplate, newTemplate *ateapipb.ActorTemplate) error { - if !slices.EqualFunc(oldTemplate.GetVolumes(), newTemplate.GetVolumes(), func(a, b *ateapipb.Volume) bool { +func validateTemplateVolumesUnchanged(oldTemplate, newTemplate *ateapi.ActorTemplate) error { + if !slices.EqualFunc(oldTemplate.GetVolumes(), newTemplate.GetVolumes(), func(a, b *ateapi.Volume) bool { return proto.Equal(a, b) }) { return apierror.FailedPrecondition( "volumes differ between the current and the new actor template; volumes must be identical to repoint an actor") } - newContainers := make(map[string]*ateapipb.Container, len(newTemplate.GetContainers())) + newContainers := make(map[string]*ateapi.Container, len(newTemplate.GetContainers())) for _, c := range newTemplate.GetContainers() { newContainers[c.GetName()] = c } @@ -377,7 +377,7 @@ func validateTemplateVolumesUnchanged(oldTemplate, newTemplate *ateapipb.ActorTe if !ok { continue } - if !slices.EqualFunc(oldC.GetVolumeMounts(), newC.GetVolumeMounts(), func(a, b *ateapipb.VolumeMount) bool { + if !slices.EqualFunc(oldC.GetVolumeMounts(), newC.GetVolumeMounts(), func(a, b *ateapi.VolumeMount) bool { return proto.Equal(a, b) }) { return apierror.FailedPrecondition( @@ -392,8 +392,8 @@ func validateTemplateVolumesUnchanged(oldTemplate, newTemplate *ateapipb.ActorTe // already owns. This is needed to not leak snapshots when the actor is deleted: // Deleting an actor collects everything under its external snapshot prefix. If // the location prefix ever changes, we risk leaking the snapshots under the old prefix. -func (s *ServiceImpl) validateSnapshotLocationUnchanged(actor *ateapipb.Actor, newTemplate *ateapipb.ActorTemplate) error { - snap := latestSnapshot(actor.GetStatus(), func(snapshot *ateapipb.Snapshot) bool { +func (s *ServiceImpl) validateSnapshotLocationUnchanged(actor *ateapi.Actor, newTemplate *ateapi.ActorTemplate) error { + snap := latestSnapshot(actor.GetStatus(), func(snapshot *ateapi.Snapshot) bool { return snapshot.GetDurableSnapshot().GetObject().GetSnapshotUri() != "" }) currentSnapshotURI := snap.GetDurableSnapshot().GetObject().GetSnapshotUri() @@ -427,7 +427,7 @@ func (s *ServiceImpl) validateSnapshotLocationUnchanged(actor *ateapipb.Actor, n return nil } -func (s *RPCService) DeleteActor(ctx context.Context, req *ateapipb.DeleteActorRequest) (deleted *ateapipb.Actor, err error) { +func (s *RPCService) DeleteActor(ctx context.Context, req *ateapi.DeleteActorRequest) (deleted *ateapi.Actor, err error) { if errs := apivalidation.ValidateDeleteActorRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -456,15 +456,15 @@ func (s *RPCService) DeleteActor(ctx context.Context, req *ateapipb.DeleteActorR return deleted, nil } -func (s *ServiceImpl) MarkActorForDeletion(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions, mutate func(*ateapipb.Actor) error) (*ateapipb.Actor, error) { +func (s *ServiceImpl) MarkActorForDeletion(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions, mutate func(*ateapi.Actor) error) (*ateapi.Actor, error) { return s.store.MarkActorForDeletion(ctx, actorRef, precondition, mutate) } -func (s *ServiceImpl) DeleteActor(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (*ateapipb.Actor, error) { +func (s *ServiceImpl) DeleteActor(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (*ateapi.Actor, error) { return s.store.DeleteActor(ctx, actorRef, precondition) } -func (s *RPCService) ResumeActor(ctx context.Context, req *ateapipb.ResumeActorRequest) (*ateapipb.ResumeActorResponse, error) { +func (s *RPCService) ResumeActor(ctx context.Context, req *ateapi.ResumeActorRequest) (*ateapi.ResumeActorResponse, error) { if errs := apivalidation.ValidateResumeActorRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -483,10 +483,10 @@ func (s *RPCService) ResumeActor(ctx context.Context, req *ateapipb.ResumeActorR } setSpanActorAttributes(ctx, actor) - return &ateapipb.ResumeActorResponse{Actor: actor, Resumed: resumed}, nil + return &ateapi.ResumeActorResponse{Actor: actor, Resumed: resumed}, nil } -func (s *RPCService) SuspendActor(ctx context.Context, req *ateapipb.SuspendActorRequest) (*ateapipb.SuspendActorResponse, error) { +func (s *RPCService) SuspendActor(ctx context.Context, req *ateapi.SuspendActorRequest) (*ateapi.SuspendActorResponse, error) { if errs := apivalidation.ValidateSuspendActorRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -504,12 +504,12 @@ func (s *RPCService) SuspendActor(ctx context.Context, req *ateapipb.SuspendActo return nil, err } setSpanActorAttributes(ctx, actor) - return &ateapipb.SuspendActorResponse{Actor: actor}, nil + return &ateapi.SuspendActorResponse{Actor: actor}, nil } // CrashActorReportedByWorker crashes a RUNNING actor whose sandbox died, on // behalf of the worker hosting it. The caller authorizes the worker. -func (s *RPCService) CrashActorReportedByWorker(ctx context.Context, actorRef resources.ActorRef, actorUID, workerName, message string) (*ateapipb.Actor, error) { +func (s *RPCService) CrashActorReportedByWorker(ctx context.Context, actorRef resources.ActorRef, actorUID, workerName, message string) (*ateapi.Actor, error) { setSpanActorRefAttributes(ctx, actorRef) actor, err := s.actorWorkflow.CrashActorReportedByWorker(ctx, actorRef, actorUID, workerName, message) if err != nil { @@ -522,7 +522,7 @@ func (s *RPCService) CrashActorReportedByWorker(ctx context.Context, actorRef re return actor, nil } -func (s *RPCService) RevertActor(ctx context.Context, req *ateapipb.RevertActorRequest) (*ateapipb.RevertActorResponse, error) { +func (s *RPCService) RevertActor(ctx context.Context, req *ateapi.RevertActorRequest) (*ateapi.RevertActorResponse, error) { if errs := apivalidation.ValidateRevertActorRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -540,10 +540,10 @@ func (s *RPCService) RevertActor(ctx context.Context, req *ateapipb.RevertActorR return nil, err } setSpanActorAttributes(ctx, actor) - return &ateapipb.RevertActorResponse{Actor: actor}, nil + return &ateapi.RevertActorResponse{Actor: actor}, nil } -func (s *RPCService) MintActorJwt(ctx context.Context, req *ateapipb.MintActorJwtRequest) (*ateapipb.MintActorJwtResponse, error) { +func (s *RPCService) MintActorJwt(ctx context.Context, req *ateapi.MintActorJwtRequest) (*ateapi.MintActorJwtResponse, error) { if errs := apivalidation.ValidateMintActorJWTRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -591,13 +591,13 @@ func (s *RPCService) MintActorJwt(ctx context.Context, req *ateapipb.MintActorJw return nil, fmt.Errorf("while signing actor JWT: %w", err) } - return &ateapipb.MintActorJwtResponse{ + return &ateapi.MintActorJwtResponse{ ActorJwt: actorJWT, ExpireTime: timestamppb.New(expiresAt), }, nil } -func (s *RPCService) MintActorCertificate(ctx context.Context, req *ateapipb.MintActorCertificateRequest) (*ateapipb.MintActorCertificateResponse, error) { +func (s *RPCService) MintActorCertificate(ctx context.Context, req *ateapi.MintActorCertificateRequest) (*ateapi.MintActorCertificateResponse, error) { if errs := apivalidation.ValidateMintActorCertificateRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -676,7 +676,7 @@ func (s *RPCService) MintActorCertificate(ctx context.Context, req *ateapipb.Min return nil, fmt.Errorf("while signing certificate: %w", err) } - return &ateapipb.MintActorCertificateResponse{ + return &ateapi.MintActorCertificateResponse{ ActorCertificates: chain, }, nil } diff --git a/cmd/ateapi/internal/controlapi/actor_template.go b/cmd/ateapi/internal/controlapi/actor_template.go index cf2c77fab1..d55ae5bf4e 100644 --- a/cmd/ateapi/internal/controlapi/actor_template.go +++ b/cmd/ateapi/internal/controlapi/actor_template.go @@ -19,17 +19,17 @@ import ( "errors" "fmt" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/defaults" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" "k8s.io/apimachinery/pkg/util/validation/field" ) -func (s *RPCService) CreateActorTemplate(ctx context.Context, req *ateapipb.CreateActorTemplateRequest) (*ateapipb.ActorTemplate, error) { +func (s *RPCService) CreateActorTemplate(ctx context.Context, req *ateapi.CreateActorTemplateRequest) (*ateapi.ActorTemplate, error) { // First scrub any fields that users are not allowed to set, then fill the // defaults so validation sees the final resource state. in := req.GetActorTemplate() @@ -60,10 +60,10 @@ func (s *RPCService) CreateActorTemplate(ctx context.Context, req *ateapipb.Crea return stored, nil } -func (s *ServiceImpl) CreateActorTemplate(ctx context.Context, inTemplate *ateapipb.ActorTemplate) (*ateapipb.ActorTemplate, error) { +func (s *ServiceImpl) CreateActorTemplate(ctx context.Context, inTemplate *ateapi.ActorTemplate) (*ateapi.ActorTemplate, error) { // Build the stored object: status is server-owned and starts empty. - outTemplate := proto.Clone(inTemplate).(*ateapipb.ActorTemplate) - outTemplate.Status = &ateapipb.ActorTemplateStatus{} + outTemplate := proto.Clone(inTemplate).(*ateapi.ActorTemplate) + outTemplate.Status = &ateapi.ActorTemplateStatus{} // Validate the final value before storing it. if errs := apivalidation.ValidateActorTemplateUpdate(ctx, field.NewPath("actor_template"), outTemplate, inTemplate); len(errs) > 0 { @@ -79,7 +79,7 @@ func (s *ServiceImpl) CreateActorTemplate(ctx context.Context, inTemplate *ateap return s.store.CreateActorTemplate(ctx, outTemplate) } -func (s *RPCService) GetActorTemplate(ctx context.Context, req *ateapipb.GetActorTemplateRequest) (*ateapipb.ActorTemplate, error) { +func (s *RPCService) GetActorTemplate(ctx context.Context, req *ateapi.GetActorTemplateRequest) (*ateapi.ActorTemplate, error) { if errs := apivalidation.ValidateGetActorTemplateRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -95,12 +95,12 @@ func (s *RPCService) GetActorTemplate(ctx context.Context, req *ateapipb.GetActo return template, nil } -func (s *ServiceImpl) GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapipb.ActorTemplate, error) { +func (s *ServiceImpl) GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapi.ActorTemplate, error) { // TODO: implement this return s.store.GetActorTemplate(ctx, templateRef) } -func (s *RPCService) ListActorTemplates(ctx context.Context, req *ateapipb.ListActorTemplatesRequest) (*ateapipb.ListActorTemplatesResponse, error) { +func (s *RPCService) ListActorTemplates(ctx context.Context, req *ateapi.ListActorTemplatesRequest) (*ateapi.ListActorTemplatesResponse, error) { if errs := apivalidation.ValidateListActorTemplatesRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -109,34 +109,34 @@ func (s *RPCService) ListActorTemplates(ctx context.Context, req *ateapipb.ListA if err != nil { return nil, mapListError(fmt.Errorf("while listing actor templates in db: %w", err)) } - return &ateapipb.ListActorTemplatesResponse{ + return &ateapi.ListActorTemplatesResponse{ ActorTemplates: page.Items, NextPageToken: page.NextPageToken, }, nil } -func (s *ServiceImpl) ListActorTemplates(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapipb.ActorTemplate], error) { +func (s *ServiceImpl) ListActorTemplates(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapi.ActorTemplate], error) { // TODO: implement this return s.store.ListActorTemplates(ctx, atespace, opts) } -func (s *RPCService) DeleteActorTemplate(ctx context.Context, req *ateapipb.DeleteActorTemplateRequest) (*ateapipb.ActorTemplate, error) { +func (s *RPCService) DeleteActorTemplate(ctx context.Context, req *ateapi.DeleteActorTemplateRequest) (*ateapi.ActorTemplate, error) { if errs := apivalidation.ValidateDeleteActorTemplateRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } return s.actorWorkflow.DeleteActorTemplate(ctx, resources.ActorTemplateRefFromObjectRef(req.GetActorTemplate()), toDeletePreconditions(req.GetOptions())) } -func (s *ServiceImpl) MarkActorTemplateForDeletion(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions, mutate func(*ateapipb.ActorTemplate) error) (*ateapipb.ActorTemplate, error) { +func (s *ServiceImpl) MarkActorTemplateForDeletion(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions, mutate func(*ateapi.ActorTemplate) error) (*ateapi.ActorTemplate, error) { return s.store.MarkActorTemplateForDeletion(ctx, templateRef, precondition, mutate) } -func (s *ServiceImpl) DeleteActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions) (*ateapipb.ActorTemplate, error) { +func (s *ServiceImpl) DeleteActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions) (*ateapi.ActorTemplate, error) { // TODO: implement this return s.store.DeleteActorTemplate(ctx, templateRef, precondition) } -func (s *ServiceImpl) UpdateActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.Precondition, mutate func(dbTemplate *ateapipb.ActorTemplate) error) (*ateapipb.ActorTemplate, error) { +func (s *ServiceImpl) UpdateActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.Precondition, mutate func(dbTemplate *ateapi.ActorTemplate) error) (*ateapi.ActorTemplate, error) { // ActorTemplates are immutable to clients: there is no update RPC, and // the only writer is the template reconciler, which updates status // against the store directly. The store enforces metadata immutability, @@ -146,7 +146,7 @@ func (s *ServiceImpl) UpdateActorTemplate(ctx context.Context, templateRef resou // actorTemplateGetter is the storage subset template resolution needs. type actorTemplateGetter interface { - GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapipb.ActorTemplate, error) + GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapi.ActorTemplate, error) } // errActorTemplateNotFound matches (via errors.Is) resolution failures where @@ -158,7 +158,7 @@ var errActorTemplateNotFound = apierror.FailedPrecondition("actor template not f // resolveActorTemplate resolves the substrate ActorTemplate the actor's // actor_template ref names. A missing template surfaces as // errActorTemplateNotFound. -func resolveActorTemplate(ctx context.Context, st actorTemplateGetter, actor *ateapipb.Actor) (*ateapipb.ActorTemplate, error) { +func resolveActorTemplate(ctx context.Context, st actorTemplateGetter, actor *ateapi.Actor) (*ateapi.ActorTemplate, error) { templateRef := resources.ActorTemplateRefFromObjectRef(actor.GetActorTemplate()) template, err := st.GetActorTemplate(ctx, templateRef) if errors.Is(err, store.ErrNotFound) { diff --git a/cmd/ateapi/internal/controlapi/actor_template_test.go b/cmd/ateapi/internal/controlapi/actor_template_test.go index 36964f2026..b68f8ff73b 100644 --- a/cmd/ateapi/internal/controlapi/actor_template_test.go +++ b/cmd/ateapi/internal/controlapi/actor_template_test.go @@ -22,13 +22,13 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/objectstoreplugin/objectstoreplugintest" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/testing/protocmp" ) @@ -37,15 +37,15 @@ import ( // validation; mutations tweak it per test case. The snapshot scopes and // resume policy are set explicitly because TestValidateActorTemplate // exercises validation directly, without defaulting. -func validActorTemplate(mutations ...func(*ateapipb.ActorTemplate)) *ateapipb.ActorTemplate { - template := &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ns1", Name: "tmpl-a"}, - Containers: []*ateapipb.Container{{Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}, - SnapshotConfig: &ateapipb.SnapshotConfig{ +func validActorTemplate(mutations ...func(*ateapi.ActorTemplate)) *ateapi.ActorTemplate { + template := &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ns1", Name: "tmpl-a"}, + Containers: []*ateapi.Container{{Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}, + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: "gs://my-bucket/snapshots", - PreferredFidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + PreferredFidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, }, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, } for _, m := range mutations { m(template) @@ -59,9 +59,9 @@ func TestCreateActorTemplate(t *testing.T) { persistence := newTestPersistence(t) s := &RPCService{impl: newServiceImpl(persistence, nil)} ctx := context.Background() - req := func(atespace, name string) *ateapipb.CreateActorTemplateRequest { - return &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.Metadata = &ateapipb.ResourceMetadata{Atespace: atespace, Name: name} + req := func(atespace, name string) *ateapi.CreateActorTemplateRequest { + return &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.Metadata = &ateapi.ResourceMetadata{Atespace: atespace, Name: name} })} } @@ -69,7 +69,7 @@ func TestCreateActorTemplate(t *testing.T) { t.Errorf("CreateActorTemplate in missing atespace = %v, want FailedPrecondition", err) } - if _, err := persistence.CreateAtespace(ctx, &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "ns1"}}); err != nil { + if _, err := persistence.CreateAtespace(ctx, &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "ns1"}}); err != nil { t.Fatalf("CreateAtespace failed: %v", err) } created, err := s.CreateActorTemplate(ctx, req("ns1", "tmpl-a")) @@ -130,14 +130,14 @@ func TestCreateActorTemplate_RequiresSnapshotLocation(t *testing.T) { impl.clusterSnapshotLocation = tt.clusterSnapshotLocation s := &RPCService{impl: impl} ctx := context.Background() - if _, err := persistence.CreateAtespace(ctx, &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "ns1"}}); err != nil { + if _, err := persistence.CreateAtespace(ctx, &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "ns1"}}); err != nil { t.Fatalf("CreateAtespace failed: %v", err) } if tt.optOut { ctx = preview.ContextWithOptOut(ctx) } - req := &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.Metadata = &ateapipb.ResourceMetadata{Atespace: "ns1", Name: fmt.Sprintf("tmpl-%d", i)} + req := &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.Metadata = &ateapi.ResourceMetadata{Atespace: "ns1", Name: fmt.Sprintf("tmpl-%d", i)} tmpl.SnapshotConfig.StorageLocation = tt.location })} if _, err := s.CreateActorTemplate(ctx, req); apierror.Code(err) != tt.wantCode { @@ -156,35 +156,35 @@ func TestCreateActorTemplateIgnoresServerOwnedFields(t *testing.T) { s := &RPCService{impl: newServiceImpl(persistence, nil)} ctx := context.Background() - if _, err := persistence.CreateAtespace(ctx, &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "ns1"}}); err != nil { + if _, err := persistence.CreateAtespace(ctx, &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "ns1"}}); err != nil { t.Fatalf("CreateAtespace failed: %v", err) } - in := validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + in := validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.Metadata.Uid = "11111111-1111-1111-1111-111111111111" tmpl.Metadata.Version = 42 - tmpl.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"pool": "default"}} - tmpl.Containers = []*ateapipb.Container{{Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}} - tmpl.Resources = &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 1<<30)} + tmpl.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"pool": "default"}} + tmpl.Containers = []*ateapi.Container{{Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}} + tmpl.Resources = &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 1<<30)} // Server-owned status a client must not be able to set. - tmpl.Status = &ateapipb.ActorTemplateStatus{ - GoldenSnapshotStatus: &ateapipb.GoldenSnapshotStatus{ - GoldenTag: &ateapipb.ObjectRef{Atespace: "ns1", Name: "golden-tag"}, + tmpl.Status = &ateapi.ActorTemplateStatus{ + GoldenSnapshotStatus: &ateapi.GoldenSnapshotStatus{ + GoldenTag: &ateapi.ObjectRef{Atespace: "ns1", Name: "golden-tag"}, }, } }) - created, err := s.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ActorTemplate: in}) + created, err := s.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ActorTemplate: in}) if err != nil { t.Fatalf("CreateActorTemplate failed: %v", err) } - want := validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + want := validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.Metadata.Version = 1 - tmpl.SnapshotConfig.GoldenSnapshotConfig = &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED} + tmpl.SnapshotConfig.GoldenSnapshotConfig = &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED} tmpl.WorkerSelector = in.GetWorkerSelector() tmpl.Containers = in.GetContainers() tmpl.Resources = in.GetResources() - tmpl.Status = &ateapipb.ActorTemplateStatus{} + tmpl.Status = &ateapi.ActorTemplateStatus{} }) if diff := cmp.Diff(want, created, protocmp.Transform(), ignoreUID, ignoreTimestamps); diff != "" { t.Errorf("CreateActorTemplate response mismatch (-want +got):\n%s", diff) @@ -202,19 +202,19 @@ func TestCreateActorTemplateDefaultsOmittedSnapshotConfig(t *testing.T) { impl.clusterSnapshotLocation = "gs://cluster-bucket/" s := &RPCService{impl: impl} ctx := context.Background() - if _, err := persistence.CreateAtespace(ctx, &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "ns1"}}); err != nil { + if _, err := persistence.CreateAtespace(ctx, &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "ns1"}}); err != nil { t.Fatalf("CreateAtespace failed: %v", err) } - created, err := s.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { + created, err := s.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.SnapshotConfig = nil })}) if err != nil { t.Fatalf("CreateActorTemplate failed: %v", err) } - want := &ateapipb.SnapshotConfig{ - PreferredFidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - GoldenSnapshotConfig: &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, + want := &ateapi.SnapshotConfig{ + PreferredFidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + GoldenSnapshotConfig: &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, } if diff := cmp.Diff(want, created.GetSnapshotConfig(), protocmp.Transform()); diff != "" { t.Errorf("CreateActorTemplate snapshot_config mismatch (-want +got):\n%s", diff) @@ -248,21 +248,21 @@ func TestDeleteActorTemplate(t *testing.T) { tmpl := seedSubstrateTemplate(t, ctx, persistence, "tmpl") templateRef := resources.ActorTemplateRefFromActorTemplate(tmpl) goldenRef := resources.ActorRef{Atespace: "team-a", Name: tmpl.GetMetadata().GetUid()} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: goldenRef.Atespace, Name: goldenRef.Name}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: goldenRef.Atespace, Name: goldenRef.Name}, ActorTemplate: templateRef.ToObjectRef(), - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) workflow, objects := newFinalizeWorkflow(persistence) actorURI := mustActorSnapshotURI(t, tmpl, actor, "snapshot") objects.PutSnapshot(t, actorURI, "manifest.json") - actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 1 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), actorURI.Name(), actorURI.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), actorURI.Name(), actorURI.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), } }) - var tag *ateapipb.Tag + var tag *ateapi.Tag if tt.pendingTag { tag = storetest.MustCreateTag(t, ctx, persistence, newPendingTestTag(t, goldenRef.Name, actor)) } else { @@ -277,8 +277,8 @@ func TestDeleteActorTemplate(t *testing.T) { objects.PutSnapshot(t, tagURI, "manifest.json") svc := &RPCService{impl: newServiceImpl(persistence, nil), actorWorkflow: workflow, objectStorePlugin: objectstoreplugintest.ControlClient(objects)} // The handler must clean up an active golden actor. - mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { - s.State = ateapipb.ActorState_ACTOR_STATE_RUNNING + mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { + s.State = ateapi.ActorState_ACTOR_STATE_RUNNING }) if tt.actorDeleted { if _, err := workflow.DeleteActor(ctx, goldenRef, store.DeletePreconditions{}); err != nil { @@ -286,7 +286,7 @@ func TestDeleteActorTemplate(t *testing.T) { } } if tt.tagDeleted { - if _, err := svc.DeleteTag(ctx, &ateapipb.DeleteTagRequest{Tag: tagRef.ToObjectRef()}); err != nil { + if _, err := svc.DeleteTag(ctx, &ateapi.DeleteTagRequest{Tag: tagRef.ToObjectRef()}); err != nil { t.Fatal(err) } } @@ -317,7 +317,7 @@ func TestDeleteActorTemplate(t *testing.T) { t.Fatalf("template after the refused delete = %v, %v; want it present and not marked", current, err) } } - req := &ateapipb.DeleteActorTemplateRequest{ActorTemplate: templateRef.ToObjectRef()} + req := &ateapi.DeleteActorTemplateRequest{ActorTemplate: templateRef.ToObjectRef()} deleted, err := svc.DeleteActorTemplate(ctx, req) if tt.failPrefix != "" { if !isObjectStoreErr(err) { @@ -381,11 +381,11 @@ func TestDeleteActorTemplate(t *testing.T) { } // seedSubstrateTemplate stores a minimal substrate ActorTemplate in team-a. -func seedSubstrateTemplate(t *testing.T, ctx context.Context, persistence store.Interface, name string) *ateapipb.ActorTemplate { +func seedSubstrateTemplate(t *testing.T, ctx context.Context, persistence store.Interface, name string) *ateapi.ActorTemplate { t.Helper() - created, err := persistence.CreateActorTemplate(ctx, &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: name}, - SnapshotConfig: &ateapipb.SnapshotConfig{ + created, err := persistence.CreateActorTemplate(ctx, &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: name}, + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: "gs://ate-snapshots/team-a/", }, }) @@ -407,7 +407,7 @@ func TestResolveActorTemplate(t *testing.T) { stored := seedSubstrateTemplate(t, ctx, persistence, "sub-tmpl") t.Run("ref reads the store", func(t *testing.T) { - actor := &ateapipb.Actor{ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}} + actor := &ateapi.Actor{ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}} got, err := resolveActorTemplate(ctx, persistence, actor) if err != nil { t.Fatalf("resolveActorTemplate: %v", err) @@ -418,7 +418,7 @@ func TestResolveActorTemplate(t *testing.T) { }) t.Run("ref to a missing template is FailedPrecondition", func(t *testing.T) { - actor := &ateapipb.Actor{ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "absent"}} + actor := &ateapi.Actor{ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "absent"}} _, err := resolveActorTemplate(ctx, persistence, actor) if got := apierror.Code(err); got != codes.FailedPrecondition { t.Fatalf("status.Code = %v, want FailedPrecondition (err: %v)", got, err) @@ -436,12 +436,12 @@ func TestResolveActorTemplate_NotFound(t *testing.T) { tests := []struct { name string - actor *ateapipb.Actor + actor *ateapi.Actor wantNotFound bool }{ - {"ref resolves", &ateapipb.Actor{ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}}, false}, - {"ref to deleted template", &ateapipb.Actor{ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "gone"}}, true}, - {"no template named at all", &ateapipb.Actor{}, true}, + {"ref resolves", &ateapi.Actor{ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}}, false}, + {"ref to deleted template", &ateapi.Actor{ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "gone"}}, true}, + {"no template named at all", &ateapi.Actor{}, true}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { @@ -469,7 +469,7 @@ func TestUpdateActorTemplateMetadata(t *testing.T) { persistence := newTestPersistence(t) ctx := context.Background() - if _, err := persistence.CreateAtespace(ctx, &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "ns1"}}); err != nil { + if _, err := persistence.CreateAtespace(ctx, &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "ns1"}}); err != nil { t.Fatalf("CreateAtespace failed: %v", err) } created, err := persistence.CreateActorTemplate(ctx, validActorTemplate()) @@ -479,9 +479,9 @@ func TestUpdateActorTemplateMetadata(t *testing.T) { ref := resources.ActorTemplateRefFromActorTemplate(created) // A server-owned status write passes validation and bumps the version. - updated, err := persistence.UpdateActorTemplate(ctx, ref, store.PreconditionFrom(created), func(tmpl *ateapipb.ActorTemplate) error { - tmpl.Status = &ateapipb.ActorTemplateStatus{GoldenSnapshotStatus: &ateapipb.GoldenSnapshotStatus{ - GoldenTag: &ateapipb.ObjectRef{Atespace: "ns1", Name: "golden-tag"}, + updated, err := persistence.UpdateActorTemplate(ctx, ref, store.PreconditionFrom(created), func(tmpl *ateapi.ActorTemplate) error { + tmpl.Status = &ateapi.ActorTemplateStatus{GoldenSnapshotStatus: &ateapi.GoldenSnapshotStatus{ + GoldenTag: &ateapi.ObjectRef{Atespace: "ns1", Name: "golden-tag"}, }} return nil }) @@ -494,9 +494,9 @@ func TestUpdateActorTemplateMetadata(t *testing.T) { // A mutation that touches an immutable field is a server bug, rejected by // the store. - for name, mutate := range map[string]func(*ateapipb.ActorTemplate) error{ - "atespace": func(tmpl *ateapipb.ActorTemplate) error { tmpl.Metadata.Atespace = "ns2"; return nil }, - "name": func(tmpl *ateapipb.ActorTemplate) error { tmpl.Metadata.Name = "tmpl-b"; return nil }, + for name, mutate := range map[string]func(*ateapi.ActorTemplate) error{ + "atespace": func(tmpl *ateapi.ActorTemplate) error { tmpl.Metadata.Atespace = "ns2"; return nil }, + "name": func(tmpl *ateapi.ActorTemplate) error { tmpl.Metadata.Name = "tmpl-b"; return nil }, } { if _, err := persistence.UpdateActorTemplate(ctx, ref, store.PreconditionFrom(updated), mutate); err == nil { t.Errorf("mutating %s succeeded, want error", name) @@ -505,7 +505,7 @@ func TestUpdateActorTemplateMetadata(t *testing.T) { // Server-assigned metadata edits are overwritten, not errors: the store // restores them from the stored value. - reverted, err := persistence.UpdateActorTemplate(ctx, ref, store.PreconditionFrom(updated), func(tmpl *ateapipb.ActorTemplate) error { + reverted, err := persistence.UpdateActorTemplate(ctx, ref, store.PreconditionFrom(updated), func(tmpl *ateapi.ActorTemplate) error { tmpl.Metadata.Uid = "1e186271-b829-4085-b2b1-6b665c1a4f42" return nil }) diff --git a/cmd/ateapi/internal/controlapi/actor_test.go b/cmd/ateapi/internal/controlapi/actor_test.go index ac2b3726ca..d6296b1f10 100644 --- a/cmd/ateapi/internal/controlapi/actor_test.go +++ b/cmd/ateapi/internal/controlapi/actor_test.go @@ -28,6 +28,7 @@ import ( "time" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" @@ -37,7 +38,6 @@ import ( "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/substratex509" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/peer" @@ -49,10 +49,10 @@ import ( func TestValidateActorStatusCrash(t *testing.T) { crashPath := field.NewPath("status", "crash") - withCrash := func(mutate ...func(*ateapipb.ActorCrash)) func(*ateapipb.Actor) { - return withActorStatus(func(s *ateapipb.ActorStatus) { - s.State = ateapipb.ActorState_ACTOR_STATE_CRASHED - s.Crash = &ateapipb.ActorCrash{ + withCrash := func(mutate ...func(*ateapi.ActorCrash)) func(*ateapi.Actor) { + return withActorStatus(func(s *ateapi.ActorStatus) { + s.State = ateapi.ActorState_ACTOR_STATE_CRASHED + s.Crash = &ateapi.ActorCrash{ Message: crashMessageWorkerGone, CrashTime: ×tamppb.Timestamp{Seconds: 867}, } @@ -64,8 +64,8 @@ func TestValidateActorStatusCrash(t *testing.T) { tests := []struct { name string - oldVal *ateapipb.Actor - newVal *ateapipb.Actor + oldVal *ateapi.Actor + newVal *ateapi.Actor want field.ErrorList }{ { @@ -76,7 +76,7 @@ func TestValidateActorStatusCrash(t *testing.T) { { name: "set empty crash", oldVal: validActor(withActorStatus()), - newVal: validActor(withCrash(func(c *ateapipb.ActorCrash) { *c = ateapipb.ActorCrash{} })), + newVal: validActor(withCrash(func(c *ateapi.ActorCrash) { *c = ateapi.ActorCrash{} })), }, { name: "clear crash", @@ -86,7 +86,7 @@ func TestValidateActorStatusCrash(t *testing.T) { { name: "replace crash", oldVal: validActor(withCrash()), - newVal: validActor(withCrash(func(c *ateapipb.ActorCrash) { + newVal: validActor(withCrash(func(c *ateapi.ActorCrash) { c.Message = crashMessageWorkerDraining c.CrashTime = ×tamppb.Timestamp{Seconds: 5309} })), @@ -94,18 +94,18 @@ func TestValidateActorStatusCrash(t *testing.T) { { name: "message at max length", oldVal: validActor(withActorStatus()), - newVal: validActor(withCrash(func(c *ateapipb.ActorCrash) { c.Message = strings.Repeat("x", 4096) })), + newVal: validActor(withCrash(func(c *ateapi.ActorCrash) { c.Message = strings.Repeat("x", 4096) })), }, { name: "message too long", oldVal: validActor(withActorStatus()), - newVal: validActor(withCrash(func(c *ateapipb.ActorCrash) { c.Message = strings.Repeat("x", 4097) })), + newVal: validActor(withCrash(func(c *ateapi.ActorCrash) { c.Message = strings.Repeat("x", 4097) })), want: field.ErrorList{field.TooLong(crashPath.Child("message"), nil, 4096).WithOrigin("maxLength")}, }, { name: "truncated crash message fits", oldVal: validActor(withActorStatus()), - newVal: validActor(withCrash(func(c *ateapipb.ActorCrash) { + newVal: validActor(withCrash(func(c *ateapi.ActorCrash) { c.Message = newActorCrash(ateattr.OperationSuspend, strings.Repeat("x", 2*maxCrashMessageBytes)).GetMessage() })), }, @@ -113,13 +113,13 @@ func TestValidateActorStatusCrash(t *testing.T) { // Unchanged fields are not revalidated on update, so a crash stored // before a limit was tightened does not block later status writes. name: "unchanged overlong crash is not revalidated", - oldVal: validActor(withCrash(func(c *ateapipb.ActorCrash) { c.Message = strings.Repeat("x", 4097) })), - newVal: validActor(withCrash(func(c *ateapipb.ActorCrash) { c.Message = strings.Repeat("x", 4097) })), + oldVal: validActor(withCrash(func(c *ateapi.ActorCrash) { c.Message = strings.Repeat("x", 4097) })), + newVal: validActor(withCrash(func(c *ateapi.ActorCrash) { c.Message = strings.Repeat("x", 4097) })), }, { name: "changed overlong crash is revalidated", - oldVal: validActor(withCrash(func(c *ateapipb.ActorCrash) { c.Message = strings.Repeat("x", 4097) })), - newVal: validActor(withCrash(func(c *ateapipb.ActorCrash) { c.Message = strings.Repeat("y", 4097) })), + oldVal: validActor(withCrash(func(c *ateapi.ActorCrash) { c.Message = strings.Repeat("x", 4097) })), + newVal: validActor(withCrash(func(c *ateapi.ActorCrash) { c.Message = strings.Repeat("y", 4097) })), want: field.ErrorList{field.TooLong(crashPath.Child("message"), nil, 4096).WithOrigin("maxLength")}, }, } @@ -135,90 +135,90 @@ func TestUpdateActor(t *testing.T) { tests := []struct { name string - stored *ateapipb.Actor - req *ateapipb.Actor - want *ateapipb.Actor + stored *ateapi.Actor + req *ateapi.Actor + want *ateapi.Actor wantCode codes.Code }{ { name: "sets a worker_selector the stored actor does not have", - stored: &ateapipb.Actor{}, - req: &ateapipb.Actor{ - ActorTemplate: &ateapipb.ObjectRef{Atespace: templateNS, Name: templateName}, - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}}, + stored: &ateapi.Actor{}, + req: &ateapi.Actor{ + ActorTemplate: &ateapi.ObjectRef{Atespace: templateNS, Name: templateName}, + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}}, }, - want: &ateapipb.Actor{WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}}}, + want: &ateapi.Actor{WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}}}, }, { name: "overwrites an existing worker_selector", - stored: &ateapipb.Actor{WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "free"}}}, - req: &ateapipb.Actor{ - ActorTemplate: &ateapipb.ObjectRef{Atespace: templateNS, Name: templateName}, - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}}, + stored: &ateapi.Actor{WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "free"}}}, + req: &ateapi.Actor{ + ActorTemplate: &ateapi.ObjectRef{Atespace: templateNS, Name: templateName}, + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}}, }, - want: &ateapipb.Actor{WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}}}, + want: &ateapi.Actor{WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}}}, }, { name: "an omitted worker_selector is cleared", - stored: &ateapipb.Actor{WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "free"}}}, - req: &ateapipb.Actor{ - ActorTemplate: &ateapipb.ObjectRef{Atespace: templateNS, Name: templateName}, + stored: &ateapi.Actor{WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "free"}}}, + req: &ateapi.Actor{ + ActorTemplate: &ateapi.ObjectRef{Atespace: templateNS, Name: templateName}, }, - want: &ateapipb.Actor{}, + want: &ateapi.Actor{}, }, { name: "SourceTag immutable field is kept", - stored: &ateapipb.Actor{SourceTag: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tag1"}}, - req: &ateapipb.Actor{ - ActorTemplate: &ateapipb.ObjectRef{Atespace: templateNS, Name: templateName}, - SourceTag: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tag1"}, - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}}, + stored: &ateapi.Actor{SourceTag: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tag1"}}, + req: &ateapi.Actor{ + ActorTemplate: &ateapi.ObjectRef{Atespace: templateNS, Name: templateName}, + SourceTag: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tag1"}, + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}}, }, - want: &ateapipb.Actor{ - SourceTag: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tag1"}, - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}}, + want: &ateapi.Actor{ + SourceTag: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tag1"}, + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}}, }, }, { name: "changes to status in the request are ignored", - stored: &ateapipb.Actor{}, - req: &ateapipb.Actor{ - ActorTemplate: &ateapipb.ObjectRef{Atespace: templateNS, Name: templateName}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + stored: &ateapi.Actor{}, + req: &ateapi.Actor{ + ActorTemplate: &ateapi.ObjectRef{Atespace: templateNS, Name: templateName}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, }, - want: &ateapipb.Actor{}, + want: &ateapi.Actor{}, }, { name: "an omitted immutable field is rejected", - stored: &ateapipb.Actor{SourceTag: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tag1"}}, - req: &ateapipb.Actor{ - ActorTemplate: &ateapipb.ObjectRef{Atespace: templateNS, Name: templateName}, + stored: &ateapi.Actor{SourceTag: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tag1"}}, + req: &ateapi.Actor{ + ActorTemplate: &ateapi.ObjectRef{Atespace: templateNS, Name: templateName}, // Omitted SourceTag }, wantCode: codes.InvalidArgument, }, { name: "an immutable field the request rewrites is rejected", - stored: &ateapipb.Actor{SourceTag: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tag1"}}, - req: &ateapipb.Actor{ - ActorTemplate: &ateapipb.ObjectRef{Atespace: "attacker-ns", Name: "attacker-tmpl"}, - SourceTag: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tag2"}, + stored: &ateapi.Actor{SourceTag: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tag1"}}, + req: &ateapi.Actor{ + ActorTemplate: &ateapi.ObjectRef{Atespace: "attacker-ns", Name: "attacker-tmpl"}, + SourceTag: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tag2"}, }, wantCode: codes.InvalidArgument, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tt.stored.Metadata = &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: testActorID} - tt.stored.ActorTemplate = &ateapipb.ObjectRef{Atespace: templateNS, Name: templateName} - tt.stored.Status = &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + tt.stored.Metadata = &ateapi.ResourceMetadata{Atespace: testAtespace, Name: testActorID} + tt.stored.ActorTemplate = &ateapi.ObjectRef{Atespace: templateNS, Name: templateName} + tt.stored.Status = &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, } svc, created := rpcServiceWithActor(t, tt.stored) tt.req.Metadata = created.GetMetadata() - updated, err := svc.UpdateActor(context.Background(), &ateapipb.UpdateActorRequest{Actor: tt.req}) + updated, err := svc.UpdateActor(context.Background(), &ateapi.UpdateActorRequest{Actor: tt.req}) if tt.wantCode != codes.OK { if code := apierror.Code(err); code != tt.wantCode { @@ -230,10 +230,10 @@ func TestUpdateActor(t *testing.T) { t.Fatalf("UpdateActor failed: %v", err) } - tt.want.Metadata = &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: testActorID, Version: 2} - tt.want.ActorTemplate = &ateapipb.ObjectRef{Atespace: templateNS, Name: templateName} - tt.want.Status = &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + tt.want.Metadata = &ateapi.ResourceMetadata{Atespace: testAtespace, Name: testActorID, Version: 2} + tt.want.ActorTemplate = &ateapi.ObjectRef{Atespace: templateNS, Name: templateName} + tt.want.Status = &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, } if diff := cmp.Diff(tt.want, updated, protocmp.Transform(), ignoreUID, ignoreTimestamps); diff != "" { t.Errorf("UpdateActor response mismatch (-want +got):\n%s", diff) @@ -255,62 +255,62 @@ func TestUpdateActor_RepointTemplate(t *testing.T) { storetest.MustCreateAtespace(t, ctx, persistence, testAtespace) // tmpl-a and tmpl-b are volume-compatible; tmpl-c mounts the data volume // elsewhere, and tmpl-d declares an extra volume. - dataVolume := &ateapipb.Volume{Name: "data", DurableDir: &ateapipb.DurableDirVolumeSource{}} - scratchVolume := &ateapipb.Volume{Name: "scratch", DurableDir: &ateapipb.DurableDirVolumeSource{}} + dataVolume := &ateapi.Volume{Name: "data", DurableDir: &ateapi.DurableDirVolumeSource{}} + scratchVolume := &ateapi.Volume{Name: "scratch", DurableDir: &ateapi.DurableDirVolumeSource{}} templates := map[string]struct { mountPath string - volumes []*ateapipb.Volume + volumes []*ateapi.Volume }{ - "tmpl-a": {"/data", []*ateapipb.Volume{dataVolume}}, - "tmpl-b": {"/data", []*ateapipb.Volume{dataVolume}}, - "tmpl-c": {"/mnt/data", []*ateapipb.Volume{dataVolume}}, - "tmpl-d": {"/data", []*ateapipb.Volume{dataVolume, scratchVolume}}, + "tmpl-a": {"/data", []*ateapi.Volume{dataVolume}}, + "tmpl-b": {"/data", []*ateapi.Volume{dataVolume}}, + "tmpl-c": {"/mnt/data", []*ateapi.Volume{dataVolume}}, + "tmpl-d": {"/data", []*ateapi.Volume{dataVolume, scratchVolume}}, } for name, tmpl := range templates { - if _, err := persistence.CreateActorTemplate(ctx, &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - Containers: []*ateapipb.Container{{ + if _, err := persistence.CreateActorTemplate(ctx, &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + Containers: []*ateapi.Container{{ Name: "main", Image: "example.com/app:v1", - VolumeMounts: []*ateapipb.VolumeMount{{Name: "data", MountPath: tmpl.mountPath}}, + VolumeMounts: []*ateapi.VolumeMount{{Name: "data", MountPath: tmpl.mountPath}}, }}, Volumes: tmpl.volumes, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: "gs://my-bucket/snapshots"}, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: "gs://my-bucket/snapshots"}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, }); err != nil { t.Fatalf("creating template %s: %v", name, err) } } - created := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + created := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) svc := &RPCService{impl: newServiceImpl(persistence, nil)} // Repointing at a template that does not exist is rejected. - _, err := svc.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{ + _, err := svc.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ Metadata: created.GetMetadata(), - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "absent"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "absent"}, }}) if got := apierror.Code(err); got != codes.FailedPrecondition { t.Fatalf("UpdateActor to an absent template = %v, want FailedPrecondition (err: %v)", got, err) } // Repointing at a template with different volume mounts is rejected. - _, err = svc.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{ + _, err = svc.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ Metadata: created.GetMetadata(), - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-c"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-c"}, }}) if got := apierror.Code(err); got != codes.FailedPrecondition { t.Fatalf("UpdateActor to a template with different mounts = %v, want FailedPrecondition (err: %v)", got, err) } // Repointing at a template with different volumes is rejected. - _, err = svc.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{ + _, err = svc.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ Metadata: created.GetMetadata(), - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-d"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-d"}, }}) if got := apierror.Code(err); got != codes.FailedPrecondition { t.Fatalf("UpdateActor to a template with different volumes = %v, want FailedPrecondition (err: %v)", got, err) @@ -318,9 +318,9 @@ func TestUpdateActor_RepointTemplate(t *testing.T) { // Repointing at an existing template with identical volumes and mounts // succeeds. - updated, err := svc.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{ + updated, err := svc.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ Metadata: created.GetMetadata(), - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-b"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-b"}, }}) if err != nil { t.Fatalf("UpdateActor failed: %v", err) @@ -332,14 +332,14 @@ func TestUpdateActor_RepointTemplate(t *testing.T) { // When the old template no longer exists there is nothing left to // compare the volume layout against, so the repoint only requires the new // ref to resolve. - orphan := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "orphan-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-gone"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + orphan := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "orphan-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-gone"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) - repointed, err := svc.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{ + repointed, err := svc.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ Metadata: orphan.GetMetadata(), - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-d"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-d"}, }}) if err != nil { t.Fatalf("UpdateActor from a deleted template failed: %v", err) @@ -350,14 +350,14 @@ func TestUpdateActor_RepointTemplate(t *testing.T) { // Repointing an actor that is not suspended is rejected, even at a // compatible template. - running := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "running-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + running := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "running-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, }) - _, err = svc.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{ + _, err = svc.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ Metadata: running.GetMetadata(), - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-b"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-b"}, }}) if got := apierror.Code(err); got != codes.FailedPrecondition { t.Fatalf("UpdateActor repointing a running actor = %v, want FailedPrecondition (err: %v)", got, err) @@ -366,27 +366,27 @@ func TestUpdateActor_RepointTemplate(t *testing.T) { // Repointing a suspended actor is allowed even when it holds a node-local // snapshot. for _, name := range []string{"paused-actor", "uploaded-paused-actor"} { - paused := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + paused := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) - uploaded := mustActorSnapshotURI(t, &ateapipb.ActorTemplate{SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: "gs://my-bucket/snapshots"}}, paused, "pause-snap") - paused = mustUpdateActorStatus(t, ctx, persistence, paused, func(s *ateapipb.ActorStatus) { - snap := newPausedSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "pause-snap", "node-1") + uploaded := mustActorSnapshotURI(t, &ateapi.ActorTemplate{SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: "gs://my-bucket/snapshots"}}, paused, "pause-snap") + paused = mustUpdateActorStatus(t, ctx, persistence, paused, func(s *ateapi.ActorStatus) { + snap := newPausedSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "pause-snap", "node-1") if name == "uploaded-paused-actor" { - snap.DurableSnapshot = &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: uploaded.String()}, + snap.DurableSnapshot = &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, + Object: &ateapi.ObjectSnapshot{SnapshotUri: uploaded.String()}, } } s.AssignedNode = "node-1" s.LastAssignedGeneration = 1 - s.Snapshots = []*ateapipb.Snapshot{snap} + s.Snapshots = []*ateapi.Snapshot{snap} }) - repointedPaused, err := svc.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{ + repointedPaused, err := svc.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ Metadata: paused.GetMetadata(), - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-b"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-b"}, }}) if err != nil { t.Fatalf("UpdateActor repointing %s failed: %v", name, err) @@ -398,10 +398,10 @@ func TestUpdateActor_RepointTemplate(t *testing.T) { // An update that keeps the template ref is still allowed while running: // the suspended-state gate applies only to repoints. - kept, err := svc.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{ + kept, err := svc.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ Metadata: running.GetMetadata(), - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}, - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}, + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}}, }}) if err != nil { t.Fatalf("UpdateActor keeping the template on a running actor failed: %v", err) @@ -438,15 +438,15 @@ func TestUpdateActor_RepointTemplateStorageLocation(t *testing.T) { "different-location": differentLocation, "corrupt": "gs:///snapshots", } { - if _, err := persistence.CreateActorTemplate(ctx, &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: location}, + if _, err := persistence.CreateActorTemplate(ctx, &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: location}, }); err != nil { t.Fatalf("creating template %s: %v", name, err) } } - snapshotOwnedByActor := func(t *testing.T, actor *ateapipb.Actor) string { + snapshotOwnedByActor := func(t *testing.T, actor *ateapi.Actor) string { t.Helper() uri, err := resources.NewActorSnapshotURI(sameLocation, testAtespace, actor.GetMetadata().GetUid(), "snap") if err != nil { @@ -454,7 +454,7 @@ func TestUpdateActor_RepointTemplateStorageLocation(t *testing.T) { } return uri.String() } - snapshotOwnedByTag := func(t *testing.T, _ *ateapipb.Actor) string { + snapshotOwnedByTag := func(t *testing.T, _ *ateapi.Actor) string { t.Helper() uri, err := resources.NewTagSnapshotURI(sameLocation, testAtespace, "0c6e2f4a-8b1d-4e57-a3f9-2d7c5b8e1a60") if err != nil { @@ -462,14 +462,10 @@ func TestUpdateActor_RepointTemplateStorageLocation(t *testing.T) { } return uri.String() } - unparseableSnapshot := func(*testing.T, *ateapipb.Actor) string { - return sameLocation + "/not-a-snapshot" - } - tests := []struct { name string template string - snapshot func(*testing.T, *ateapipb.Actor) string + snapshot func(*testing.T, *ateapi.Actor) string // pending leaves the snapshot's upload PENDING, as an async suspend does. pending bool // lastAssignedGen overrides status.LastAssignedGeneration when > 0 @@ -541,13 +537,6 @@ func TestUpdateActor_RepointTemplateStorageLocation(t *testing.T) { repointTo: "different-location", wantCode: codes.FailedPrecondition, }, - { - name: "unparseable snapshot", - template: "same-location", - snapshot: unparseableSnapshot, - repointTo: "different-location", - wantCode: codes.Internal, - }, { name: "invalid storage location on the new template", template: "same-location", @@ -590,31 +579,31 @@ func TestUpdateActor_RepointTemplateStorageLocation(t *testing.T) { impl := newServiceImpl(persistence, nil) impl.clusterSnapshotLocation = tt.clusterSnapshotLocation svc := &RPCService{impl: impl} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: fmt.Sprintf("actor-%d", i)}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: tt.template}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: fmt.Sprintf("actor-%d", i)}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: tt.template}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) if tt.snapshot != nil { uri := tt.snapshot(t, actor) - storageStatus := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + storageStatus := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED if tt.pending { - storageStatus = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + storageStatus = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING } - actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 1 if tt.lastAssignedGen > 0 { s.LastAssignedGeneration = tt.lastAssignedGen } - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "snapshot", uri, storageStatus), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "snapshot", uri, storageStatus), } }) } - updated, err := svc.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{ + updated, err := svc.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ Metadata: actor.GetMetadata(), - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: tt.repointTo}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: tt.repointTo}, }}) if got := apierror.Code(err); got != tt.wantCode { t.Fatalf("UpdateActor to %s = %v, want %v (err: %v)", tt.repointTo, got, tt.wantCode, err) @@ -632,23 +621,23 @@ func TestUpdateActor_RepointTemplateStorageLocation(t *testing.T) { // per-container mount comparison applied when an actor is repointed at a // replacement template. func TestValidateTemplateVolumesUnchanged(t *testing.T) { - dataVolume := &ateapipb.Volume{Name: "data", DurableDir: &ateapipb.DurableDirVolumeSource{}} - scratchVolume := &ateapipb.Volume{Name: "scratch", DurableDir: &ateapipb.DurableDirVolumeSource{}} - template := func(volumes []*ateapipb.Volume, containers ...*ateapipb.Container) *ateapipb.ActorTemplate { - return &ateapipb.ActorTemplate{Volumes: volumes, Containers: containers} + dataVolume := &ateapi.Volume{Name: "data", DurableDir: &ateapi.DurableDirVolumeSource{}} + scratchVolume := &ateapi.Volume{Name: "scratch", DurableDir: &ateapi.DurableDirVolumeSource{}} + template := func(volumes []*ateapi.Volume, containers ...*ateapi.Container) *ateapi.ActorTemplate { + return &ateapi.ActorTemplate{Volumes: volumes, Containers: containers} } - container := func(name string, mounts ...*ateapipb.VolumeMount) *ateapipb.Container { - return &ateapipb.Container{Name: name, Image: "example.com/app:v1", VolumeMounts: mounts} + container := func(name string, mounts ...*ateapi.VolumeMount) *ateapi.Container { + return &ateapi.Container{Name: name, Image: "example.com/app:v1", VolumeMounts: mounts} } - dataMount := &ateapipb.VolumeMount{Name: "data", MountPath: "/data"} - scratchMount := &ateapipb.VolumeMount{Name: "scratch", MountPath: "/scratch"} + dataMount := &ateapi.VolumeMount{Name: "data", MountPath: "/data"} + scratchMount := &ateapi.VolumeMount{Name: "scratch", MountPath: "/scratch"} - oneVolume := []*ateapipb.Volume{dataVolume} - twoVolumes := []*ateapipb.Volume{dataVolume, scratchVolume} + oneVolume := []*ateapi.Volume{dataVolume} + twoVolumes := []*ateapi.Volume{dataVolume, scratchVolume} tests := []struct { name string - oldTmpl, newTmpl *ateapipb.ActorTemplate + oldTmpl, newTmpl *ateapi.ActorTemplate wantErr bool }{{ name: "identical volumes and mounts", @@ -671,22 +660,22 @@ func TestValidateTemplateVolumesUnchanged(t *testing.T) { }, { name: "volume renamed", oldTmpl: template(oneVolume, container("main", dataMount)), - newTmpl: template([]*ateapipb.Volume{{Name: "data2", DurableDir: &ateapipb.DurableDirVolumeSource{}}}, container("main", dataMount)), + newTmpl: template([]*ateapi.Volume{{Name: "data2", DurableDir: &ateapi.DurableDirVolumeSource{}}}, container("main", dataMount)), wantErr: true, }, { name: "volume source changed", oldTmpl: template(oneVolume, container("main", dataMount)), - newTmpl: template([]*ateapipb.Volume{{Name: "data", Image: &ateapipb.ImageVolumeSource{Reference: "example.com/data@sha256:0f9c04b7387d13ba9d15ec50355f9ad533fee2e5ad25378753a30671f8f9b938"}}}, container("main", dataMount)), + newTmpl: template([]*ateapi.Volume{{Name: "data", Image: &ateapi.ImageVolumeSource{Reference: "example.com/data@sha256:0f9c04b7387d13ba9d15ec50355f9ad533fee2e5ad25378753a30671f8f9b938"}}}, container("main", dataMount)), wantErr: true, }, { name: "volume order changed", oldTmpl: template(twoVolumes, container("main", dataMount)), - newTmpl: template([]*ateapipb.Volume{scratchVolume, dataVolume}, container("main", dataMount)), + newTmpl: template([]*ateapi.Volume{scratchVolume, dataVolume}, container("main", dataMount)), wantErr: true, }, { name: "mount path changed", oldTmpl: template(oneVolume, container("main", dataMount)), - newTmpl: template(oneVolume, container("main", &ateapipb.VolumeMount{Name: "data", MountPath: "/mnt/data"})), + newTmpl: template(oneVolume, container("main", &ateapi.VolumeMount{Name: "data", MountPath: "/mnt/data"})), wantErr: true, }, { name: "mount added", @@ -742,19 +731,19 @@ func TestUpdateActor_DeleteRecreateRace(t *testing.T) { // Actor A: what the client reads, and what its uid precondition names. // Freshly created, so it sits at version 1. - original := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{WorkerPod: "pod-a"}, + original := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{WorkerPod: "pod-a"}, }, }) // A concurrent client deletes A and recreates the same atespace/name as a // brand new actor B, in the window the handler used to leave open between // its own read and the store's WATCH. - var recreated *ateapipb.Actor + var recreated *ateapi.Actor var err error racing := &conflictInjectingStore{ Interface: persistence, @@ -765,10 +754,10 @@ func TestUpdateActor_DeleteRecreateRace(t *testing.T) { if _, err := persistence.DeleteActor(ctx, actorRef, store.DeletePreconditions{}); err != nil { t.Fatalf("racing writer: DeleteActor: %v", err) } - recreated, err = persistence.CreateActor(ctx, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + recreated, err = persistence.CreateActor(ctx, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) if err != nil { t.Fatalf("racing writer: recreate CreateActor: %v", err) @@ -778,8 +767,8 @@ func TestUpdateActor_DeleteRecreateRace(t *testing.T) { svc := &RPCService{impl: newServiceImpl(racing, nil)} // The client asserts "only update the actor with uid A". - original.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}} - _, err = svc.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: original}) + original.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}} + _, err = svc.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: original}) if code := apierror.Code(err); code != codes.Aborted { t.Errorf("UpdateActor error = %v (code %v), want code Aborted: the actor holding uid %s was deleted mid-update", err, code, original.GetMetadata().GetUid()) @@ -794,9 +783,9 @@ func TestUpdateActor_DeleteRecreateRace(t *testing.T) { } // The stored record must still be actor B as its creator left it. Any of A's // state showing up here is the clobber. - if got := stored.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := stored.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("stored state = %v, want %v: recreated actor was overwritten with the deleted actor's state", - got, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + got, ateapi.ActorState_ACTOR_STATE_SUSPENDED) } if got := stored.GetStatus().GetWorkerAssignment(); got != nil { t.Errorf("stored worker_assignment = %v, want nil: recreated actor inherited the deleted actor's worker", got) @@ -817,10 +806,10 @@ func TestUpdateActor_ConcurrentDisjointUpdates(t *testing.T) { actorRef := resources.ActorRef{Atespace: testAtespace, Name: testActorID} - original := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + original := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, }) // A suspend workflow bumps state (a field that a later update operation will not touch) @@ -828,8 +817,8 @@ func TestUpdateActor_ConcurrentDisjointUpdates(t *testing.T) { racing := &conflictInjectingStore{ Interface: persistence, inject: func() { - if _, err := persistence.UpdateActor(ctx, actorRef, store.PreconditionFrom(original), func(toUpdate *ateapipb.Actor) error { - toUpdate.Status.State = ateapipb.ActorState_ACTOR_STATE_SUSPENDING + if _, err := persistence.UpdateActor(ctx, actorRef, store.PreconditionFrom(original), func(toUpdate *ateapi.Actor) error { + toUpdate.Status.State = ateapi.ActorState_ACTOR_STATE_SUSPENDING return nil }); err != nil { t.Fatalf("racing writer: mark suspending: %v", err) @@ -840,8 +829,8 @@ func TestUpdateActor_ConcurrentDisjointUpdates(t *testing.T) { // Update operation is changing the worker_selector field, not the actor's state (like the concurrent op) // This update must fail: the racing update bumped the version. - original.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}} - _, err := svc.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: original}) + original.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}} + _, err := svc.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: original}) if code := apierror.Code(err); code != codes.Aborted { t.Errorf("UpdateActor error = %v (code %v), want code Aborted: the guarded version moved under the update", err, code) } @@ -854,16 +843,16 @@ func TestUpdateActor_ConcurrentDisjointUpdates(t *testing.T) { if got := stored.GetWorkerSelector(); got != nil { t.Errorf("stored worker_selector = %v, want nil: the rejected update was applied anyway", got) } - if got := stored.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDING { - t.Errorf("stored state = %v, want %v: the concurrent writer's field must survive", got, ateapipb.ActorState_ACTOR_STATE_SUSPENDING) + if got := stored.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDING { + t.Errorf("stored state = %v, want %v: the concurrent writer's field must survive", got, ateapi.ActorState_ACTOR_STATE_SUSPENDING) } } // validActor returns a minimal Actor which should pass input validation. -func validActor(mods ...func(*ateapipb.Actor)) *ateapipb.Actor { - a := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ns1", Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, +func validActor(mods ...func(*ateapi.Actor)) *ateapi.Actor { + a := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ns1", Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, } for _, m := range mods { m(a) @@ -873,10 +862,10 @@ func validActor(mods ...func(*ateapipb.Actor)) *ateapipb.Actor { // withActorStatus returns a modifier func (see validActor) which sets the // actor's status to a valid value. -func withActorStatus(mods ...func(*ateapipb.ActorStatus)) func(*ateapipb.Actor) { - return func(a *ateapipb.Actor) { - a.Status = &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, +func withActorStatus(mods ...func(*ateapi.ActorStatus)) func(*ateapi.Actor) { + return func(a *ateapi.Actor) { + a.Status = &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, } for _, m := range mods { m(a.Status) @@ -886,7 +875,7 @@ func withActorStatus(mods ...func(*ateapipb.ActorStatus)) func(*ateapipb.Actor) // rpcServiceWithActor seeds one actor in a PostgreSQL-backed store and returns an // RPCService over it. -func rpcServiceWithActor(t *testing.T, actor *ateapipb.Actor) (*RPCService, *ateapipb.Actor) { +func rpcServiceWithActor(t *testing.T, actor *ateapi.Actor) (*RPCService, *ateapi.Actor) { t.Helper() persistence, cleanup := storetest.SetupTestStore(t) t.Cleanup(cleanup) @@ -899,12 +888,12 @@ func TestCreateActor_DoesNotInheritGoldenEgressPolicy(t *testing.T) { preview.InitForTest(t, "GoldenEgressPolicy") for _, tt := range []struct { name string - policy *ateapipb.EgressPolicyTemplate + policy *ateapi.EgressPolicyTemplate }{ {name: "absent"}, - {name: "configured", policy: &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{ - {Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}}}, - {Https: &ateapipb.HttpsRule{Hostnames: []string{"api.example.com"}}}, + {name: "configured", policy: &ateapi.EgressPolicyTemplate{Rules: []*ateapi.EgressRule{ + {Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}}}, + {Https: &ateapi.HttpsRule{Hostnames: []string{"api.example.com"}}}, }}}, } { t.Run(tt.name, func(t *testing.T) { @@ -915,8 +904,8 @@ func TestCreateActor_DoesNotInheritGoldenEgressPolicy(t *testing.T) { svc := &RPCService{impl: impl} storetest.MustCreateAtespace(t, ctx, persistence, "templates") storetest.MustCreateAtespace(t, ctx, persistence, "actors") - tmpl, err := svc.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.Metadata = &ateapipb.ResourceMetadata{Atespace: "templates", Name: "tmpl"} + tmpl, err := svc.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.Metadata = &ateapi.ResourceMetadata{Atespace: "templates", Name: "tmpl"} tmpl.GoldenEgressPolicy = tt.policy })}) if err != nil { @@ -930,27 +919,27 @@ func TestCreateActor_DoesNotInheritGoldenEgressPolicy(t *testing.T) { {Atespace: "actors", Name: tmpl.GetMetadata().GetUid()}, {Atespace: tmpl.GetMetadata().GetAtespace(), Name: tmpl.GetMetadata().GetUid()}, } { - actor, err := svc.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: target.Atespace, Name: target.Name}, ActorTemplate: tmplRef, + actor, err := svc.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: target.Atespace, Name: target.Name}, ActorTemplate: tmplRef, }}) if err != nil { t.Fatal(err) } ref := resources.ActorRefFromActor(actor).ToObjectRef() - if _, err := svc.GetActorEgressPolicy(ctx, &ateapipb.GetActorEgressPolicyRequest{Actor: ref, Name: resources.SingletonName}); apierror.Code(err) != codes.NotFound { + if _, err := svc.GetActorEgressPolicy(ctx, &ateapi.GetActorEgressPolicyRequest{Actor: ref, Name: resources.SingletonName}); apierror.Code(err) != codes.NotFound { t.Fatalf("actor %v inherited golden policy: %v, want NotFound", target, err) } - if _, err := svc.CreateActorEgressPolicy(ctx, &ateapipb.CreateActorEgressPolicyRequest{ + if _, err := svc.CreateActorEgressPolicy(ctx, &ateapi.CreateActorEgressPolicyRequest{ Actor: ref, - EgressPolicy: &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: target.Atespace, Name: resources.SingletonName}, - Rules: []*ateapipb.EgressRule{{Https: &ateapipb.HttpsRule{Hostnames: []string{"runtime.example.com"}}}}, + EgressPolicy: &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: target.Atespace, Name: resources.SingletonName}, + Rules: []*ateapi.EgressRule{{Https: &ateapi.HttpsRule{Hostnames: []string{"runtime.example.com"}}}}, }, }); err != nil { t.Fatalf("creating the actor's runtime policy: %v", err) } } - gotTemplate, err := svc.GetActorTemplate(ctx, &ateapipb.GetActorTemplateRequest{ActorTemplate: tmplRef}) + gotTemplate, err := svc.GetActorTemplate(ctx, &ateapi.GetActorTemplateRequest{ActorTemplate: tmplRef}) if err != nil || !proto.Equal(gotTemplate, tmpl) { t.Fatalf("creating runtime policies changed the template: %v, %v", gotTemplate, err) } @@ -965,14 +954,14 @@ func TestCreateActor_GoldenTagDefault(t *testing.T) { persistence := newTestPersistence(t) storetest.MustCreateAtespace(t, ctx, persistence, "team-a") tmpl := seedSubstrateTemplate(t, ctx, persistence, "tmpl") - ref := &ateapipb.ObjectRef{Atespace: "team-a", Name: tmpl.GetMetadata().GetUid()} - tag := &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: ref.Atespace, Name: ref.Name}, + ref := &ateapi.ObjectRef{Atespace: "team-a", Name: tmpl.GetMetadata().GetUid()} + tag := &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: ref.Atespace, Name: ref.Name}, SourceActor: ref, - Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED, - Status: &ateapipb.TagStatus{ + Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED, + Status: &ateapi.TagStatus{ ActorTemplateUid: tmpl.GetMetadata().GetUid(), - Snapshot: newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), someActorUID, "gs://bucket/atespaces/team-a/tags/"+someActorUID, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + Snapshot: newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), someActorUID, "gs://bucket/atespaces/team-a/tags/"+someActorUID, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), }, } wantCode := codes.OK @@ -986,28 +975,28 @@ func TestCreateActor_GoldenTagDefault(t *testing.T) { tag.Status.ActorTemplateUid = "other" wantCode = codes.FailedPrecondition case "data scope": - tag.Status.Snapshot.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES + tag.Status.Snapshot.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES } if scenario != "missing" { if _, err := persistence.CreateTag(ctx, tag); err != nil { t.Fatal(err) } } - if _, err := persistence.UpdateActorTemplate(ctx, resources.ActorTemplateRefFromActorTemplate(tmpl), store.PreconditionFrom(tmpl), func(db *ateapipb.ActorTemplate) error { - db.Status = &ateapipb.ActorTemplateStatus{GoldenSnapshotStatus: &ateapipb.GoldenSnapshotStatus{GoldenTag: ref}} - db.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{{Https: &ateapipb.HttpsRule{Hostnames: []string{"init.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{443}}}}}} + if _, err := persistence.UpdateActorTemplate(ctx, resources.ActorTemplateRefFromActorTemplate(tmpl), store.PreconditionFrom(tmpl), func(db *ateapi.ActorTemplate) error { + db.Status = &ateapi.ActorTemplateStatus{GoldenSnapshotStatus: &ateapi.GoldenSnapshotStatus{GoldenTag: ref}} + db.GoldenEgressPolicy = &ateapi.EgressPolicyTemplate{Rules: []*ateapi.EgressRule{{Https: &ateapi.HttpsRule{Hostnames: []string{"init.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{443}}}}}} return nil }); err != nil { t.Fatal(err) } - actor := &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "actor"}, ActorTemplate: resources.ActorTemplateRefFromActorTemplate(tmpl).ToObjectRef()} + actor := &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "actor"}, ActorTemplate: resources.ActorTemplateRefFromActorTemplate(tmpl).ToObjectRef()} if scenario == "explicit tag" { tag.Metadata.Name = "explicit" - tag.Status.Snapshot = newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), "explicit", "gs://bucket/atespaces/team-a/tags/explicit", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + tag.Status.Snapshot = newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), "explicit", "gs://bucket/atespaces/team-a/tags/explicit", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) if _, err := persistence.CreateTag(ctx, tag); err != nil { t.Fatal(err) } - actor.SourceTag = &ateapipb.ObjectRef{Atespace: ref.Atespace, Name: "explicit"} + actor.SourceTag = &ateapi.ObjectRef{Atespace: ref.Atespace, Name: "explicit"} } svc := &ServiceImpl{store: persistence} created, err := svc.CreateActor(ctx, actor) @@ -1017,8 +1006,8 @@ func TestCreateActor_GoldenTagDefault(t *testing.T) { if err != nil { return } - gotSnap := findLatestDurableSnapshot(created.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) - if gotSnap.GetDurableSnapshot().GetObject().GetSnapshotUri() != tagDurableSnapshotURI(tag, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) || gotSnap.GetActorTemplateUid() != tmpl.GetMetadata().GetUid() { + gotSnap := findLatestDurableSnapshot(created.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + if gotSnap.GetDurableSnapshot().GetObject().GetSnapshotUri() != tagDurableSnapshotURI(tag, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) || gotSnap.GetActorTemplateUid() != tmpl.GetMetadata().GetUid() { t.Fatalf("incorrect initial status: %v", created.GetStatus()) } if _, err := persistence.GetEgressPolicy(ctx, resources.ActorRefFromActor(created)); !errors.Is(err, store.ErrNotFound) { @@ -1029,10 +1018,10 @@ func TestCreateActor_GoldenTagDefault(t *testing.T) { if err != nil { t.Fatal(err) } - if _, err := persistence.UpdateActor(ctx, resources.ActorRefFromActor(created), store.PreconditionFrom(created), func(db *ateapipb.Actor) error { + if _, err := persistence.UpdateActor(ctx, resources.ActorRefFromActor(created), store.PreconditionFrom(created), func(db *ateapi.Actor) error { db.Status.LastAssignedGeneration = 1 - db.Status.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), uri.Name(), uri.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + db.Status.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), uri.Name(), uri.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), } return nil }); err != nil { @@ -1054,10 +1043,10 @@ func TestCreateActor_GoldenTagDefault(t *testing.T) { type fakeActorServiceStore struct { serviceStore - actors map[resources.ActorRef]*ateapipb.Actor + actors map[resources.ActorRef]*ateapi.Actor } -func (f *fakeActorServiceStore) GetActor(_ context.Context, actorRef resources.ActorRef) (*ateapipb.Actor, error) { +func (f *fakeActorServiceStore) GetActor(_ context.Context, actorRef resources.ActorRef) (*ateapi.Actor, error) { a, ok := f.actors[actorRef] if !ok { return nil, store.ErrNotFound @@ -1075,13 +1064,13 @@ func TestMintActorCertificate(t *testing.T) { }) actorUID := "3b9f1e77-2c4d-4a80-91be-6d5c8f0a7e21" - created := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: testActorID, Uid: actorUID}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + created := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: testActorID, Uid: actorUID}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, } fakeStore := &fakeActorServiceStore{ - actors: map[resources.ActorRef]*ateapipb.Actor{ + actors: map[resources.ActorRef]*ateapi.Actor{ {Atespace: testAtespace, Name: testActorID}: created, }, } @@ -1109,8 +1098,8 @@ func TestMintActorCertificate(t *testing.T) { t.Fatalf("CreateCertificateRequest: %v", err) } - resp, err := svc.MintActorCertificate(ctx, &ateapipb.MintActorCertificateRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: testActorID}, + resp, err := svc.MintActorCertificate(ctx, &ateapi.MintActorCertificateRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: testActorID}, ActorUid: created.GetMetadata().GetUid(), CertificateSigningRequest: csr, }) diff --git a/cmd/ateapi/internal/controlapi/atespace.go b/cmd/ateapi/internal/controlapi/atespace.go index 2d72b37eef..ac23952e23 100644 --- a/cmd/ateapi/internal/controlapi/atespace.go +++ b/cmd/ateapi/internal/controlapi/atespace.go @@ -19,15 +19,15 @@ import ( "errors" "fmt" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/defaults" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) -func (s *RPCService) CreateAtespace(ctx context.Context, req *ateapipb.CreateAtespaceRequest) (*ateapipb.Atespace, error) { +func (s *RPCService) CreateAtespace(ctx context.Context, req *ateapi.CreateAtespaceRequest) (*ateapi.Atespace, error) { // First scrub any fields that users are not allowed to set, then fill the // defaults so validation sees the final resource state. inAtespace := req.GetAtespace() @@ -46,7 +46,7 @@ func (s *RPCService) CreateAtespace(ctx context.Context, req *ateapipb.CreateAte return s.impl.CreateAtespace(ctx, inAtespace) } -func (s *ServiceImpl) CreateAtespace(ctx context.Context, inAtespace *ateapipb.Atespace) (*ateapipb.Atespace, error) { +func (s *ServiceImpl) CreateAtespace(ctx context.Context, inAtespace *ateapi.Atespace) (*ateapi.Atespace, error) { // no further processing or status, but if there were, we would do it here // Save the data in the storage layer. @@ -61,7 +61,7 @@ func (s *ServiceImpl) CreateAtespace(ctx context.Context, inAtespace *ateapipb.A return stored, nil } -func (s *RPCService) GetAtespace(ctx context.Context, req *ateapipb.GetAtespaceRequest) (*ateapipb.Atespace, error) { +func (s *RPCService) GetAtespace(ctx context.Context, req *ateapi.GetAtespaceRequest) (*ateapi.Atespace, error) { if errs := apivalidation.ValidateGetAtespaceRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -69,7 +69,7 @@ func (s *RPCService) GetAtespace(ctx context.Context, req *ateapipb.GetAtespaceR return s.impl.GetAtespace(ctx, req.Atespace.Name) } -func (s *ServiceImpl) GetAtespace(ctx context.Context, name string) (*ateapipb.Atespace, error) { +func (s *ServiceImpl) GetAtespace(ctx context.Context, name string) (*ateapi.Atespace, error) { atespace, err := s.store.GetAtespace(ctx, name) if errors.Is(err, store.ErrNotFound) { return nil, apierror.NotFound("Atespace %s not found", name) @@ -80,7 +80,7 @@ func (s *ServiceImpl) GetAtespace(ctx context.Context, name string) (*ateapipb.A return atespace, nil } -func (s *RPCService) ListAtespaces(ctx context.Context, req *ateapipb.ListAtespacesRequest) (*ateapipb.ListAtespacesResponse, error) { +func (s *RPCService) ListAtespaces(ctx context.Context, req *ateapi.ListAtespacesRequest) (*ateapi.ListAtespacesResponse, error) { if errs := apivalidation.ValidateListAtespacesRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -89,13 +89,13 @@ func (s *RPCService) ListAtespaces(ctx context.Context, req *ateapipb.ListAtespa if err != nil { return nil, err } - return &ateapipb.ListAtespacesResponse{ + return &ateapi.ListAtespacesResponse{ Atespaces: page.Items, NextPageToken: page.NextPageToken, }, nil } -func (s *ServiceImpl) ListAtespaces(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapipb.Atespace], error) { +func (s *ServiceImpl) ListAtespaces(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapi.Atespace], error) { page, err := s.store.ListAtespaces(ctx, opts) if err != nil { return page, mapListError(fmt.Errorf("while listing atespaces in db: %w", err)) @@ -103,7 +103,7 @@ func (s *ServiceImpl) ListAtespaces(ctx context.Context, opts store.ListOptions) return page, nil } -func (s *RPCService) DeleteAtespace(ctx context.Context, req *ateapipb.DeleteAtespaceRequest) (*ateapipb.Atespace, error) { +func (s *RPCService) DeleteAtespace(ctx context.Context, req *ateapi.DeleteAtespaceRequest) (*ateapi.Atespace, error) { if errs := apivalidation.ValidateDeleteAtespaceRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -111,7 +111,7 @@ func (s *RPCService) DeleteAtespace(ctx context.Context, req *ateapipb.DeleteAte return s.impl.DeleteAtespace(ctx, req.Atespace.Name, toDeletePreconditions(req.GetOptions())) } -func (s *ServiceImpl) DeleteAtespace(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapipb.Atespace, error) { +func (s *ServiceImpl) DeleteAtespace(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.Atespace, error) { deleted, err := s.store.DeleteAtespace(ctx, name, precondition) if err != nil { if errors.Is(err, store.ErrNotFound) { diff --git a/cmd/ateapi/internal/controlapi/atespace_test.go b/cmd/ateapi/internal/controlapi/atespace_test.go index 6a649fda48..004f19588f 100644 --- a/cmd/ateapi/internal/controlapi/atespace_test.go +++ b/cmd/ateapi/internal/controlapi/atespace_test.go @@ -19,21 +19,21 @@ import ( "testing" openfgav1 "github.com/openfga/api/proto/openfga/v1" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/authz" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/principal" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/codes" ) // validAtespace returns a minimal Atespace which should pass input validation. -func validAtespace(mods ...func(*ateapipb.Atespace)) *ateapipb.Atespace { - a := &ateapipb.Atespace{ - Metadata: &ateapipb.ResourceMetadata{Name: "team1"}, +func validAtespace(mods ...func(*ateapi.Atespace)) *ateapi.Atespace { + a := &ateapi.Atespace{ + Metadata: &ateapi.ResourceMetadata{Name: "team1"}, } for _, m := range mods { m(a) @@ -43,8 +43,8 @@ func validAtespace(mods ...func(*ateapipb.Atespace)) *ateapipb.Atespace { // withAtespaceMetadata returns a modifier func (see validAtespace) which sets // the atespace's resource metadata to a valid value. -func withAtespaceMetadata(mutate func(*ateapipb.ResourceMetadata)) func(*ateapipb.Atespace) { - return func(a *ateapipb.Atespace) { mutate(a.Metadata) } +func withAtespaceMetadata(mutate func(*ateapi.ResourceMetadata)) func(*ateapi.Atespace) { + return func(a *ateapi.Atespace) { mutate(a.Metadata) } } func TestAtespace_EndToEndOpenFGAScenarios(t *testing.T) { @@ -85,37 +85,37 @@ func TestAtespace_EndToEndOpenFGAScenarios(t *testing.T) { aliceCtx := asUser("alice") bobCtx := asUser("bob") - callCreate := func(c context.Context, name string) (*ateapipb.Atespace, error) { - req := &ateapipb.CreateAtespaceRequest{ - Atespace: validAtespace(withAtespaceMetadata(func(m *ateapipb.ResourceMetadata) { m.Name = name })), + callCreate := func(c context.Context, name string) (*ateapi.Atespace, error) { + req := &ateapi.CreateAtespaceRequest{ + Atespace: validAtespace(withAtespaceMetadata(func(m *ateapi.ResourceMetadata) { m.Name = name })), } - resp, err := interceptor(c, req, &grpc.UnaryServerInfo{FullMethod: ateapipb.Control_CreateAtespace_FullMethodName}, func(hc context.Context, r any) (any, error) { - return svc.CreateAtespace(hc, r.(*ateapipb.CreateAtespaceRequest)) + resp, err := interceptor(c, req, &grpc.UnaryServerInfo{FullMethod: ateapi.Control_CreateAtespace_FullMethodName}, func(hc context.Context, r any) (any, error) { + return svc.CreateAtespace(hc, r.(*ateapi.CreateAtespaceRequest)) }) if err != nil { return nil, err } - return resp.(*ateapipb.Atespace), nil + return resp.(*ateapi.Atespace), nil } - callGet := func(c context.Context, name string) (*ateapipb.Atespace, error) { - req := &ateapipb.GetAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: name}} - resp, err := interceptor(c, req, &grpc.UnaryServerInfo{FullMethod: ateapipb.Control_GetAtespace_FullMethodName}, func(hc context.Context, r any) (any, error) { - return svc.GetAtespace(hc, r.(*ateapipb.GetAtespaceRequest)) + callGet := func(c context.Context, name string) (*ateapi.Atespace, error) { + req := &ateapi.GetAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: name}} + resp, err := interceptor(c, req, &grpc.UnaryServerInfo{FullMethod: ateapi.Control_GetAtespace_FullMethodName}, func(hc context.Context, r any) (any, error) { + return svc.GetAtespace(hc, r.(*ateapi.GetAtespaceRequest)) }) if err != nil { return nil, err } - return resp.(*ateapipb.Atespace), nil + return resp.(*ateapi.Atespace), nil } - callDelete := func(c context.Context, name string) (*ateapipb.Atespace, error) { - req := &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: name}} - resp, err := interceptor(c, req, &grpc.UnaryServerInfo{FullMethod: ateapipb.Control_DeleteAtespace_FullMethodName}, func(hc context.Context, r any) (any, error) { - return svc.DeleteAtespace(hc, r.(*ateapipb.DeleteAtespaceRequest)) + callDelete := func(c context.Context, name string) (*ateapi.Atespace, error) { + req := &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: name}} + resp, err := interceptor(c, req, &grpc.UnaryServerInfo{FullMethod: ateapi.Control_DeleteAtespace_FullMethodName}, func(hc context.Context, r any) (any, error) { + return svc.DeleteAtespace(hc, r.(*ateapi.DeleteAtespaceRequest)) }) if err != nil { return nil, err } - return resp.(*ateapipb.Atespace), nil + return resp.(*ateapi.Atespace), nil } grantObjectRole := func(user, role, object string) { @@ -180,8 +180,8 @@ func TestAtespace_EndToEndOpenFGAScenarios(t *testing.T) { } // --- Scenario 2: Non-empty DeleteAtespace fails with FailedPrecondition and preserves permissions --- - tmpl, err := persistence.CreateActorTemplate(ctx, &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-1", Name: "tmpl-1"}, + tmpl, err := persistence.CreateActorTemplate(ctx, &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-1", Name: "tmpl-1"}, }) if err != nil { t.Fatalf("CreateActorTemplate failed: %v", err) diff --git a/cmd/ateapi/internal/controlapi/common_test.go b/cmd/ateapi/internal/controlapi/common_test.go index 2b294108e9..3621a106f4 100644 --- a/cmd/ateapi/internal/controlapi/common_test.go +++ b/cmd/ateapi/internal/controlapi/common_test.go @@ -18,8 +18,8 @@ import ( "context" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/testing/protocmp" "k8s.io/apimachinery/pkg/util/validation/field" ) @@ -31,9 +31,9 @@ const ( ) var ( - ignoreUID = protocmp.IgnoreFields(&ateapipb.ResourceMetadata{}, "uid") - ignoreVersion = protocmp.IgnoreFields(&ateapipb.ResourceMetadata{}, "version") - ignoreTimestamps = protocmp.IgnoreFields(&ateapipb.ResourceMetadata{}, "create_time", "update_time", "delete_time") + ignoreUID = protocmp.IgnoreFields(&ateapi.ResourceMetadata{}, "uid") + ignoreVersion = protocmp.IgnoreFields(&ateapi.ResourceMetadata{}, "version") + ignoreTimestamps = protocmp.IgnoreFields(&ateapi.ResourceMetadata{}, "create_time", "update_time", "delete_time") ) func assertValidateErr(t *testing.T, got field.ErrorList, want field.ErrorList) { @@ -46,7 +46,7 @@ func assertValidateErr(t *testing.T, got field.ErrorList, want field.ErrorList) // is still a meaningful thing to assert on even though a Worker holds a set; // asserting through this keeps them readable and would fail loudly (by looking // at the wrong entry) if a test ever placed two. -func firstAssignment(t *testing.T, st store.Interface, workerName string) *ateapipb.ActorAssignment { +func firstAssignment(t *testing.T, st store.Interface, workerName string) *ateapi.ActorAssignment { t.Helper() page, err := st.ListWorkerAssignments(context.Background(), workerName, store.ListOptions{}) if err != nil { @@ -60,7 +60,7 @@ func firstAssignment(t *testing.T, st store.Interface, workerName string) *ateap // seedAssignment places an actor on an already-created worker, which is how a // test arranges a worker that is already hosting something. -func seedAssignment(t *testing.T, st store.Interface, workerName string, assignment *ateapipb.ActorAssignment) { +func seedAssignment(t *testing.T, st store.Interface, workerName string, assignment *ateapi.ActorAssignment) { t.Helper() if assignment == nil { return diff --git a/cmd/ateapi/internal/controlapi/converter.go b/cmd/ateapi/internal/controlapi/converter.go index 174c371cc3..54e589096d 100644 --- a/cmd/ateapi/internal/controlapi/converter.go +++ b/cmd/ateapi/internal/controlapi/converter.go @@ -15,20 +15,20 @@ package controlapi import ( + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/proto/ateletpb" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // fidelityToAtelet maps the public fidelity ladder onto the identical atelet // wire enum, level by level. Anything else, including UNSPECIFIED, goes out // as UNSPECIFIED, which atelet rejects, rather than being silently promoted. -func fidelityToAtelet(in ateapipb.SnapshotFidelity) ateletpb.SnapshotFidelity { +func fidelityToAtelet(in ateapi.SnapshotFidelity) ateletpb.SnapshotFidelity { switch in { - case ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES: + case ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES: return ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES - case ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS: + case ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS: return ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS - case ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY: + case ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY: return ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY default: return ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED @@ -37,28 +37,28 @@ func fidelityToAtelet(in ateapipb.SnapshotFidelity) ateletpb.SnapshotFidelity { // fidelityFromAtelet maps atelet's fidelity enum back onto the identical // public one. Anything else comes back UNSPECIFIED. -func fidelityFromAtelet(in ateletpb.SnapshotFidelity) ateapipb.SnapshotFidelity { +func fidelityFromAtelet(in ateletpb.SnapshotFidelity) ateapi.SnapshotFidelity { switch in { case ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES: - return ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES + return ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES case ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS: - return ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS + return ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS case ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY: - return ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + return ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY default: - return ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED + return ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED } } // snapshotReportFromAtelet converts a snapshot atelet reports into the form // ReportActorSnapshotState takes, which carries the snapshot's fields inline. // A report that names no snapshot converts to nil. -func snapshotReportFromAtelet(r *ateletpb.SnapshotReport) *ateapipb.SnapshotReport { +func snapshotReportFromAtelet(r *ateletpb.SnapshotReport) *ateapi.SnapshotReport { if r.GetSnapshot() == nil { return nil } snap := r.GetSnapshot() - out := &ateapipb.SnapshotReport{ + out := &ateapi.SnapshotReport{ Uuid: snap.GetSnapshotUuid(), Generation: snap.GetGeneration(), Fidelity: fidelityFromAtelet(snap.GetFidelity()), @@ -66,7 +66,7 @@ func snapshotReportFromAtelet(r *ateletpb.SnapshotReport) *ateapipb.SnapshotRepo DurableCompleteTime: r.GetDurableCompleteTime(), } if obj := snap.GetObject(); obj != nil { - out.Object = &ateapipb.ObjectSnapshot{SnapshotUri: obj.GetSnapshotUri()} + out.Object = &ateapi.ObjectSnapshot{SnapshotUri: obj.GetSnapshotUri()} } return out } diff --git a/cmd/ateapi/internal/controlapi/converter_test.go b/cmd/ateapi/internal/controlapi/converter_test.go index 5266c46e38..208e3cfb7c 100644 --- a/cmd/ateapi/internal/controlapi/converter_test.go +++ b/cmd/ateapi/internal/controlapi/converter_test.go @@ -22,8 +22,8 @@ import ( "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/timestamppb" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/proto/ateletpb" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // TestFidelityToAtelet pins the level-by-level mapping onto the atelet enum: @@ -31,32 +31,32 @@ import ( func TestFidelityToAtelet(t *testing.T) { tests := []struct { name string - in ateapipb.SnapshotFidelity + in ateapi.SnapshotFidelity expected ateletpb.SnapshotFidelity }{ { name: "memory", - in: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + in: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, expected: ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, }, { name: "rootfs", - in: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, + in: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, expected: ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, }, { name: "volumes", - in: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, + in: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, expected: ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, }, { name: "unspecified stays unspecified", - in: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED, + in: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED, expected: ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED, }, { name: "value outside the enum", - in: ateapipb.SnapshotFidelity(99), + in: ateapi.SnapshotFidelity(99), expected: ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED, }, } @@ -77,13 +77,13 @@ func TestFidelityFromAtelet(t *testing.T) { tests := []struct { name string in ateletpb.SnapshotFidelity - want ateapipb.SnapshotFidelity + want ateapi.SnapshotFidelity }{ - {"memory", ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}, - {"rootfs", ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS}, - {"volumes", ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES}, - {"unspecified stays unspecified", ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED}, - {"value outside the enum", ateletpb.SnapshotFidelity(99), ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED}, + {"memory", ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}, + {"rootfs", ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS}, + {"volumes", ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES}, + {"unspecified stays unspecified", ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED}, + {"value outside the enum", ateletpb.SnapshotFidelity(99), ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -100,7 +100,7 @@ func TestSnapshotReportFromAtelet(t *testing.T) { tests := []struct { name string in *ateletpb.SnapshotReport - want *ateapipb.SnapshotReport + want *ateapi.SnapshotReport }{{ name: "every field", in: &ateletpb.SnapshotReport{ @@ -113,11 +113,11 @@ func TestSnapshotReportFromAtelet(t *testing.T) { LocalCommitTime: committed, DurableCompleteTime: uploaded, }, - want: &ateapipb.SnapshotReport{ + want: &ateapi.SnapshotReport{ Uuid: "snap-2", Generation: 2, - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: "gs://snapshots/snap-2"}, + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, + Object: &ateapi.ObjectSnapshot{SnapshotUri: "gs://snapshots/snap-2"}, LocalCommitTime: committed, DurableCompleteTime: uploaded, }, @@ -127,10 +127,10 @@ func TestSnapshotReportFromAtelet(t *testing.T) { Snapshot: &ateletpb.Snapshot{SnapshotUuid: "snap-3", Generation: 3, Fidelity: ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}, LocalCommitTime: committed, }, - want: &ateapipb.SnapshotReport{ + want: &ateapi.SnapshotReport{ Uuid: "snap-3", Generation: 3, - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, LocalCommitTime: committed, }, }, { diff --git a/cmd/ateapi/internal/controlapi/crash.go b/cmd/ateapi/internal/controlapi/crash.go index 05b8236a2a..382b144a39 100644 --- a/cmd/ateapi/internal/controlapi/crash.go +++ b/cmd/ateapi/internal/controlapi/crash.go @@ -21,12 +21,12 @@ import ( "log/slog" "strings" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/actorevent" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" @@ -128,13 +128,8 @@ func crashActor(ctx context.Context, st crashActorStore, actorRef resources.Acto if err != nil { return fmt.Errorf("while loading actor to crash: %w", err) } - return crashActorVersion(ctx, st, actorRef, actor, opName, message) -} -// crashActorVersion is crashActor for actor as already read. It fails with -// store.ErrVersionConflict if the actor changed since. -func crashActorVersion(ctx context.Context, st crashActorStore, actorRef resources.ActorRef, actor *ateapipb.Actor, opName, message string) error { - wasAlreadyCrashed := actor.GetStatus().GetState() == ateapipb.ActorState_ACTOR_STATE_CRASHED + wasAlreadyCrashed := actor.GetStatus().GetState() == ateapi.ActorState_ACTOR_STATE_CRASHED opName = ateattr.NormalizeOperationName(opName) // Release the worker before moving the actor to CRASHED state. @@ -154,8 +149,8 @@ func crashActorVersion(ctx context.Context, st crashActorStore, actorRef resourc sandboxClass := actor.GetStatus().GetWorkerAssignment().GetSandboxRuntime().GetSandboxClass() crashAttrs := ateattr.ActorMetricAttributes(actor, sandboxClass, opName) - if _, err := st.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapipb.Actor) error { - toUpdate.Status.State = ateapipb.ActorState_ACTOR_STATE_CRASHED + if _, err := st.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapi.Actor) error { + toUpdate.Status.State = ateapi.ActorState_ACTOR_STATE_CRASHED // An actor crashed concurrently, e.g. by worker deletion, keeps its first crash. if !wasAlreadyCrashed { toUpdate.Status.Crash = newActorCrash(opName, message) @@ -182,11 +177,11 @@ func crashActorVersion(ctx context.Context, st crashActorStore, actorRef resourc // newActorCrash records a crash that happens now, prefixing message with the // operation that failed when it is known. -func newActorCrash(opName, message string) *ateapipb.ActorCrash { +func newActorCrash(opName, message string) *ateapi.ActorCrash { if opName = ateattr.NormalizeOperationName(opName); opName != ateattr.OperationUnknown { message = opName + " failed: " + message } - return &ateapipb.ActorCrash{ + return &ateapi.ActorCrash{ Message: truncateUTF8(strings.ToValidUTF8(message, "�"), maxCrashMessageBytes), CrashTime: timestamppb.Now(), } @@ -199,7 +194,7 @@ func newActorCrash(opName, message string) *ateapipb.ActorCrash { // It names ate.actor.state for the same reason worker's lifecycle records do: a // crash is the one transition worker never observes, so a consumer taking the // last state an actor reached has to see this record to reach "crashed" at all. -func logActorCrashed(ctx context.Context, actor *ateapipb.Actor, opName string) { +func logActorCrashed(ctx context.Context, actor *ateapi.Actor, opName string) { attrs := ateattr.ActorLogAttrs(resources.ActorAttributionFromActor(actor)) attrs = append(attrs, slog.String(string(ateattr.ActorOperationNameKey), ateattr.NormalizeOperationName(opName))) attrs = append(attrs, slog.String(string(ateattr.ActorStateKey), ateattr.ActorStateCrashed)) @@ -209,17 +204,17 @@ func logActorCrashed(ctx context.Context, actor *ateapipb.Actor, opName string) // crashActorStore encapsulates the subset of store operations needed to crash // an actor. type crashActorStore interface { - GetActor(ctx context.Context, actorRef resources.ActorRef) (*ateapipb.Actor, error) - UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(toUpdate *ateapipb.Actor) error) (*ateapipb.Actor, error) - GetWorker(ctx context.Context, name string) (*ateapipb.Worker, error) - ReleaseActorFromWorker(ctx context.Context, workerName string, actorUID string) (*ateapipb.Worker, error) + GetActor(ctx context.Context, actorRef resources.ActorRef) (*ateapi.Actor, error) + UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(toUpdate *ateapi.Actor) error) (*ateapi.Actor, error) + GetWorker(ctx context.Context, name string) (*ateapi.Worker, error) + ReleaseActorFromWorker(ctx context.Context, workerName string, actorUID string) (*ateapi.Worker, error) } // releaseWorker clears the worker's assignment if it still points at the given // actor. A missing worker or an already-cleared assignment is not an error. // It returns the worker as it stands after the release, which callers holding // a cache of workers hand to it. -func releaseWorker(ctx context.Context, st crashActorStore, actor *ateapipb.Actor) (*ateapipb.Worker, error) { +func releaseWorker(ctx context.Context, st crashActorStore, actor *ateapi.Actor) (*ateapi.Worker, error) { assignment := actor.GetStatus().GetWorkerAssignment() if assignment == nil { slog.WarnContext(ctx, "Actor's worker assignment is already cleared") diff --git a/cmd/ateapi/internal/controlapi/crash_test.go b/cmd/ateapi/internal/controlapi/crash_test.go index 079a993d58..03d6d925c6 100644 --- a/cmd/ateapi/internal/controlapi/crash_test.go +++ b/cmd/ateapi/internal/controlapi/crash_test.go @@ -28,13 +28,13 @@ import ( "time" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/actorevent" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel/attribute" otellog "go.opentelemetry.io/otel/log" "go.opentelemetry.io/otel/log/global" @@ -51,12 +51,12 @@ import ( func seedActor(t *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef) { t.Helper() - storetest.MustCreateActor(t, ctx, st, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorRef.Name, Atespace: actorRef.Atespace}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: "uid"}, + storetest.MustCreateActor(t, ctx, st, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorRef.Name, Atespace: actorRef.Atespace}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: "uid"}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "pod", @@ -64,8 +64,8 @@ func seedActor(t *testing.T, ctx context.Context, st store.Interface, actorRef r WorkerPodIps: []string{"1.2.3.4"}, }, LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "reserved-snapshot", "gs://bucket/atespaces/as/actors/uid/snapshots/reserved-snapshot", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "reserved-snapshot", "gs://bucket/atespaces/as/actors/uid/snapshots/reserved-snapshot", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), }, }, }) @@ -75,13 +75,13 @@ func seedActor(t *testing.T, ctx context.Context, st store.Interface, actorRef r // assigned to the given actor (unassigned if assigned is the zero ActorRef). func seedWorker(t *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef) { t.Helper() - worker := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "uid"}, + worker := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "uid"}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "pod", WorkerPodUid: "uid", - Status: &ateapipb.WorkerStatus{}, + Status: &ateapi.WorkerStatus{}, } if _, err := st.CreateWorker(ctx, worker); err != nil { t.Fatalf("seed worker: %v", err) @@ -89,13 +89,13 @@ func seedWorker(t *testing.T, ctx context.Context, st store.Interface, actorRef if actorRef == (resources.ActorRef{}) { return } - assignment := &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: actorRef.Atespace, Name: actorRef.Name}, + assignment := &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorUid: "synthetic-" + actorRef.Name, } if actor, err := st.GetActor(ctx, actorRef); err == nil { - assignment = &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: actor.GetMetadata().GetAtespace(), Name: actor.GetMetadata().GetName()}, + assignment = &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: actor.GetMetadata().GetAtespace(), Name: actor.GetMetadata().GetName()}, ActorUid: actor.GetMetadata().GetUid(), } } @@ -106,13 +106,13 @@ func seedWorker(t *testing.T, ctx context.Context, st store.Interface, actorRef // already cleared, e.g. by a prior release. func seedUnboundActor(t *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef) { t.Helper() - storetest.MustCreateActor(t, ctx, st, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorRef.Name, Atespace: actorRef.Atespace}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, + storetest.MustCreateActor(t, ctx, st, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorRef.Name, Atespace: actorRef.Atespace}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "reserved-snapshot", "gs://bucket/atespaces/as/actors/uid/snapshots/reserved-snapshot", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "reserved-snapshot", "gs://bucket/atespaces/as/actors/uid/snapshots/reserved-snapshot", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), }, }, }) @@ -126,11 +126,11 @@ func assertCrashed(t *testing.T, ctx context.Context, st store.Interface, actorR if err != nil { t.Fatalf("GetActor(%v) = %v, want nil", actorRef, err) } - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { - t.Errorf("status = %v, want %v", got.GetStatus().GetState(), ateapipb.ActorState_ACTOR_STATE_CRASHED) + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { + t.Errorf("status = %v, want %v", got.GetStatus().GetState(), ateapi.ActorState_ACTOR_STATE_CRASHED) } // Keep the snapshot uri for debugging. - if findLatestDurableSnapshot(got.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) == nil { + if findLatestDurableSnapshot(got.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) == nil { t.Error(`in-progress durable snapshot URI = "", want preserved`) } if got.GetStatus().GetWorkerAssignment() != nil { @@ -203,19 +203,19 @@ func TestCrashActor(t *testing.T) { seed: true, setup: func(t *testing.T, ctx context.Context, st store.Interface) { // Create a worker assigned to the same actorRef, but with a stale UID - worker := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "uid"}, + worker := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "uid"}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "pod", WorkerPodUid: "uid", - Status: &ateapipb.WorkerStatus{}, + Status: &ateapi.WorkerStatus{}, } if _, err := st.CreateWorker(ctx, worker); err != nil { t.Fatalf("CreateWorker: %v", err) } - seedAssignment(t, st, "uid", &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: actorRef.Atespace, Name: actorRef.Name}, + seedAssignment(t, st, "uid", &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorUid: "stale-incarnation-uid", }) }, @@ -370,7 +370,7 @@ func TestHandleAteletError(t *testing.T) { isTerminateRPC bool err error wantCode codes.Code - wantState ateapipb.ActorState + wantState ateapi.ActorState }{ { name: "Unavailable leaves the actor as it was", @@ -378,7 +378,7 @@ func TestHandleAteletError(t *testing.T) { rpc: "Restore", err: status.Error(codes.Unavailable, "connection refused"), wantCode: codes.Unavailable, - wantState: ateapipb.ActorState_ACTOR_STATE_RUNNING, + wantState: ateapi.ActorState_ACTOR_STATE_RUNNING, }, { name: "Canceled leaves the actor as it was", @@ -386,7 +386,7 @@ func TestHandleAteletError(t *testing.T) { rpc: "Restore", err: status.Error(codes.Canceled, "grpc: the client connection is closing"), wantCode: codes.Internal, - wantState: ateapipb.ActorState_ACTOR_STATE_RUNNING, + wantState: ateapi.ActorState_ACTOR_STATE_RUNNING, }, { name: "DeadlineExceeded leaves the actor as it was", @@ -394,7 +394,7 @@ func TestHandleAteletError(t *testing.T) { rpc: "Restore", err: status.Error(codes.DeadlineExceeded, "context deadline exceeded"), wantCode: codes.Internal, - wantState: ateapipb.ActorState_ACTOR_STATE_RUNNING, + wantState: ateapi.ActorState_ACTOR_STATE_RUNNING, }, { name: "wrapped Unavailable leaves the actor as it was", @@ -402,7 +402,7 @@ func TestHandleAteletError(t *testing.T) { rpc: "Restore", err: fmt.Errorf("while restoring actor: %w", status.Error(codes.Unavailable, "connection refused")), wantCode: codes.Unavailable, - wantState: ateapipb.ActorState_ACTOR_STATE_RUNNING, + wantState: ateapi.ActorState_ACTOR_STATE_RUNNING, }, { name: "cancelled caller gets Canceled and leaves the actor as it was", @@ -410,7 +410,7 @@ func TestHandleAteletError(t *testing.T) { rpc: "Restore", err: fmt.Errorf("while restoring actor: %w", status.Error(codes.Canceled, "connection closing")), wantCode: codes.Canceled, - wantState: ateapipb.ActorState_ACTOR_STATE_RUNNING, + wantState: ateapi.ActorState_ACTOR_STATE_RUNNING, }, { name: "expired caller deadline gets DeadlineExceeded and leaves the actor as it was", @@ -418,7 +418,7 @@ func TestHandleAteletError(t *testing.T) { rpc: "Restore", err: fmt.Errorf("while restoring actor: %w", status.Error(codes.DeadlineExceeded, "restore reply timed out")), wantCode: codes.DeadlineExceeded, - wantState: ateapipb.ActorState_ACTOR_STATE_RUNNING, + wantState: ateapi.ActorState_ACTOR_STATE_RUNNING, }, { name: "ended workflow context leaves the actor as it was", @@ -426,7 +426,7 @@ func TestHandleAteletError(t *testing.T) { rpc: "Restore", err: status.Error(codes.Internal, "context canceled"), wantCode: codes.Canceled, - wantState: ateapipb.ActorState_ACTOR_STATE_RUNNING, + wantState: ateapi.ActorState_ACTOR_STATE_RUNNING, }, { name: "Internal crashes the actor", @@ -434,7 +434,7 @@ func TestHandleAteletError(t *testing.T) { rpc: "Restore", err: status.Error(codes.Internal, "while reading local snapshot manifest"), wantCode: codes.Internal, - wantState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + wantState: ateapi.ActorState_ACTOR_STATE_CRASHED, }, { name: "FailedPrecondition crashes the actor", @@ -442,7 +442,7 @@ func TestHandleAteletError(t *testing.T) { rpc: "Restore", err: status.Error(codes.FailedPrecondition, "invalid checkpoint result"), wantCode: codes.Internal, - wantState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + wantState: ateapi.ActorState_ACTOR_STATE_CRASHED, }, { name: "plain error crashes the actor", @@ -450,7 +450,7 @@ func TestHandleAteletError(t *testing.T) { rpc: "Restore", err: errors.New("while getting atelet conn"), wantCode: codes.Internal, - wantState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + wantState: ateapi.ActorState_ACTOR_STATE_CRASHED, }, { name: "Terminate leaves the actor as it was", @@ -459,7 +459,7 @@ func TestHandleAteletError(t *testing.T) { isTerminateRPC: true, err: status.Error(codes.Internal, "while unmounting volumes"), wantCode: codes.Internal, - wantState: ateapipb.ActorState_ACTOR_STATE_RUNNING, + wantState: ateapi.ActorState_ACTOR_STATE_RUNNING, }, } for _, tt := range tests { @@ -493,7 +493,7 @@ func TestHandleAteletError(t *testing.T) { if got := actor.GetStatus().GetState(); got != tt.wantState { t.Errorf("state = %v, want %v", got, tt.wantState) } - if tt.wantState != ateapipb.ActorState_ACTOR_STATE_CRASHED && actor.GetStatus().GetWorkerAssignment() == nil { + if tt.wantState != ateapi.ActorState_ACTOR_STATE_CRASHED && actor.GetStatus().GetWorkerAssignment() == nil { t.Error("worker assignment was cleared, want it kept for the retry") } }) @@ -561,34 +561,34 @@ func TestCrashActor_Metrics(t *testing.T) { defer cleanup() actorRef := resources.ActorRef{Atespace: "demo-ns", Name: "counter-actor"} - worker := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "pod-uid-1"}, + worker := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "pod-uid-1"}, WorkerNamespace: "demo-ns", WorkerPool: "pool-1", WorkerPod: "pod-1", WorkerPodUid: "pod-uid-1", - Status: &ateapipb.WorkerStatus{}, + Status: &ateapi.WorkerStatus{}, } if _, err := st.CreateWorker(ctx, worker); err != nil { t.Fatalf("CreateWorker: %v", err) } - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "demo-ns", Name: "counter-actor", Uid: "actor-uid-1", }, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "demo-ns", Name: "counter-template"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: "pod-uid-1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "demo-ns", Name: "counter-template"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: "pod-uid-1"}, WorkerNamespace: "demo-ns", WorkerPool: "pool-1", WorkerPod: "pod-1", WorkerPodUid: "pod-uid-1", - SandboxRuntime: &ateapipb.ActorSandboxRuntime{SandboxClass: "gvisor"}, + SandboxRuntime: &ateapi.ActorSandboxRuntime{SandboxClass: "gvisor"}, }, }, } @@ -674,7 +674,7 @@ type failingReleaseStore struct { err error } -func (f failingReleaseStore) ReleaseActorFromWorker(context.Context, string, string) (*ateapipb.Worker, error) { +func (f failingReleaseStore) ReleaseActorFromWorker(context.Context, string, string) (*ateapi.Worker, error) { return nil, f.err } @@ -708,8 +708,8 @@ func TestCrashActorReleaseFailureLeavesWorkerReclaimable(t *testing.T) { if gerr != nil { t.Fatalf("GetActor() = %v, want nil", gerr) } - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { - t.Errorf("status = %v, want %v (actor must not be crashed when the release fails)", got.GetStatus().GetState(), ateapipb.ActorState_ACTOR_STATE_RUNNING) + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { + t.Errorf("status = %v, want %v (actor must not be crashed when the release fails)", got.GetStatus().GetState(), ateapi.ActorState_ACTOR_STATE_RUNNING) } if got.GetStatus().GetWorkerAssignment() == nil { t.Error("WorkerAssignment cleared, want preserved so the release can be retried") @@ -761,8 +761,8 @@ func TestCrashActorAndFail(t *testing.T) { if gerr != nil { t.Fatalf("GetActor() = %v, want nil", gerr) } - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { - t.Errorf("status = %v, want %v (the crash did not commit)", got.GetStatus().GetState(), ateapipb.ActorState_ACTOR_STATE_RUNNING) + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { + t.Errorf("status = %v, want %v (the crash did not commit)", got.GetStatus().GetState(), ateapi.ActorState_ACTOR_STATE_RUNNING) } }) } @@ -925,10 +925,10 @@ func TestCrashActor_RecordAndCounterAgree(t *testing.T) { defer cleanup() actorRef := resources.ActorRef{Atespace: "demo-ns", Name: "counter-actor"} - storetest.MustCreateActor(t, ctx, st, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "demo-ns", Name: "counter-template"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + storetest.MustCreateActor(t, ctx, st, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "demo-ns", Name: "counter-template"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, }) if err := crashActor(ctx, st, actorRef, ateattr.OperationResume, "test crash"); err != nil { diff --git a/cmd/ateapi/internal/controlapi/delete_options.go b/cmd/ateapi/internal/controlapi/delete_options.go index 85a83f1930..9e34ef3d69 100644 --- a/cmd/ateapi/internal/controlapi/delete_options.go +++ b/cmd/ateapi/internal/controlapi/delete_options.go @@ -15,10 +15,10 @@ package controlapi import ( + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) -func toDeletePreconditions(opts *ateapipb.DeleteOptions) store.DeletePreconditions { +func toDeletePreconditions(opts *ateapi.DeleteOptions) store.DeletePreconditions { return store.DeletePreconditions{UID: opts.GetUid(), Version: opts.GetVersion()} } diff --git a/cmd/ateapi/internal/controlapi/egress_policy.go b/cmd/ateapi/internal/controlapi/egress_policy.go index 0072db889f..48ef447049 100644 --- a/cmd/ateapi/internal/controlapi/egress_policy.go +++ b/cmd/ateapi/internal/controlapi/egress_policy.go @@ -19,17 +19,17 @@ import ( "errors" "fmt" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/defaults" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" "k8s.io/apimachinery/pkg/util/validation/field" ) -func (s *RPCService) CreateActorEgressPolicy(ctx context.Context, req *ateapipb.CreateActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) { +func (s *RPCService) CreateActorEgressPolicy(ctx context.Context, req *ateapi.CreateActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) { // First scrub any fields that users are not allowed to set, then fill the // defaults so validation sees the final resource state. policy := req.GetEgressPolicy() @@ -44,12 +44,12 @@ func (s *RPCService) CreateActorEgressPolicy(ctx context.Context, req *ateapipb. return s.impl.CreateEgressPolicy(ctx, actorRef, policy) } -func (s *ServiceImpl) CreateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, policy *ateapipb.EgressPolicy) (*ateapipb.EgressPolicy, error) { +func (s *ServiceImpl) CreateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, policy *ateapi.EgressPolicy) (*ateapi.EgressPolicy, error) { created, err := s.store.CreateEgressPolicy(ctx, actorRef, policy) return mapEgressPolicyWrite(created, err) } -func (s *RPCService) GetActorEgressPolicy(ctx context.Context, req *ateapipb.GetActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) { +func (s *RPCService) GetActorEgressPolicy(ctx context.Context, req *ateapi.GetActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) { if errs := apivalidation.ValidateGetActorEgressPolicyRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -57,7 +57,7 @@ func (s *RPCService) GetActorEgressPolicy(ctx context.Context, req *ateapipb.Get return s.impl.GetEgressPolicy(ctx, resources.ActorRefFromObjectRef(req.GetActor())) } -func (s *ServiceImpl) GetEgressPolicy(ctx context.Context, actorRef resources.ActorRef) (*ateapipb.EgressPolicy, error) { +func (s *ServiceImpl) GetEgressPolicy(ctx context.Context, actorRef resources.ActorRef) (*ateapi.EgressPolicy, error) { policy, err := s.store.GetEgressPolicy(ctx, actorRef) if errors.Is(err, store.ErrNotFound) { return nil, apierror.NotFound("EgressPolicy for actor %s not found", actorRef) @@ -68,7 +68,7 @@ func (s *ServiceImpl) GetEgressPolicy(ctx context.Context, actorRef resources.Ac return policy, nil } -func (s *RPCService) UpdateActorEgressPolicy(ctx context.Context, req *ateapipb.UpdateActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) { +func (s *RPCService) UpdateActorEgressPolicy(ctx context.Context, req *ateapi.UpdateActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) { policy := req.GetEgressPolicy() if policy != nil { scrubResourceMetadataForUpdate(policy.Metadata) @@ -77,7 +77,7 @@ func (s *RPCService) UpdateActorEgressPolicy(ctx context.Context, req *ateapipb. return nil, resources.ToAPIError(errs) } actorRef := resources.ActorRefFromObjectRef(req.GetActor()) - return s.impl.UpdateEgressPolicy(ctx, actorRef, store.PreconditionFrom(policy), func(toUpdate *ateapipb.EgressPolicy) error { + return s.impl.UpdateEgressPolicy(ctx, actorRef, store.PreconditionFrom(policy), func(toUpdate *ateapi.EgressPolicy) error { metadata := toUpdate.GetMetadata() proto.Reset(toUpdate) proto.Merge(toUpdate, policy) @@ -87,9 +87,9 @@ func (s *RPCService) UpdateActorEgressPolicy(ctx context.Context, req *ateapipb. }) } -func (s *ServiceImpl) UpdateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(*ateapipb.EgressPolicy) error) (*ateapipb.EgressPolicy, error) { - updated, err := s.store.UpdateEgressPolicy(ctx, actorRef, precondition, func(toUpdate *ateapipb.EgressPolicy) error { - oldVal := proto.Clone(toUpdate).(*ateapipb.EgressPolicy) +func (s *ServiceImpl) UpdateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(*ateapi.EgressPolicy) error) (*ateapi.EgressPolicy, error) { + updated, err := s.store.UpdateEgressPolicy(ctx, actorRef, precondition, func(toUpdate *ateapi.EgressPolicy) error { + oldVal := proto.Clone(toUpdate).(*ateapi.EgressPolicy) if err := mutate(toUpdate); err != nil { return err } @@ -102,7 +102,7 @@ func (s *ServiceImpl) UpdateEgressPolicy(ctx context.Context, actorRef resources return mapEgressPolicyWrite(updated, err) } -func (s *RPCService) DeleteActorEgressPolicy(ctx context.Context, req *ateapipb.DeleteActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) { +func (s *RPCService) DeleteActorEgressPolicy(ctx context.Context, req *ateapi.DeleteActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) { if errs := apivalidation.ValidateDeleteActorEgressPolicyRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -110,12 +110,12 @@ func (s *RPCService) DeleteActorEgressPolicy(ctx context.Context, req *ateapipb. return s.impl.DeleteEgressPolicy(ctx, resources.ActorRefFromObjectRef(req.GetActor()), toDeletePreconditions(req.GetOptions())) } -func (s *ServiceImpl) DeleteEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (*ateapipb.EgressPolicy, error) { +func (s *ServiceImpl) DeleteEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (*ateapi.EgressPolicy, error) { deleted, err := s.store.DeleteEgressPolicy(ctx, actorRef, precondition) return mapEgressPolicyWrite(deleted, err) } -func mapEgressPolicyWrite(policy *ateapipb.EgressPolicy, err error) (*ateapipb.EgressPolicy, error) { +func mapEgressPolicyWrite(policy *ateapi.EgressPolicy, err error) (*ateapi.EgressPolicy, error) { switch { case err == nil: return policy, nil diff --git a/cmd/ateapi/internal/controlapi/egress_policy_test.go b/cmd/ateapi/internal/controlapi/egress_policy_test.go index 99552be053..386d265447 100644 --- a/cmd/ateapi/internal/controlapi/egress_policy_test.go +++ b/cmd/ateapi/internal/controlapi/egress_policy_test.go @@ -17,11 +17,11 @@ package controlapi import ( "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" ) @@ -30,45 +30,45 @@ func TestActorEgressPolicy(t *testing.T) { persistence, cleanup := storetest.SetupTestStore(t) defer cleanup() service := &RPCService{impl: &ServiceImpl{store: persistence}} - if _, err := persistence.CreateAtespace(t.Context(), &ateapipb.Atespace{ - Metadata: &ateapipb.ResourceMetadata{Name: testAtespace}, + if _, err := persistence.CreateAtespace(t.Context(), &ateapi.Atespace{ + Metadata: &ateapi.ResourceMetadata{Name: testAtespace}, }); err != nil { t.Fatal(err) } - _, err := persistence.CreateActor(t.Context(), &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "egress-actor"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + _, err := persistence.CreateActor(t.Context(), &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "egress-actor"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, }) if err != nil { t.Fatal(err) } - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "egress-actor"} + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "egress-actor"} - if _, err := service.GetActorEgressPolicy(t.Context(), &ateapipb.GetActorEgressPolicyRequest{ + if _, err := service.GetActorEgressPolicy(t.Context(), &ateapi.GetActorEgressPolicyRequest{ Actor: actorRef, Name: resources.SingletonName, }); apierror.Code(err) != codes.NotFound { t.Fatalf("policy before create status = %v, want NotFound", apierror.Code(err)) } - if _, err := service.GetActorEgressPolicy(t.Context(), &ateapipb.GetActorEgressPolicyRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "missing-actor"}, + if _, err := service.GetActorEgressPolicy(t.Context(), &ateapi.GetActorEgressPolicyRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "missing-actor"}, Name: resources.SingletonName, }); apierror.Code(err) != codes.NotFound { t.Fatalf("missing parent status = %v, want NotFound", apierror.Code(err)) } - created, err := service.CreateActorEgressPolicy(t.Context(), &ateapipb.CreateActorEgressPolicyRequest{ + created, err := service.CreateActorEgressPolicy(t.Context(), &ateapi.CreateActorEgressPolicyRequest{ Actor: actorRef, - EgressPolicy: &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{ + EgressPolicy: &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{ Atespace: testAtespace, Name: "default", Uid: "ignored", Version: 99, - }, Rules: []*ateapipb.EgressRule{{ - Http: &ateapipb.HttpRule{ + }, Rules: []*ateapi.EgressRule{{ + Http: &ateapi.HttpRule{ Hostnames: []string{"api.example.com"}, - Effects: &ateapipb.HttpRuleEffects{ - ReplaceHeaders: []*ateapipb.CredentialHeader{{ + Effects: &ateapi.HttpRuleEffects{ + ReplaceHeaders: []*ateapi.CredentialHeader{{ Header: "Authorization", Prefix: "Bearer ", CredentialUri: "ate-secret://kubernetes.io/provider/ns/name", @@ -81,10 +81,10 @@ func TestActorEgressPolicy(t *testing.T) { if err != nil { t.Fatal(err) } - if _, err := service.CreateActorEgressPolicy(t.Context(), &ateapipb.CreateActorEgressPolicyRequest{ + if _, err := service.CreateActorEgressPolicy(t.Context(), &ateapi.CreateActorEgressPolicyRequest{ Actor: actorRef, - EgressPolicy: &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "default"}, + EgressPolicy: &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "default"}, }, }); apierror.Code(err) != codes.AlreadyExists { t.Fatalf("create collision status = %v, want AlreadyExists", apierror.Code(err)) @@ -95,50 +95,50 @@ func TestActorEgressPolicy(t *testing.T) { if md := created.GetMetadata(); md.GetName() != "default" || md.GetAtespace() != testAtespace || md.GetUid() == "" || md.GetVersion() != 1 || md.GetCreateTime() == nil || md.GetUpdateTime() == nil { t.Fatalf("created metadata = %v", md) } - got, err := service.GetActorEgressPolicy(t.Context(), &ateapipb.GetActorEgressPolicyRequest{Actor: actorRef, Name: resources.SingletonName}) + got, err := service.GetActorEgressPolicy(t.Context(), &ateapi.GetActorEgressPolicyRequest{Actor: actorRef, Name: resources.SingletonName}) if err != nil || !proto.Equal(got, created) { t.Fatalf("policy after create = %v, %v; want %v", got, err, created) } - if _, err := service.impl.UpdateEgressPolicy(t.Context(), resources.ActorRefFromObjectRef(actorRef), store.PreconditionFrom(created), func(policy *ateapipb.EgressPolicy) error { + if _, err := service.impl.UpdateEgressPolicy(t.Context(), resources.ActorRefFromObjectRef(actorRef), store.PreconditionFrom(created), func(policy *ateapi.EgressPolicy) error { policy.Rules[0].Http.Hostnames = nil return nil }); apierror.Code(err) != codes.InvalidArgument { t.Fatalf("invalid internal update status = %v, want InvalidArgument", apierror.Code(err)) } - replacement := proto.Clone(created).(*ateapipb.EgressPolicy) + replacement := proto.Clone(created).(*ateapi.EgressPolicy) replacement.Rules = nil - missingPreconditions := proto.Clone(replacement).(*ateapipb.EgressPolicy) + missingPreconditions := proto.Clone(replacement).(*ateapi.EgressPolicy) missingPreconditions.Metadata.Uid = "" missingPreconditions.Metadata.Version = 0 - if _, err := service.UpdateActorEgressPolicy(t.Context(), &ateapipb.UpdateActorEgressPolicyRequest{ + if _, err := service.UpdateActorEgressPolicy(t.Context(), &ateapi.UpdateActorEgressPolicyRequest{ Actor: actorRef, EgressPolicy: missingPreconditions, }); apierror.Code(err) != codes.InvalidArgument { t.Fatalf("missing preconditions status = %v, want InvalidArgument", apierror.Code(err)) } - changedIdentity := proto.Clone(replacement).(*ateapipb.EgressPolicy) + changedIdentity := proto.Clone(replacement).(*ateapi.EgressPolicy) changedIdentity.Metadata.Atespace = "other" changedIdentity.Metadata.Name = "other" - if _, err := service.UpdateActorEgressPolicy(t.Context(), &ateapipb.UpdateActorEgressPolicyRequest{ + if _, err := service.UpdateActorEgressPolicy(t.Context(), &ateapi.UpdateActorEgressPolicyRequest{ Actor: actorRef, EgressPolicy: changedIdentity, }); apierror.Code(err) != codes.InvalidArgument { t.Fatalf("changed identity status = %v, want InvalidArgument", apierror.Code(err)) } - updated, err := service.UpdateActorEgressPolicy(t.Context(), &ateapipb.UpdateActorEgressPolicyRequest{ + updated, err := service.UpdateActorEgressPolicy(t.Context(), &ateapi.UpdateActorEgressPolicyRequest{ Actor: actorRef, EgressPolicy: replacement, }) if err != nil || updated.GetMetadata().GetVersion() != 2 || len(updated.GetRules()) != 0 { t.Fatalf("replacement = %v, %v; want empty version 2", updated, err) } - if _, err := service.UpdateActorEgressPolicy(t.Context(), &ateapipb.UpdateActorEgressPolicyRequest{ + if _, err := service.UpdateActorEgressPolicy(t.Context(), &ateapi.UpdateActorEgressPolicyRequest{ Actor: actorRef, EgressPolicy: replacement, }); apierror.Code(err) != codes.Aborted { t.Fatalf("stale replacement status = %v, want Aborted", apierror.Code(err)) } - deleted, err := service.DeleteActorEgressPolicy(t.Context(), &ateapipb.DeleteActorEgressPolicyRequest{ + deleted, err := service.DeleteActorEgressPolicy(t.Context(), &ateapi.DeleteActorEgressPolicyRequest{ Actor: actorRef, Name: resources.SingletonName, }) @@ -152,7 +152,7 @@ func TestActorEgressPolicy(t *testing.T) { if !proto.Equal(deleted, updated) { t.Fatalf("deleted policy = %v; want %v with delete_time set", deleted, updated) } - if _, err := service.GetActorEgressPolicy(t.Context(), &ateapipb.GetActorEgressPolicyRequest{ + if _, err := service.GetActorEgressPolicy(t.Context(), &ateapi.GetActorEgressPolicyRequest{ Actor: actorRef, Name: resources.SingletonName, }); apierror.Code(err) != codes.NotFound { diff --git a/cmd/ateapi/internal/controlapi/export_test.go b/cmd/ateapi/internal/controlapi/export_test.go index daeed181c6..c1953553a8 100644 --- a/cmd/ateapi/internal/controlapi/export_test.go +++ b/cmd/ateapi/internal/controlapi/export_test.go @@ -18,11 +18,11 @@ import ( "context" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/scheduling" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" ) @@ -49,19 +49,19 @@ type ConflictingUpdateStore = conflictingUpdateStore type ReleaseWindowWorkflow struct { Name string // State is the actor's state while the worker holds it. - State ateapipb.ActorState + State ateapi.ActorState // Snapshot, when set, is the actor's latest snapshot. - Snapshot func(t *testing.T) *ateapipb.Snapshot + Snapshot func(t *testing.T) *ateapi.Snapshot // Finalize runs the workflow or step that releases the worker and then // records the actor's new state against st. Async and sync suspend reach the // fake atelet newWireCaptureWorkflow serves for the worker // WireTestAssignment names, so the actor must be assigned that worker // and run from the template SeedSuspendTemplate stores. - Finalize func(t *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef, actor *ateapipb.Actor) error + Finalize func(t *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef, actor *ateapi.Actor) error // WantRetry is the code of Finalize retried against the real store. WantRetry codes.Code // WantFinalState is the actor's state once the retry commits. - WantFinalState ateapipb.ActorState + WantFinalState ateapi.ActorState } // ReleaseWindowWorkflows returns async suspend ("pause"), sync suspend, crash, @@ -72,63 +72,63 @@ type ReleaseWindowWorkflow struct { func ReleaseWindowWorkflows() []ReleaseWindowWorkflow { // The workers these tests create carry no labels, so a template // selecting a pool makes any of them ineligible. - ineligibleTemplate := &ateapipb.ActorTemplate{ - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"pool": "other"}}, + ineligibleTemplate := &ateapi.ActorTemplate{ + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"pool": "other"}}, } return []ReleaseWindowWorkflow{ { Name: "pause", - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, - Snapshot: func(t *testing.T) *ateapipb.Snapshot { + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, + Snapshot: func(t *testing.T) *ateapi.Snapshot { // An async suspend in progress: a PENDING durable copy, not yet captured. - return newInProgressSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "local-snap-1") + return newInProgressSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "local-snap-1") }, // The actor is seeded SUSPENDING, so the suspend skips its mark step // and its first actor update is the finalize commit. - Finalize: func(t *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef, _ *ateapipb.Actor) error { + Finalize: func(t *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef, _ *ateapi.Actor) error { w, _ := newWireCaptureWorkflow(t, st) _, err := w.SuspendActor(ctx, actorRef, suspendAsync) return err }, WantRetry: codes.OK, - WantFinalState: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + WantFinalState: ateapi.ActorState_ACTOR_STATE_SUSPENDED, }, { Name: "suspend", - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, - Snapshot: func(t *testing.T) *ateapipb.Snapshot { - return newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "snapshot-1", someActorSnapshotURI(t, testStorageLocation, "team-a", "snapshot-1"), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, + Snapshot: func(t *testing.T) *ateapi.Snapshot { + return newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "snapshot-1", someActorSnapshotURI(t, testStorageLocation, "team-a", "snapshot-1"), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) }, // As for the async suspend, the finalize commit is the first actor update. - Finalize: func(t *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef, _ *ateapipb.Actor) error { + Finalize: func(t *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef, _ *ateapi.Actor) error { w, _ := newWireCaptureWorkflow(t, st) _, err := w.SuspendActor(ctx, actorRef, suspendSync) return err }, WantRetry: codes.OK, - WantFinalState: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + WantFinalState: ateapi.ActorState_ACTOR_STATE_SUSPENDED, }, { Name: "crash", - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - Finalize: func(_ *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef, _ *ateapipb.Actor) error { + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + Finalize: func(_ *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef, _ *ateapi.Actor) error { return crashActor(ctx, st, actorRef, ateattr.OperationResume, "test crash") }, WantRetry: codes.OK, - WantFinalState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + WantFinalState: ateapi.ActorState_ACTOR_STATE_CRASHED, }, { // A resume that finds its worker ineligible releases it, then // crashes the actor. The retry finds the worker no longer hosts // the actor and crashes it. Name: "resume onto an ineligible worker", - State: ateapipb.ActorState_ACTOR_STATE_RESUMING, - Finalize: func(_ *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef, actor *ateapipb.Actor) error { + State: ateapi.ActorState_ACTOR_STATE_RESUMING, + Finalize: func(_ *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef, actor *ateapi.Actor) error { _, err := (&ActorWorkflow{store: st, scheduler: scheduling.New(nil)}).validateAssignedWorker(ctx, actorRef, actor, ineligibleTemplate) return err }, WantRetry: codes.Aborted, - WantFinalState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + WantFinalState: ateapi.ActorState_ACTOR_STATE_CRASHED, }, } } diff --git a/cmd/ateapi/internal/controlapi/functionaltest/access_policy_test.go b/cmd/ateapi/internal/controlapi/functionaltest/access_policy_test.go index 0e73d0a5b4..34726ff8e0 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/access_policy_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/access_policy_test.go @@ -19,8 +19,8 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" @@ -39,13 +39,13 @@ func TestGlobalAccessPolicy_CRUD(t *testing.T) { defer tc.cleanup() ctx := context.Background() - _, err := tc.client.GetGlobalAccessPolicy(ctx, &ateapipb.GetGlobalAccessPolicyRequest{Name: resources.SingletonName}) + _, err := tc.client.GetGlobalAccessPolicy(ctx, &ateapi.GetGlobalAccessPolicyRequest{Name: resources.SingletonName}) wantCode(t, "Get before create", err, codes.NotFound) - created, err := tc.client.CreateGlobalAccessPolicy(ctx, &ateapipb.CreateGlobalAccessPolicyRequest{ - AccessPolicy: &ateapipb.AccessPolicy{ - Metadata: &ateapipb.ResourceMetadata{Name: "default"}, - Bindings: []*ateapipb.Binding{{Role: "owner", Members: []string{"user:alice"}}}, + created, err := tc.client.CreateGlobalAccessPolicy(ctx, &ateapi.CreateGlobalAccessPolicyRequest{ + AccessPolicy: &ateapi.AccessPolicy{ + Metadata: &ateapi.ResourceMetadata{Name: "default"}, + Bindings: []*ateapi.Binding{{Role: "owner", Members: []string{"user:alice"}}}, }, }) if err != nil { @@ -55,15 +55,15 @@ func TestGlobalAccessPolicy_CRUD(t *testing.T) { t.Errorf("created metadata = %v, want name default, a uid and version 1", md) } - _, err = tc.client.CreateGlobalAccessPolicy(ctx, &ateapipb.CreateGlobalAccessPolicyRequest{ - AccessPolicy: &ateapipb.AccessPolicy{ - Metadata: &ateapipb.ResourceMetadata{Name: "default"}, - Bindings: []*ateapipb.Binding{{Role: "owner", Members: []string{"user:alice"}}}, + _, err = tc.client.CreateGlobalAccessPolicy(ctx, &ateapi.CreateGlobalAccessPolicyRequest{ + AccessPolicy: &ateapi.AccessPolicy{ + Metadata: &ateapi.ResourceMetadata{Name: "default"}, + Bindings: []*ateapi.Binding{{Role: "owner", Members: []string{"user:alice"}}}, }, }) wantCode(t, "second Create", err, codes.AlreadyExists) - got, err := tc.client.GetGlobalAccessPolicy(ctx, &ateapipb.GetGlobalAccessPolicyRequest{Name: resources.SingletonName}) + got, err := tc.client.GetGlobalAccessPolicy(ctx, &ateapi.GetGlobalAccessPolicyRequest{Name: resources.SingletonName}) if err != nil { t.Fatalf("Get failed: %v", err) } @@ -71,12 +71,12 @@ func TestGlobalAccessPolicy_CRUD(t *testing.T) { t.Errorf("Get mismatch (-created +got):\n%s", diff) } - update := proto.Clone(created).(*ateapipb.AccessPolicy) - update.Bindings = []*ateapipb.Binding{ + update := proto.Clone(created).(*ateapi.AccessPolicy) + update.Bindings = []*ateapi.Binding{ {Role: "owner", Members: []string{"user:alice"}}, {Role: "viewer", Members: []string{"user:bob"}}, } - updated, err := tc.client.UpdateGlobalAccessPolicy(ctx, &ateapipb.UpdateGlobalAccessPolicyRequest{AccessPolicy: update}) + updated, err := tc.client.UpdateGlobalAccessPolicy(ctx, &ateapi.UpdateGlobalAccessPolicyRequest{AccessPolicy: update}) if err != nil { t.Fatalf("Update failed: %v", err) } @@ -88,7 +88,7 @@ func TestGlobalAccessPolicy_CRUD(t *testing.T) { } // The update above consumed created's version. - _, err = tc.client.UpdateGlobalAccessPolicy(ctx, &ateapipb.UpdateGlobalAccessPolicyRequest{AccessPolicy: update}) + _, err = tc.client.UpdateGlobalAccessPolicy(ctx, &ateapi.UpdateGlobalAccessPolicyRequest{AccessPolicy: update}) wantCode(t, "stale Update", err, codes.Aborted) } @@ -97,29 +97,29 @@ func TestAtespaceAccessPolicy_CRUD(t *testing.T) { defer tc.cleanup() ctx := context.Background() createAtespace(t, tc, "team-a") - ref := &ateapipb.ObjectRef{Name: "team-a"} - policy := &ateapipb.AccessPolicy{ - Metadata: &ateapipb.ResourceMetadata{Name: "default"}, - Bindings: []*ateapipb.Binding{{Role: "editor", Members: []string{"user:alice"}}}, + ref := &ateapi.ObjectRef{Name: "team-a"} + policy := &ateapi.AccessPolicy{ + Metadata: &ateapi.ResourceMetadata{Name: "default"}, + Bindings: []*ateapi.Binding{{Role: "editor", Members: []string{"user:alice"}}}, } - _, err := tc.client.CreateAtespaceAccessPolicy(ctx, &ateapipb.CreateAtespaceAccessPolicyRequest{ - Atespace: &ateapipb.ObjectRef{Name: "missing"}, + _, err := tc.client.CreateAtespaceAccessPolicy(ctx, &ateapi.CreateAtespaceAccessPolicyRequest{ + Atespace: &ateapi.ObjectRef{Name: "missing"}, AccessPolicy: policy, }) wantCode(t, "Create on missing atespace", err, codes.FailedPrecondition) - _, err = tc.client.GetAtespaceAccessPolicy(ctx, &ateapipb.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) + _, err = tc.client.GetAtespaceAccessPolicy(ctx, &ateapi.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) wantCode(t, "Get before create", err, codes.NotFound) - created, err := tc.client.CreateAtespaceAccessPolicy(ctx, &ateapipb.CreateAtespaceAccessPolicyRequest{Atespace: ref, AccessPolicy: policy}) + created, err := tc.client.CreateAtespaceAccessPolicy(ctx, &ateapi.CreateAtespaceAccessPolicyRequest{Atespace: ref, AccessPolicy: policy}) if err != nil { t.Fatalf("Create failed: %v", err) } - _, err = tc.client.CreateAtespaceAccessPolicy(ctx, &ateapipb.CreateAtespaceAccessPolicyRequest{Atespace: ref, AccessPolicy: policy}) + _, err = tc.client.CreateAtespaceAccessPolicy(ctx, &ateapi.CreateAtespaceAccessPolicyRequest{Atespace: ref, AccessPolicy: policy}) wantCode(t, "second Create", err, codes.AlreadyExists) - got, err := tc.client.GetAtespaceAccessPolicy(ctx, &ateapipb.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) + got, err := tc.client.GetAtespaceAccessPolicy(ctx, &ateapi.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) if err != nil { t.Fatalf("Get failed: %v", err) } @@ -127,9 +127,9 @@ func TestAtespaceAccessPolicy_CRUD(t *testing.T) { t.Errorf("Get mismatch (-created +got):\n%s", diff) } - update := proto.Clone(created).(*ateapipb.AccessPolicy) - update.Bindings = []*ateapipb.Binding{{Role: "viewer", Members: []string{"user:bob"}}} - updated, err := tc.client.UpdateAtespaceAccessPolicy(ctx, &ateapipb.UpdateAtespaceAccessPolicyRequest{Atespace: ref, AccessPolicy: update}) + update := proto.Clone(created).(*ateapi.AccessPolicy) + update.Bindings = []*ateapi.Binding{{Role: "viewer", Members: []string{"user:bob"}}} + updated, err := tc.client.UpdateAtespaceAccessPolicy(ctx, &ateapi.UpdateAtespaceAccessPolicyRequest{Atespace: ref, AccessPolicy: update}) if err != nil { t.Fatalf("Update failed: %v", err) } @@ -137,28 +137,28 @@ func TestAtespaceAccessPolicy_CRUD(t *testing.T) { t.Errorf("updated bindings mismatch (-want +got):\n%s", diff) } - _, err = tc.client.DeleteAtespaceAccessPolicy(ctx, &ateapipb.DeleteAtespaceAccessPolicyRequest{ + _, err = tc.client.DeleteAtespaceAccessPolicy(ctx, &ateapi.DeleteAtespaceAccessPolicyRequest{ Atespace: ref, Name: resources.SingletonName, - Options: &ateapipb.DeleteOptions{Version: created.GetMetadata().GetVersion()}, + Options: &ateapi.DeleteOptions{Version: created.GetMetadata().GetVersion()}, }) wantCode(t, "Delete with stale version", err, codes.Aborted) - if _, err := tc.client.DeleteAtespaceAccessPolicy(ctx, &ateapipb.DeleteAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}); err != nil { + if _, err := tc.client.DeleteAtespaceAccessPolicy(ctx, &ateapi.DeleteAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}); err != nil { t.Fatalf("Delete failed: %v", err) } - _, err = tc.client.GetAtespaceAccessPolicy(ctx, &ateapipb.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) + _, err = tc.client.GetAtespaceAccessPolicy(ctx, &ateapi.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) wantCode(t, "Get after delete", err, codes.NotFound) - _, err = tc.client.DeleteAtespaceAccessPolicy(ctx, &ateapipb.DeleteAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) + _, err = tc.client.DeleteAtespaceAccessPolicy(ctx, &ateapi.DeleteAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) wantCode(t, "second Delete", err, codes.NotFound) // Deleting the atespace removes its policy with it. - if _, err := tc.client.CreateAtespaceAccessPolicy(ctx, &ateapipb.CreateAtespaceAccessPolicyRequest{Atespace: ref, AccessPolicy: policy}); err != nil { + if _, err := tc.client.CreateAtespaceAccessPolicy(ctx, &ateapi.CreateAtespaceAccessPolicyRequest{Atespace: ref, AccessPolicy: policy}); err != nil { t.Fatalf("re-Create failed: %v", err) } - if _, err := tc.client.DeleteAtespace(ctx, &ateapipb.DeleteAtespaceRequest{Atespace: ref}); err != nil { + if _, err := tc.client.DeleteAtespace(ctx, &ateapi.DeleteAtespaceRequest{Atespace: ref}); err != nil { t.Fatalf("DeleteAtespace failed: %v", err) } - _, err = tc.client.GetAtespaceAccessPolicy(ctx, &ateapipb.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) + _, err = tc.client.GetAtespaceAccessPolicy(ctx, &ateapi.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) wantCode(t, "Get after DeleteAtespace", err, codes.NotFound) } diff --git a/cmd/ateapi/internal/controlapi/functionaltest/actor_template_test.go b/cmd/ateapi/internal/controlapi/functionaltest/actor_template_test.go index 42f33e9117..e589656a95 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/actor_template_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/actor_template_test.go @@ -28,7 +28,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "github.com/google/go-cmp/cmp" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/testing/protocmp" @@ -40,16 +40,16 @@ func TestActorTemplateCRUD(t *testing.T) { defer tc.cleanup() ctx := context.Background() - created, err := tc.client.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ - ActorTemplate: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "tmpl-a"}, - Containers: []*ateapipb.Container{{Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: "gs://my-bucket/snapshots"}, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 1<<30)}, + created, err := tc.client.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ + ActorTemplate: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "tmpl-a"}, + Containers: []*ateapi.Container{{Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: "gs://my-bucket/snapshots"}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 1<<30)}, // Server-owned status on the request is ignored. - Status: &ateapipb.ActorTemplateStatus{ - GoldenSnapshotStatus: &ateapipb.GoldenSnapshotStatus{ - GoldenTag: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "golden-tag"}, + Status: &ateapi.ActorTemplateStatus{ + GoldenSnapshotStatus: &ateapi.GoldenSnapshotStatus{ + GoldenTag: &ateapi.ObjectRef{Atespace: testAtespace, Name: "golden-tag"}, }, }, }, @@ -57,32 +57,32 @@ func TestActorTemplateCRUD(t *testing.T) { if err != nil { t.Fatalf("CreateActorTemplate failed: %v", err) } - want := &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "tmpl-a", Version: 1}, - Containers: []*ateapipb.Container{{Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}, - SnapshotConfig: &ateapipb.SnapshotConfig{ + want := &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "tmpl-a", Version: 1}, + Containers: []*ateapi.Container{{Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}, + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: "gs://my-bucket/snapshots", - PreferredFidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - GoldenSnapshotConfig: &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, + PreferredFidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + GoldenSnapshotConfig: &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, }, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 1<<30)}, - Status: &ateapipb.ActorTemplateStatus{}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 1<<30)}, + Status: &ateapi.ActorTemplateStatus{}, } if diff := cmp.Diff(want, created, protocmp.Transform(), ignoreUID, ignoreTimestamps); diff != "" { t.Errorf("CreateActorTemplate response mismatch (-want +got):\n%s", diff) } - _, err = tc.client.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ - ActorTemplate: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "tmpl-a"}, - Containers: []*ateapipb.Container{{Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: "gs://my-bucket/snapshots"}, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, + _, err = tc.client.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ + ActorTemplate: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "tmpl-a"}, + Containers: []*ateapi.Container{{Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: "gs://my-bucket/snapshots"}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, }, }) assertGrpcError(t, err, codes.AlreadyExists, "ActorTemplate "+testAtespace+"/tmpl-a already exists") - got, err := tc.client.GetActorTemplate(ctx, &ateapipb.GetActorTemplateRequest{ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}}) + got, err := tc.client.GetActorTemplate(ctx, &ateapi.GetActorTemplateRequest{ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}}) if err != nil { t.Fatalf("GetActorTemplate failed: %v", err) } @@ -90,7 +90,7 @@ func TestActorTemplateCRUD(t *testing.T) { t.Errorf("GetActorTemplate response mismatch (-created +got):\n%s", diff) } - list, err := tc.client.ListActorTemplates(ctx, &ateapipb.ListActorTemplatesRequest{}) + list, err := tc.client.ListActorTemplates(ctx, &ateapi.ListActorTemplatesRequest{}) if err != nil { t.Fatalf("ListActorTemplates failed: %v", err) } @@ -100,14 +100,14 @@ func TestActorTemplateCRUD(t *testing.T) { // The atespace filter scopes the listing: a match returns the template, a // different atespace returns nothing. - list, err = tc.client.ListActorTemplates(ctx, &ateapipb.ListActorTemplatesRequest{Atespace: testAtespace}) + list, err = tc.client.ListActorTemplates(ctx, &ateapi.ListActorTemplatesRequest{Atespace: testAtespace}) if err != nil { t.Fatalf("ListActorTemplates(atespace) failed: %v", err) } if len(list.GetActorTemplates()) != 1 { t.Errorf("ListActorTemplates(atespace=%s) = %v, want [tmpl-a]", testAtespace, list.GetActorTemplates()) } - list, err = tc.client.ListActorTemplates(ctx, &ateapipb.ListActorTemplatesRequest{Atespace: "other-atespace"}) + list, err = tc.client.ListActorTemplates(ctx, &ateapi.ListActorTemplatesRequest{Atespace: "other-atespace"}) if err != nil { t.Fatalf("ListActorTemplates(other atespace) failed: %v", err) } @@ -115,7 +115,7 @@ func TestActorTemplateCRUD(t *testing.T) { t.Errorf("ListActorTemplates(atespace=other-atespace) = %v, want []", list.GetActorTemplates()) } - deleted, err := tc.client.DeleteActorTemplate(ctx, &ateapipb.DeleteActorTemplateRequest{ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}}) + deleted, err := tc.client.DeleteActorTemplate(ctx, &ateapi.DeleteActorTemplateRequest{ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}}) if err != nil { t.Fatalf("DeleteActorTemplate failed: %v", err) } @@ -125,9 +125,9 @@ func TestActorTemplateCRUD(t *testing.T) { if deleted.GetMetadata().GetDeleteTime() == nil { t.Errorf("the deleted template carries no delete_time") } - _, err = tc.client.GetActorTemplate(ctx, &ateapipb.GetActorTemplateRequest{ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}}) + _, err = tc.client.GetActorTemplate(ctx, &ateapi.GetActorTemplateRequest{ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}}) assertGrpcError(t, err, codes.NotFound, "ActorTemplate "+testAtespace+"/tmpl-a not found") - _, err = tc.client.DeleteActorTemplate(ctx, &ateapipb.DeleteActorTemplateRequest{ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}}) + _, err = tc.client.DeleteActorTemplate(ctx, &ateapi.DeleteActorTemplateRequest{ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}}) assertGrpcError(t, err, codes.NotFound, "ActorTemplate "+testAtespace+"/tmpl-a not found") } @@ -138,27 +138,27 @@ func TestGoldenTagLifecycle(t *testing.T) { ctx, cancel := context.WithCancel(t.Context()) defer cancel() createWorkerPool(t, tc, ns, "pool1", map[string]string{poolLabelKey: ns}) - tmpl := createTemplateWithSelector(t, tc, "golden-template", &ateapipb.Selector{MatchLabels: map[string]string{poolLabelKey: ns}}) + tmpl := createTemplateWithSelector(t, tc, "golden-template", &ateapi.Selector{MatchLabels: map[string]string{poolLabelKey: ns}}) workerName := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") templateRef := resources.ActorTemplateRefFromActorTemplate(tmpl) // Created before readiness: a later golden tag must not change its source. - early, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "early"}, ActorTemplate: templateRef.ToObjectRef(), + early, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "early"}, ActorTemplate: templateRef.ToObjectRef(), }}) if err != nil { t.Fatal(err) } controlapi.NewActorTemplateReconciler(tc.persistence, tc.service, 7*time.Second).Start(ctx) - var goldenRef *ateapipb.ObjectRef + var goldenRef *ateapi.ObjectRef err = wait.PollUntilContextTimeout(ctx, 50*time.Millisecond, 30*time.Second, true, func(ctx context.Context) (bool, error) { - current, err := tc.client.GetActorTemplate(ctx, &ateapipb.GetActorTemplateRequest{ActorTemplate: templateRef.ToObjectRef()}) + current, err := tc.client.GetActorTemplate(ctx, &ateapi.GetActorTemplateRequest{ActorTemplate: templateRef.ToObjectRef()}) goldenRef = current.GetStatus().GetGoldenSnapshotStatus().GetGoldenTag() return goldenRef != nil, err }) if err != nil { t.Fatalf("waiting for golden tag: %v", err) } - golden, err := tc.client.GetTag(ctx, &ateapipb.GetTagRequest{Tag: goldenRef}) + golden, err := tc.client.GetTag(ctx, &ateapi.GetTagRequest{Tag: goldenRef}) if err != nil { t.Fatal(err) } @@ -171,12 +171,12 @@ func TestGoldenTagLifecycle(t *testing.T) { t.Fatalf("golden snapshot %q is not under the golden tag's own prefix", uri) } assertSnapshotPresent(t, tc, uri) - _, err = tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: goldenRef}) + _, err = tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: goldenRef}) if status.Code(err) != codes.NotFound { t.Fatalf("golden actor was not deleted: %v", err) } - late, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "late"}, ActorTemplate: templateRef.ToObjectRef(), + late, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "late"}, ActorTemplate: templateRef.ToObjectRef(), }}) if err != nil { t.Fatal(err) @@ -188,39 +188,39 @@ func TestGoldenTagLifecycle(t *testing.T) { tc.fakeAtelet.Lock.Lock() tc.fakeAtelet.RunCalled = false tc.fakeAtelet.Lock.Unlock() - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: resources.ActorRefFromActor(early).ToObjectRef()}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: resources.ActorRefFromActor(early).ToObjectRef()}); err != nil { t.Fatal(err) } if !tc.fakeAtelet.RunCalled { t.Fatal("actor created before golden readiness did not cold boot") } - if _, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: resources.ActorRefFromActor(early).ToObjectRef()}); err != nil { + if _, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: resources.ActorRefFromActor(early).ToObjectRef()}); err != nil { t.Fatal(err) } waitForWorkerAvailable(t, tc, workerName) - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: resources.ActorRefFromActor(late).ToObjectRef()}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: resources.ActorRefFromActor(late).ToObjectRef()}); err != nil { t.Fatal(err) } if !tc.fakeAtelet.RestoreCalled { t.Fatal("actor did not restore golden tag") } - if _, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ + if _, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{ Actor: resources.ActorRefFromActor(late).ToObjectRef(), - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }); err != nil { t.Fatal(err) } assertSnapshotPresent(t, tc, uri) - for _, actor := range []*ateapipb.Actor{early, late} { - if _, err := tc.client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: resources.ActorRefFromActor(actor).ToObjectRef()}); err != nil { + for _, actor := range []*ateapi.Actor{early, late} { + if _, err := tc.client.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: resources.ActorRefFromActor(actor).ToObjectRef()}); err != nil { t.Fatal(err) } } - if _, err := tc.client.DeleteActorTemplate(ctx, &ateapipb.DeleteActorTemplateRequest{ActorTemplate: templateRef.ToObjectRef()}); err != nil { + if _, err := tc.client.DeleteActorTemplate(ctx, &ateapi.DeleteActorTemplateRequest{ActorTemplate: templateRef.ToObjectRef()}); err != nil { t.Fatal(err) } assertSnapshotCollected(t, tc, uri) - _, err = tc.client.GetTag(ctx, &ateapipb.GetTagRequest{Tag: goldenRef}) + _, err = tc.client.GetTag(ctx, &ateapi.GetTagRequest{Tag: goldenRef}) if status.Code(err) != codes.NotFound { t.Fatalf("golden tag was not deleted: %v", err) } @@ -233,30 +233,30 @@ func TestActorLifecycleWithoutGoldenSnapshot(t *testing.T) { ctx, cancel := context.WithCancel(t.Context()) defer cancel() createWorkerPool(t, tc, ns, "pool1", map[string]string{poolLabelKey: ns}) - tmpl, err := tc.client.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ActorTemplate: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "no-golden"}, - SnapshotConfig: &ateapipb.SnapshotConfig{ + tmpl, err := tc.client.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ActorTemplate: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "no-golden"}, + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: testStorageLocation, - GoldenSnapshotConfig: &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED}, + GoldenSnapshotConfig: &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED}, }, - Containers: []*ateapipb.Container{{Name: "main", Image: "main@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", Command: []string{"/main"}}}, - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{poolLabelKey: ns}}, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, + Containers: []*ateapi.Container{{Name: "main", Image: "main@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", Command: []string{"/main"}}}, + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{poolLabelKey: ns}}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, }}) if err != nil { t.Fatal(err) } - if tmpl.GetSnapshotConfig().GetGoldenSnapshotConfig().GetMode() != ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED { + if tmpl.GetSnapshotConfig().GetGoldenSnapshotConfig().GetMode() != ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED { t.Fatal("CreateActorTemplate did not preserve the golden snapshot opt-out") } workerName := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") - controlTemplate := createTemplateWithSelector(t, tc, "golden-control", &ateapipb.Selector{MatchLabels: map[string]string{poolLabelKey: ns}}) - goldenRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: tmpl.GetMetadata().GetUid()} + controlTemplate := createTemplateWithSelector(t, tc, "golden-control", &ateapi.Selector{MatchLabels: map[string]string{poolLabelKey: ns}}) + goldenRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: tmpl.GetMetadata().GetUid()} assertNoGolden := func(ctx context.Context) error { - if _, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: goldenRef}); status.Code(err) != codes.NotFound { + if _, err := tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: goldenRef}); status.Code(err) != codes.NotFound { return fmt.Errorf("disabled template's golden actor: got %v, want NotFound", err) } - if _, err := tc.client.GetTag(ctx, &ateapipb.GetTagRequest{Tag: goldenRef}); status.Code(err) != codes.NotFound { + if _, err := tc.client.GetTag(ctx, &ateapi.GetTagRequest{Tag: goldenRef}); status.Code(err) != codes.NotFound { return fmt.Errorf("disabled template's golden tag: got %v, want NotFound", err) } return nil @@ -267,7 +267,7 @@ func TestActorLifecycleWithoutGoldenSnapshot(t *testing.T) { if err := assertNoGolden(ctx); err != nil { return false, err } - current, err := tc.client.GetActorTemplate(ctx, &ateapipb.GetActorTemplateRequest{ + current, err := tc.client.GetActorTemplate(ctx, &ateapi.GetActorTemplateRequest{ ActorTemplate: resources.ActorTemplateRefFromActorTemplate(controlTemplate).ToObjectRef(), }) return current.GetStatus().GetGoldenSnapshotStatus().GetGoldenTag() != nil, err @@ -276,8 +276,8 @@ func TestActorLifecycleWithoutGoldenSnapshot(t *testing.T) { t.Fatalf("waiting for enabled template's golden tag: %v", err) } waitForWorkerAvailable(t, tc, workerName) - actor, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "actor"}, + actor, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "actor"}, ActorTemplate: resources.ActorTemplateRefFromActorTemplate(tmpl).ToObjectRef(), }}) if err != nil { @@ -290,7 +290,7 @@ func TestActorLifecycleWithoutGoldenSnapshot(t *testing.T) { tc.fakeAtelet.Lock.Lock() tc.fakeAtelet.RunCalled, tc.fakeAtelet.RestoreCalled = false, false tc.fakeAtelet.Lock.Unlock() - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatal(err) } tc.fakeAtelet.Lock.Lock() @@ -299,7 +299,7 @@ func TestActorLifecycleWithoutGoldenSnapshot(t *testing.T) { if !ran || restored { t.Fatal("first resume did not cold boot") } - suspended, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: ref, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + suspended, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatal(err) } @@ -309,7 +309,7 @@ func TestActorLifecycleWithoutGoldenSnapshot(t *testing.T) { } assertSnapshotPresent(t, tc, snapshotURI) waitForWorkerAvailable(t, tc, workerName) - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatal(err) } if got := tc.fakeAtelet.lastRestoreRequest().GetSnapshot().GetObject().GetSnapshotUri(); got != snapshotURI { @@ -318,13 +318,13 @@ func TestActorLifecycleWithoutGoldenSnapshot(t *testing.T) { if err := assertNoGolden(ctx); err != nil { t.Fatal(err) } - if _, err := tc.client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}); err != nil { t.Fatal(err) } - if _, err := tc.client.DeleteActorTemplate(ctx, &ateapipb.DeleteActorTemplateRequest{ActorTemplate: resources.ActorTemplateRefFromActorTemplate(tmpl).ToObjectRef()}); err != nil { + if _, err := tc.client.DeleteActorTemplate(ctx, &ateapi.DeleteActorTemplateRequest{ActorTemplate: resources.ActorTemplateRefFromActorTemplate(tmpl).ToObjectRef()}); err != nil { t.Fatal(err) } - if _, err := tc.client.DeleteActorTemplate(ctx, &ateapipb.DeleteActorTemplateRequest{ActorTemplate: resources.ActorTemplateRefFromActorTemplate(controlTemplate).ToObjectRef()}); err != nil { + if _, err := tc.client.DeleteActorTemplate(ctx, &ateapi.DeleteActorTemplateRequest{ActorTemplate: resources.ActorTemplateRefFromActorTemplate(controlTemplate).ToObjectRef()}); err != nil { t.Fatal(err) } } @@ -335,7 +335,7 @@ func TestListActorTemplates_InvalidPageToken(t *testing.T) { defer tc.cleanup() _, err := tc.client.ListActorTemplates(context.Background(), - &ateapipb.ListActorTemplatesRequest{Options: &ateapipb.ListOptions{PageToken: "%%%"}}) + &ateapi.ListActorTemplatesRequest{Options: &ateapi.ListOptions{PageToken: "%%%"}}) assertGrpcError(t, err, codes.InvalidArgument, "invalid page_token") } @@ -347,33 +347,33 @@ func TestDeleteActorTemplate_Preconditions(t *testing.T) { tmpl := createTemplateWithSelector(t, tc, "tmpl1", nil) templateRef := resources.ActorTemplateRefFromActorTemplate(tmpl) ref := templateRef.ToObjectRef() - del := func(opts *ateapipb.DeleteOptions) error { - _, err := tc.client.DeleteActorTemplate(ctx, &ateapipb.DeleteActorTemplateRequest{ActorTemplate: ref, Options: opts}) + del := func(opts *ateapi.DeleteOptions) error { + _, err := tc.client.DeleteActorTemplate(ctx, &ateapi.DeleteActorTemplateRequest{ActorTemplate: ref, Options: opts}) return err } uid, version := tmpl.GetMetadata().GetUid(), tmpl.GetMetadata().GetVersion() - assertGrpcError(t, del(&ateapipb.DeleteOptions{Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: uid, Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: foreignUID}), codes.Aborted, "ActorTemplate "+templateRef.String()+" does not have uid "+foreignUID) - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: foreignUID, Version: version}), codes.Aborted, "ActorTemplate "+templateRef.String()+" does not have uid "+foreignUID) - if _, err := tc.client.GetActorTemplate(ctx, &ateapipb.GetActorTemplateRequest{ActorTemplate: ref}); err != nil { + assertGrpcError(t, del(&ateapi.DeleteOptions{Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: uid, Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: foreignUID}), codes.Aborted, "ActorTemplate "+templateRef.String()+" does not have uid "+foreignUID) + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: foreignUID, Version: version}), codes.Aborted, "ActorTemplate "+templateRef.String()+" does not have uid "+foreignUID) + if _, err := tc.client.GetActorTemplate(ctx, &ateapi.GetActorTemplateRequest{ActorTemplate: ref}); err != nil { t.Fatalf("a refused delete removed the template: %v", err) } - if err := del(&ateapipb.DeleteOptions{Version: version}); err != nil { + if err := del(&ateapi.DeleteOptions{Version: version}); err != nil { t.Fatalf("DeleteActorTemplate with the matching version: %v", err) } tmpl = createTemplateWithSelector(t, tc, "tmpl1", nil) - if err := del(&ateapipb.DeleteOptions{Uid: tmpl.GetMetadata().GetUid()}); err != nil { + if err := del(&ateapi.DeleteOptions{Uid: tmpl.GetMetadata().GetUid()}); err != nil { t.Fatalf("DeleteActorTemplate with the matching uid: %v", err) } tmpl = createTemplateWithSelector(t, tc, "tmpl1", nil) - if err := del(&ateapipb.DeleteOptions{Uid: tmpl.GetMetadata().GetUid(), Version: tmpl.GetMetadata().GetVersion()}); err != nil { + if err := del(&ateapi.DeleteOptions{Uid: tmpl.GetMetadata().GetUid(), Version: tmpl.GetMetadata().GetVersion()}); err != nil { t.Fatalf("DeleteActorTemplate with both guards: %v", err) } - _, err := tc.client.GetActorTemplate(ctx, &ateapipb.GetActorTemplateRequest{ActorTemplate: ref}) + _, err := tc.client.GetActorTemplate(ctx, &ateapi.GetActorTemplateRequest{ActorTemplate: ref}) assertGrpcError(t, err, codes.NotFound, "ActorTemplate "+templateRef.String()+" not found") } @@ -401,20 +401,20 @@ func TestCreateActorTemplate_ExternalVolumesPreview(t *testing.T) { if tt.optIn { ctx = metadata.AppendToOutgoingContext(ctx, preview.Header, "true") } - _, err := tc.client.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ - ActorTemplate: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: fmt.Sprintf("tmpl-ext-%d", i)}, - Containers: []*ateapipb.Container{{ + _, err := tc.client.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ + ActorTemplate: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: fmt.Sprintf("tmpl-ext-%d", i)}, + Containers: []*ateapi.Container{{ Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - VolumeMounts: []*ateapipb.VolumeMount{{Name: "data", MountPath: "/data"}}, + VolumeMounts: []*ateapi.VolumeMount{{Name: "data", MountPath: "/data"}}, }}, - Volumes: []*ateapipb.Volume{{ + Volumes: []*ateapi.Volume{{ Name: "data", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{StorageClassName: "standard", CapacityBytes: 1 << 30}}, + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "standard", CapacityBytes: 1 << 30}}, }}, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 1<<30)}, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: "gs://my-bucket/snapshots"}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 1<<30)}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: "gs://my-bucket/snapshots"}, }, }) if status.Code(err) != tt.wantCode { @@ -455,15 +455,15 @@ func TestCreateActorTemplate_PerTemplateSnapshotLocationPreview(t *testing.T) { if tt.optIn { ctx = metadata.AppendToOutgoingContext(ctx, preview.Header, "true") } - _, err := tc.client.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ - ActorTemplate: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: fmt.Sprintf("tmpl-loc-%d", i)}, - Containers: []*ateapipb.Container{{ + _, err := tc.client.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ + ActorTemplate: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: fmt.Sprintf("tmpl-loc-%d", i)}, + Containers: []*ateapi.Container{{ Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", }}, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 1<<30)}, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: tt.location}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 1<<30)}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: tt.location}, }, }) if status.Code(err) != tt.wantCode { @@ -498,26 +498,26 @@ func TestCreateActorTemplate_GoldenEgressPolicyPreview(t *testing.T) { if tt.optIn { client = tc.client } - tmpl := proto.Clone(base).(*ateapipb.ActorTemplate) - tmpl.Metadata = &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: fmt.Sprintf("golden-egress-%d", i)} + tmpl := proto.Clone(base).(*ateapi.ActorTemplate) + tmpl.Metadata = &ateapi.ResourceMetadata{Atespace: testAtespace, Name: fmt.Sprintf("golden-egress-%d", i)} tmpl.Status = nil - tmpl.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{Rules: functionalEgressPolicy().Rules} + tmpl.GoldenEgressPolicy = &ateapi.EgressPolicyTemplate{Rules: functionalEgressPolicy().Rules} if tt.snapshotsDisabled { - tmpl.SnapshotConfig.GoldenSnapshotConfig = &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED} + tmpl.SnapshotConfig.GoldenSnapshotConfig = &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED} } ref := resources.ActorTemplateRefFromActorTemplate(tmpl).ToObjectRef() - created, err := client.CreateActorTemplate(t.Context(), &ateapipb.CreateActorTemplateRequest{ActorTemplate: tmpl}) + created, err := client.CreateActorTemplate(t.Context(), &ateapi.CreateActorTemplateRequest{ActorTemplate: tmpl}) if tt.wantCode != codes.OK { assertGrpcErrorRegex(t, err, tt.wantCode, "golden_egress_policy") - _, err = client.GetActorTemplate(t.Context(), &ateapipb.GetActorTemplateRequest{ActorTemplate: ref}) + _, err = client.GetActorTemplate(t.Context(), &ateapi.GetActorTemplateRequest{ActorTemplate: ref}) assertGrpcErrorRegex(t, err, codes.NotFound, "not found") return } if err != nil { t.Fatalf("CreateActorTemplate: %v", err) } - wantPolicy := &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{{ - Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{80}}}, + wantPolicy := &ateapi.EgressPolicyTemplate{Rules: []*ateapi.EgressRule{{ + Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{80}}}, }}} if diff := cmp.Diff(wantPolicy, created.GetGoldenEgressPolicy(), protocmp.Transform()); diff != "" { t.Fatalf("golden policy (-want +got):\n%s", diff) @@ -525,14 +525,14 @@ func TestCreateActorTemplate_GoldenEgressPolicyPreview(t *testing.T) { // Opting out or disabling the gate must not strand existing templates. preview.InitForTest(t) - got, err := tc.noOptInClient.GetActorTemplate(t.Context(), &ateapipb.GetActorTemplateRequest{ActorTemplate: ref}) + got, err := tc.noOptInClient.GetActorTemplate(t.Context(), &ateapi.GetActorTemplateRequest{ActorTemplate: ref}) if err != nil { t.Fatalf("GetActorTemplate with gate disabled: %v", err) } if diff := cmp.Diff(created, got, protocmp.Transform()); diff != "" { t.Fatalf("template changed with gate disabled (-want +got):\n%s", diff) } - if _, err := tc.noOptInClient.DeleteActorTemplate(t.Context(), &ateapipb.DeleteActorTemplateRequest{ActorTemplate: ref}); err != nil { + if _, err := tc.noOptInClient.DeleteActorTemplate(t.Context(), &ateapi.DeleteActorTemplateRequest{ActorTemplate: ref}); err != nil { t.Fatalf("DeleteActorTemplate with gate disabled: %v", err) } }) diff --git a/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go b/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go index 0ae62e7953..dae1b1eae2 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go @@ -31,6 +31,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/s3/types" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/actoridjwt" "go.ate.dev/substrate/internal/apierror" @@ -41,7 +42,6 @@ import ( "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/volume" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/metric/metricdata" "google.golang.org/grpc/codes" @@ -66,30 +66,30 @@ func TestCreateActor_Success(t *testing.T) { tmpl := createTemplate(t, tc, ns) - createResp, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ + createResp, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: testAtespace, Name: "id1", }, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "free"}}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "free"}}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - want := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "id1", Atespace: testAtespace, Version: 1}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + want := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "id1", Atespace: testAtespace, Version: 1}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)), + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)), }, }, - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "free"}}, + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "free"}}, } // The diff below ignores the server-assigned uid/timestamps (non-deterministic), @@ -121,16 +121,16 @@ func TestCreateActor_WithExternalVolumes(t *testing.T) { tc := setupPreviewTest(t, ns) defer tc.cleanup() - volumes := []*ateapipb.Volume{ + volumes := []*ateapi.Volume{ { Name: "ext-vol-1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }, } - mounts := []*ateapipb.VolumeMount{ + mounts := []*ateapi.VolumeMount{ { Name: "ext-vol-1", MountPath: "/data", @@ -138,10 +138,10 @@ func TestCreateActor_WithExternalVolumes(t *testing.T) { } createTemplateWithVolumes(t, tc, ns, volumes, mounts) - createResp, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "vol-actor-1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + createResp, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "vol-actor-1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }) if err != nil { @@ -160,8 +160,8 @@ func TestCreateActor_WithExternalVolumes(t *testing.T) { } // Verify GetActor returns the same external volume state - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "vol-actor-1"}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "vol-actor-1"}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) @@ -185,16 +185,16 @@ func TestCreateActor_ExternalVolumesWithoutOptIn(t *testing.T) { defer tc.cleanup() createTemplateWithVolumes(t, tc, ns, - []*ateapipb.Volume{{ + []*ateapi.Volume{{ Name: "ext-vol-1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{StorageClassName: "standard", CapacityBytes: 10 << 30}}, + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "standard", CapacityBytes: 10 << 30}}, }}, - []*ateapipb.VolumeMount{{Name: "ext-vol-1", MountPath: "/data"}}) + []*ateapi.VolumeMount{{Name: "ext-vol-1", MountPath: "/data"}}) - _, err := tc.noOptInClient.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "vol-actor-1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.noOptInClient.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "vol-actor-1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }) if status.Code(err) != codes.InvalidArgument { @@ -217,36 +217,36 @@ func TestActorLifecycle_ExternalVolumesWithoutOptIn(t *testing.T) { defer tc.cleanup() createTemplateWithVolumes(t, tc, ns, - []*ateapipb.Volume{{ + []*ateapi.Volume{{ Name: "data-vol", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{StorageClassName: "fast", CapacityBytes: 20 << 30}}, + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "fast", CapacityBytes: 20 << 30}}, }}, - []*ateapipb.VolumeMount{{Name: "data-vol", MountPath: "/mnt/data"}}) + []*ateapi.VolumeMount{{Name: "data-vol", MountPath: "/mnt/data"}}) createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-vol-no-opt-in"} - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: actorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-vol-no-opt-in"} + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: actorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }); err != nil { t.Fatalf("CreateActor failed: %v", err) } - _, err := tc.noOptInClient.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: actorRef}) + _, err := tc.noOptInClient.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("ResumeActor failed: %v", err) } - if _, err := tc.noOptInClient.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.noOptInClient.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: actorRef}); err != nil { t.Fatalf("SuspendActor failed: %v", err) } - if _, err := tc.noOptInClient.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.noOptInClient.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{Actor: actorRef}); err != nil { t.Fatalf("DeleteActor failed: %v", err) } - _, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: actorRef}) + _, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: actorRef}) if status.Code(err) != codes.NotFound { t.Errorf("GetActor after delete err = %v, want NotFound", err) } @@ -258,9 +258,9 @@ func TestCreateActor_TemplateNotFound(t *testing.T) { tc := setupTest(t, ns) defer tc.cleanup() - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "non-existent"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "non-existent"}, }}) if got := status.Code(err); got != codes.FailedPrecondition { t.Fatalf("CreateActor with a missing template = %v, want FailedPrecondition (err: %v)", got, err) @@ -276,38 +276,38 @@ func TestCreateActor_SubstrateTemplateRef(t *testing.T) { defer tc.cleanup() ctx := context.Background() - if _, err := tc.client.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ - ActorTemplate: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "sub-tmpl"}, - Containers: []*ateapipb.Container{{Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: "gs://my-bucket/snapshots"}, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, + if _, err := tc.client.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ + ActorTemplate: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "sub-tmpl"}, + Containers: []*ateapi.Container{{Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: "gs://my-bucket/snapshots"}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, }, }); err != nil { t.Fatalf("CreateActorTemplate failed: %v", err) } - created, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "ref-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "sub-tmpl"}, + created, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "ref-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "sub-tmpl"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - want := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "ref-actor", Version: 1}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + want := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "ref-actor", Version: 1}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, } if diff := cmp.Diff(want, created, protocmp.Transform(), ignoreUID, ignoreTimestamps); diff != "" { t.Errorf("CreateActor response mismatch (-want +got):\n%s", diff) } // A reference to a template that does not exist fails. - _, err = tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "ref-actor-2"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "absent"}, + _, err = tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "ref-actor-2"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "absent"}, }}) if got := status.Code(err); got != codes.FailedPrecondition { t.Fatalf("CreateActor with an absent template ref = %v, want FailedPrecondition (err: %v)", got, err) @@ -322,17 +322,17 @@ func TestCreateActor_Duplicate(t *testing.T) { createTemplate(t, tc, ns) - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("first CreateActor failed: %v", err) } - _, err = tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err = tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) assertGrpcError(t, err, codes.AlreadyExists, "Actor id1 already exists") } @@ -346,10 +346,10 @@ func TestCreateActor_StampsFullSpanIdentity(t *testing.T) { createTemplate(t, tc, ns) attrs := recordRootSpanAttrs(t, func(ctx context.Context) { - if _, err := tc.service.CreateActor(ctx, &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.service.CreateActor(ctx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }); err != nil { t.Fatalf("CreateActor: %v", err) @@ -377,16 +377,16 @@ func TestCreateActor_RejectsDifferentTemplateForDataSnapshot(t *testing.T) { tmpl := createTemplate(t, tc, ns) createTemplateWithSelector(t, tc, "tmpl2", nil) - seedTag(t, tc, "data-source", "data-snapshot", func(tag *ateapipb.Tag) { - tag.Status.Snapshot.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES + seedTag(t, tc, "data-source", "data-snapshot", func(tag *ateapi.Tag) { + tag.Status.Snapshot.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES tag.Status.ActorTemplateUid = tmpl.GetMetadata().GetUid() }) - _, err := tc.service.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "clone"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl2"}, - SourceTag: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "data-snapshot"}, + _, err := tc.service.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "clone"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl2"}, + SourceTag: &ateapi.ObjectRef{Atespace: testAtespace, Name: "data-snapshot"}, }, }) if apierror.Code(err) != codes.FailedPrecondition { @@ -400,34 +400,34 @@ func TestCreateActor_RejectsSnapshotWithExternalVolumes(t *testing.T) { ns := namespaceForTest("ns-snapshot-external-volume") tc := setupPreviewTest(t, ns) defer tc.cleanup() - template, err := tc.client.CreateActorTemplate(context.Background(), &ateapipb.CreateActorTemplateRequest{ - ActorTemplate: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "tmpl1"}, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: "gs://snapshots"}, - Containers: []*ateapipb.Container{{ - Name: "main", Image: "main@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", VolumeMounts: []*ateapipb.VolumeMount{{Name: "data", MountPath: "/data"}}, + template, err := tc.client.CreateActorTemplate(context.Background(), &ateapi.CreateActorTemplateRequest{ + ActorTemplate: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "tmpl1"}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: "gs://snapshots"}, + Containers: []*ateapi.Container{{ + Name: "main", Image: "main@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", VolumeMounts: []*ateapi.VolumeMount{{Name: "data", MountPath: "/data"}}, }}, - Volumes: []*ateapipb.Volume{{ + Volumes: []*ateapi.Volume{{ Name: "data", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ CapacityBytes: 1 << 30, StorageClassName: "standard", }}, }}, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, }, }) if err != nil { t.Fatalf("Create ActorTemplate: %v", err) } - seedTag(t, tc, "external-volume-source", "external-volume-snapshot", func(tag *ateapipb.Tag) { + seedTag(t, tc, "external-volume-source", "external-volume-snapshot", func(tag *ateapi.Tag) { tag.Status.ActorTemplateUid = template.GetMetadata().GetUid() }) - tagRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "external-volume-snapshot"} + tagRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "external-volume-snapshot"} - _, err = tc.service.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "clone"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err = tc.service.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "clone"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, SourceTag: tagRef, }, }) @@ -448,16 +448,16 @@ func TestCreateActor_PendingTag(t *testing.T) { // Simulates a tag creation that failed while writing the snapshot to // external storage. - pending := seedTag(t, tc, "pending-source", "pending", func(tag *ateapipb.Tag) { - tag.Status.Snapshot.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + pending := seedTag(t, tc, "pending-source", "pending", func(tag *ateapi.Tag) { + tag.Status.Snapshot.DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING tag.Status.ActorTemplateUid = tmpl.GetMetadata().GetUid() }) - tagRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pending"} + tagRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "pending"} // seeding an actor from the pending tag must fail. - _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "clone"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "clone"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, SourceTag: tagRef, }}) assertGrpcError(t, err, codes.FailedPrecondition, "source Tag is still being created or failed creation") @@ -466,17 +466,17 @@ func TestCreateActor_PendingTag(t *testing.T) { snapshotURI := pending.GetStatus().GetSnapshot().GetDurableSnapshot().GetObject().GetSnapshotUri() if _, err := tc.persistence.UpdateTag(ctx, resources.TagRefFromTag(pending), store.PreconditionFrom(pending), - func(toUpdate *ateapipb.Tag) error { - toUpdate.Status.Snapshot.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + func(toUpdate *ateapi.Tag) error { + toUpdate.Status.Snapshot.DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED return nil }); err != nil { t.Fatalf("finalizing the tag: %v", err) } // The tag was finalized. Now, actor creation should succeed. - clone, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "clone"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + clone, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "clone"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, SourceTag: tagRef, }}) if err != nil { @@ -499,16 +499,16 @@ func TestGetActor_Found(t *testing.T) { name := "id1" - createResp, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + createResp, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) @@ -530,8 +530,8 @@ func TestGetActor_NotFound(t *testing.T) { tc := setupTest(t, ns) defer tc.cleanup() - _, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "non-existent"}, + _, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "non-existent"}, }) assertGrpcError(t, err, codes.NotFound, "Actor test-atespace/non-existent not found") } @@ -549,22 +549,22 @@ func TestListActors(t *testing.T) { createTemplate(t, tc, ns) - resp1, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + resp1, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor 1 failed: %v", err) } - resp2, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id2"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + resp2, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id2"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor 2 failed: %v", err) } - listResp, err := tc.client.ListActors(context.Background(), &ateapipb.ListActorsRequest{Atespace: testAtespace}) + listResp, err := tc.client.ListActors(context.Background(), &ateapi.ListActorsRequest{Atespace: testAtespace}) if err != nil { t.Fatalf("ListActors failed: %v", err) } @@ -573,14 +573,14 @@ func TestListActors(t *testing.T) { t.Fatalf("expected 2 actors, got %d", len(listResp.Actors)) } - want := []*ateapipb.Actor{ + want := []*ateapi.Actor{ resp1, resp2, } opts := []cmp.Option{ protocmp.Transform(), - cmpopts.SortSlices(func(a, b *ateapipb.Actor) bool { + cmpopts.SortSlices(func(a, b *ateapi.Actor) bool { return a.GetMetadata().GetName() < b.GetMetadata().GetName() }), } @@ -602,10 +602,10 @@ func TestListActors_ByAtespace(t *testing.T) { createAtespace(t, tc, "team-a") createAtespace(t, tc, "team-b") - create := func(atespace, name string) *ateapipb.Actor { - resp, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + create := func(atespace, name string) *ateapi.Actor { + resp, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor(%s, atespace=%q) failed: %v", name, atespace, err) @@ -618,32 +618,32 @@ func TestListActors_ByAtespace(t *testing.T) { sortByID := []cmp.Option{ protocmp.Transform(), - cmpopts.SortSlices(func(a, b *ateapipb.Actor) bool { return a.GetMetadata().GetName() < b.GetMetadata().GetName() }), + cmpopts.SortSlices(func(a, b *ateapi.Actor) bool { return a.GetMetadata().GetName() < b.GetMetadata().GetName() }), } // List scoped to team-a returns only its actors. - listA, err := tc.client.ListActors(context.Background(), &ateapipb.ListActorsRequest{Atespace: "team-a"}) + listA, err := tc.client.ListActors(context.Background(), &ateapi.ListActorsRequest{Atespace: "team-a"}) if err != nil { t.Fatalf("ListActors(team-a) failed: %v", err) } - if diff := cmp.Diff([]*ateapipb.Actor{a1, a2}, listA.GetActors(), sortByID...); diff != "" { + if diff := cmp.Diff([]*ateapi.Actor{a1, a2}, listA.GetActors(), sortByID...); diff != "" { t.Errorf("ListActors(team-a) mismatch (-want +got):\n%s", diff) } // List scoped to team-b returns only its actor. - listB, err := tc.client.ListActors(context.Background(), &ateapipb.ListActorsRequest{Atespace: "team-b"}) + listB, err := tc.client.ListActors(context.Background(), &ateapi.ListActorsRequest{Atespace: "team-b"}) if err != nil { t.Fatalf("ListActors(team-b) failed: %v", err) } - if diff := cmp.Diff([]*ateapipb.Actor{b1}, listB.GetActors(), sortByID...); diff != "" { + if diff := cmp.Diff([]*ateapi.Actor{b1}, listB.GetActors(), sortByID...); diff != "" { t.Errorf("ListActors(team-b) mismatch (-want +got):\n%s", diff) } // Get is scoped: the right atespace hits, the empty atespace misses (deny-across by key). - if _, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "id1"}}); err != nil { + if _, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "id1"}}); err != nil { t.Errorf("GetActor(id1, team-a) failed: %v", err) } - _, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"}}) + _, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"}}) assertGrpcError(t, err, codes.NotFound, "Actor test-atespace/id1 not found") } @@ -659,9 +659,9 @@ func TestListActors_AllAtespaces(t *testing.T) { createAtespace(t, tc, "team-b") create := func(atespace, name string) { - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor(%s, atespace=%q) failed: %v", name, atespace, err) } @@ -670,7 +670,7 @@ func TestListActors_AllAtespaces(t *testing.T) { create("team-b", "id2") // Empty atespace lists across all atespaces; returned actors carry their atespace. - resp, err := tc.client.ListActors(context.Background(), &ateapipb.ListActorsRequest{}) + resp, err := tc.client.ListActors(context.Background(), &ateapi.ListActorsRequest{}) if err != nil { t.Fatalf("ListActors(all) failed: %v", err) } @@ -694,11 +694,11 @@ func TestListActors_Pagination(t *testing.T) { createTemplate(t, tc, ns) - var want []*ateapipb.Actor + var want []*ateapi.Actor for i := 0; i < 5; i++ { - resp, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: fmt.Sprintf("name%d", i)}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + resp, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: fmt.Sprintf("name%d", i)}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor %d failed: %v", i, err) @@ -706,13 +706,13 @@ func TestListActors_Pagination(t *testing.T) { want = append(want, resp) } - var allActors []*ateapipb.Actor + var allActors []*ateapi.Actor pageToken := "" for { - listResp, err := tc.client.ListActors(context.Background(), &ateapipb.ListActorsRequest{ + listResp, err := tc.client.ListActors(context.Background(), &ateapi.ListActorsRequest{ Atespace: testAtespace, - Options: &ateapipb.ListOptions{PageSize: 2, PageToken: pageToken}, + Options: &ateapi.ListOptions{PageSize: 2, PageToken: pageToken}, }) if err != nil { t.Fatalf("ListActors failed: %v", err) @@ -731,7 +731,7 @@ func TestListActors_Pagination(t *testing.T) { opts := []cmp.Option{ protocmp.Transform(), - cmpopts.SortSlices(func(a, b *ateapipb.Actor) bool { + cmpopts.SortSlices(func(a, b *ateapi.Actor) bool { return a.GetMetadata().GetName() < b.GetMetadata().GetName() }), } @@ -750,36 +750,36 @@ func TestUpdateActor_Success(t *testing.T) { tmpl := createTemplate(t, tc, ns) - toUpdate, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - WorkerSelector: &ateapipb.Selector{ + toUpdate, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + WorkerSelector: &ateapi.Selector{ MatchLabels: map[string]string{"tier": "free"}, }, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - toUpdate.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}} + toUpdate.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}} - updateResp, err := tc.client.UpdateActor(context.Background(), &ateapipb.UpdateActorRequest{ + updateResp, err := tc.client.UpdateActor(context.Background(), &ateapi.UpdateActorRequest{ Actor: toUpdate, }) if err != nil { t.Fatalf("UpdateActor failed: %v", err) } - wantActor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "id1", Atespace: testAtespace, Version: 2}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + wantActor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "id1", Atespace: testAtespace, Version: 2}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)), + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)), }, }, - WorkerSelector: &ateapipb.Selector{ + WorkerSelector: &ateapi.Selector{ MatchLabels: map[string]string{"tier": "paid"}, }, } @@ -787,7 +787,7 @@ func TestUpdateActor_Success(t *testing.T) { t.Errorf("UpdateActor response mismatch (-want +got):\n%s", diff) } - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"}}) + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"}}) if err != nil { t.Fatalf("GetActor failed: %v", err) } @@ -821,46 +821,46 @@ func TestUpdateActor_RepointTemplate(t *testing.T) { ctx := context.Background() // tmpl-a and tmpl-b are volume-compatible; tmpl-c mounts the data // volume elsewhere, and tmpl-d declares an extra volume. - dataVolume := &ateapipb.Volume{Name: "data", DurableDir: &ateapipb.DurableDirVolumeSource{}} - scratchVolume := &ateapipb.Volume{Name: "scratch", DurableDir: &ateapipb.DurableDirVolumeSource{}} + dataVolume := &ateapi.Volume{Name: "data", DurableDir: &ateapi.DurableDirVolumeSource{}} + scratchVolume := &ateapi.Volume{Name: "scratch", DurableDir: &ateapi.DurableDirVolumeSource{}} templates := map[string]struct { mountPath string - volumes []*ateapipb.Volume + volumes []*ateapi.Volume }{ - "tmpl-a": {"/data", []*ateapipb.Volume{dataVolume}}, - "tmpl-b": {"/data", []*ateapipb.Volume{dataVolume}}, - "tmpl-c": {"/mnt/data", []*ateapipb.Volume{dataVolume}}, - "tmpl-d": {"/data", []*ateapipb.Volume{dataVolume, scratchVolume}}, + "tmpl-a": {"/data", []*ateapi.Volume{dataVolume}}, + "tmpl-b": {"/data", []*ateapi.Volume{dataVolume}}, + "tmpl-c": {"/mnt/data", []*ateapi.Volume{dataVolume}}, + "tmpl-d": {"/data", []*ateapi.Volume{dataVolume, scratchVolume}}, } for name, tmpl := range templates { - if _, err := tc.client.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ - ActorTemplate: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - Containers: []*ateapipb.Container{{ + if _, err := tc.client.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ + ActorTemplate: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + Containers: []*ateapi.Container{{ Name: "main", Image: "example.com/app:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - VolumeMounts: []*ateapipb.VolumeMount{{Name: "data", MountPath: tmpl.mountPath}}, + VolumeMounts: []*ateapi.VolumeMount{{Name: "data", MountPath: tmpl.mountPath}}, }}, Volumes: tmpl.volumes, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: "gs://my-bucket/snapshots"}, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: "gs://my-bucket/snapshots"}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, }, }); err != nil { t.Fatalf("CreateActorTemplate %s failed: %v", name, err) } } - created, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "repoint-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}, + created, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "repoint-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - updated, err := tc.client.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{ + updated, err := tc.client.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ Metadata: created.GetMetadata(), - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: tt.template}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: tt.template}, }}) if got := status.Code(err); got != tt.wantCode { t.Fatalf("UpdateActor repointing at %s = %v, want %v (err: %v)", tt.template, got, tt.wantCode, err) @@ -869,10 +869,10 @@ func TestUpdateActor_RepointTemplate(t *testing.T) { return } - want := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "repoint-actor", Version: 2}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: tt.template}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + want := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "repoint-actor", Version: 2}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: tt.template}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, } if diff := cmp.Diff(want, updated, protocmp.Transform(), ignoreUID, ignoreTimestamps); diff != "" { t.Errorf("UpdateActor response mismatch (-want +got):\n%s", diff) @@ -892,10 +892,10 @@ func TestUpdateActor(t *testing.T) { tmpl := createTemplate(t, tc, ns) - created, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - WorkerSelector: &ateapipb.Selector{ + created, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + WorkerSelector: &ateapi.Selector{ MatchLabels: map[string]string{"tier": "free"}, }, }}) @@ -904,25 +904,25 @@ func TestUpdateActor(t *testing.T) { } // Mutable field - created.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}} + created.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}} // Output-only: server-owned, so this is ignored rather than applied. - created.Status = &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING} - updatedActor, err := tc.client.UpdateActor(context.Background(), &ateapipb.UpdateActorRequest{Actor: created}) + created.Status = &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING} + updatedActor, err := tc.client.UpdateActor(context.Background(), &ateapi.UpdateActorRequest{Actor: created}) if err != nil { t.Fatalf("UpdateActor failed: %v", err) } - wantActor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "id1", Atespace: testAtespace, Version: 2}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + wantActor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "id1", Atespace: testAtespace, Version: 2}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)), + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)), }, }, - WorkerSelector: &ateapipb.Selector{ + WorkerSelector: &ateapi.Selector{ MatchLabels: map[string]string{"tier": "paid"}, }, } @@ -931,20 +931,20 @@ func TestUpdateActor(t *testing.T) { } // Mutable template ref: repoint the actor at a second template. - tmpl2 := proto.Clone(tmpl).(*ateapipb.ActorTemplate) - tmpl2.Metadata = &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "tmpl2"} + tmpl2 := proto.Clone(tmpl).(*ateapi.ActorTemplate) + tmpl2.Metadata = &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "tmpl2"} tmpl2.Status = nil - if _, err := tc.client.CreateActorTemplate(context.Background(), &ateapipb.CreateActorTemplateRequest{ActorTemplate: tmpl2}); err != nil { + if _, err := tc.client.CreateActorTemplate(context.Background(), &ateapi.CreateActorTemplateRequest{ActorTemplate: tmpl2}); err != nil { t.Fatalf("CreateActorTemplate failed: %v", err) } - updatedActor.ActorTemplate = &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl2"} - repointed, err := tc.client.UpdateActor(context.Background(), &ateapipb.UpdateActorRequest{Actor: updatedActor}) + updatedActor.ActorTemplate = &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl2"} + repointed, err := tc.client.UpdateActor(context.Background(), &ateapi.UpdateActorRequest{Actor: updatedActor}) if err != nil { t.Fatalf("UpdateActor failed: %v", err) } wantActor.Metadata.Version = 3 - wantActor.ActorTemplate = &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl2"} + wantActor.ActorTemplate = &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl2"} if diff := cmp.Diff(wantActor, repointed, protocmp.Transform(), ignoreUID, ignoreTimestamps); diff != "" { t.Errorf("UpdateActor response mismatch after template repoint (-want +got):\n%s", diff) } @@ -960,11 +960,11 @@ func TestUpdateActor_Preconditions(t *testing.T) { createTemplate(t, tc, ns) ctx := context.Background() - createActor := func() *ateapipb.Actor { + createActor := func() *ateapi.Actor { t.Helper() - actor, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actor, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) @@ -972,16 +972,16 @@ func TestUpdateActor_Preconditions(t *testing.T) { return actor } - update := func(observed *ateapipb.Actor, tier string) (*ateapipb.Actor, error) { - actor := proto.Clone(observed).(*ateapipb.Actor) - actor.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"tier": tier}} - return tc.client.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: actor}) + update := func(observed *ateapi.Actor, tier string) (*ateapi.Actor, error) { + actor := proto.Clone(observed).(*ateapi.Actor) + actor.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"tier": tier}} + return tc.client.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: actor}) } // Delete and recreate the same atespace/name actor, so the first lifecycle's uid // becomes stale. staleUID := createActor().GetMetadata().GetUid() - if _, err := tc.client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: testActorID}, + if _, err := tc.client.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: testActorID}, }); err != nil { t.Fatalf("DeleteActor failed: %v", err) } @@ -993,7 +993,7 @@ func TestUpdateActor_Preconditions(t *testing.T) { t.Fatalf("recreated actor reused uid %s, want a fresh one", uid) } // No preconditions - unguarded := proto.Clone(created).(*ateapipb.Actor) + unguarded := proto.Clone(created).(*ateapi.Actor) unguarded.Metadata.Uid, unguarded.Metadata.Version = "", 0 _, err := update(unguarded, "blind") assertGrpcError(t, err, codes.InvalidArgument, "while updating actor test-atespace/id1: persistence: precondition required: uid") @@ -1001,7 +1001,7 @@ func TestUpdateActor_Preconditions(t *testing.T) { // The uid from the deleted lifecycle must be rejected, even though the // atespace/name it was observed under still resolves and the version it // guards on matches the recreated actor's. - otherLifecycle := proto.Clone(created).(*ateapipb.Actor) + otherLifecycle := proto.Clone(created).(*ateapi.Actor) otherLifecycle.Metadata.Uid = staleUID _, err = update(otherLifecycle, "other-lifecycle") assertGrpcError(t, err, codes.Aborted, "concurrent update conflict, please retry") @@ -1047,8 +1047,8 @@ func TestUpdateActor_NotFound(t *testing.T) { tc := setupTest(t, ns) defer tc.cleanup() - _, err := tc.client.UpdateActor(context.Background(), &ateapipb.UpdateActorRequest{ - Actor: &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{ + _, err := tc.client.UpdateActor(context.Background(), &ateapi.UpdateActorRequest{ + Actor: &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{ Atespace: testAtespace, Name: "does-not-exist", // Well-formed guards to pass preconditions validation @@ -1065,19 +1065,19 @@ func TestUpdateActor_StampsFullSpanIdentity(t *testing.T) { defer tc.cleanup() createTemplate(t, tc, ns) - toUpdate, err := tc.service.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + toUpdate, err := tc.service.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }) if err != nil { t.Fatalf("seed CreateActor: %v", err) } - toUpdate.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"env": "prod"}} + toUpdate.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"env": "prod"}} attrs := recordRootSpanAttrs(t, func(ctx context.Context) { - if _, err := tc.service.UpdateActor(ctx, &ateapipb.UpdateActorRequest{ + if _, err := tc.service.UpdateActor(ctx, &ateapi.UpdateActorRequest{ Actor: toUpdate, }); err != nil { t.Fatalf("UpdateActor: %v", err) @@ -1102,8 +1102,8 @@ func TestUpdateActor_FailedLookupStampsRefIdentityOnly(t *testing.T) { defer tc.cleanup() attrs := recordRootSpanAttrs(t, func(ctx context.Context) { - if _, err := tc.service.UpdateActor(ctx, &ateapipb.UpdateActorRequest{ - Actor: &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{ + if _, err := tc.service.UpdateActor(ctx, &ateapi.UpdateActorRequest{ + Actor: &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{ Atespace: testAtespace, Name: testActorID, // Well-formed guards to pass preconditions validation @@ -1131,16 +1131,16 @@ func TestDeleteActor_Success(t *testing.T) { createTemplate(t, tc, ns) - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - deleted, err := tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"}, + deleted, err := tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"}, }) if err != nil { t.Fatalf("DeleteActor failed: %v", err) @@ -1156,8 +1156,8 @@ func TestDeleteActor_Success(t *testing.T) { t.Errorf("deleted actor atespace = %q, want %q", got, testAtespace) } - _, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"}, + _, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"}, }) assertGrpcError(t, err, codes.NotFound, "Actor test-atespace/id1 not found") } @@ -1170,9 +1170,9 @@ func TestDeleteActor_MissingSnapshotBucket(t *testing.T) { {name: "S3", err: &types.NoSuchBucket{}}, {name: "GCS", err: storage.ErrBucketNotExist}, } { - for _, state := range []ateapipb.ActorState{ - ateapipb.ActorState_ACTOR_STATE_SUSPENDED, - ateapipb.ActorState_ACTOR_STATE_DELETING, + for _, state := range []ateapi.ActorState{ + ateapi.ActorState_ACTOR_STATE_SUSPENDED, + ateapi.ActorState_ACTOR_STATE_DELETING, } { t.Run(provider.name+"/"+state.String(), func(t *testing.T) { ns := namespaceForTest("ns-delete-missing-bucket") @@ -1180,10 +1180,10 @@ func TestDeleteActor_MissingSnapshotBucket(t *testing.T) { defer tc.cleanup() createTemplate(t, tc, ns) ctx := t.Context() - ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: testActorID} - actor, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + ref := &ateapi.ObjectRef{Atespace: testAtespace, Name: testActorID} + actor, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor: %v", err) @@ -1192,15 +1192,15 @@ func TestDeleteActor_MissingSnapshotBucket(t *testing.T) { if err != nil { t.Fatal(err) } - if _, err := tc.persistence.UpdateActor(ctx, resources.ActorRefFromActor(actor), store.PreconditionFrom(actor), func(toUpdate *ateapipb.Actor) error { + if _, err := tc.persistence.UpdateActor(ctx, resources.ActorRefFromActor(actor), store.PreconditionFrom(actor), func(toUpdate *ateapi.Actor) error { toUpdate.Status.State = state - snap := newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", uri.Name(), uri.String()) - if state != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + snap := newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", uri.Name(), uri.String()) + if state != ateapi.ActorState_ACTOR_STATE_SUSPENDED { // A failed upload leaves only the in-progress URI, even // when a prior deletion already marked the actor DELETING. - snap.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + snap.DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING } - toUpdate.Status.Snapshots = []*ateapipb.Snapshot{snap} + toUpdate.Status.Snapshots = []*ateapi.Snapshot{snap} return nil }); err != nil { t.Fatalf("UpdateActor: %v", err) @@ -1217,7 +1217,7 @@ func TestDeleteActor_MissingSnapshotBucket(t *testing.T) { } return fmt.Errorf("snapshot bucket removed: %w", provider.err) } - deleted, err := tc.client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref}) + deleted, err := tc.client.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}) if err != nil { t.Fatalf("DeleteActor with missing snapshot bucket: %v", err) } @@ -1227,7 +1227,7 @@ func TestDeleteActor_MissingSnapshotBucket(t *testing.T) { if got := listCalls.Load(); got != 1 { t.Errorf("snapshot cleanup list calls = %d, want 1", got) } - _, err = tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: ref}) + _, err = tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: ref}) assertGrpcError(t, err, codes.NotFound, "Actor test-atespace/id1 not found") }) } @@ -1247,46 +1247,46 @@ func TestDeleteActor_Running(t *testing.T) { }) defer tc.cleanup() - createTemplateWithVolumes(t, tc, ns, []*ateapipb.Volume{ + createTemplateWithVolumes(t, tc, ns, []*ateapi.Volume{ { Name: "vol1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }, - }, []*ateapipb.VolumeMount{ + }, []*ateapi.VolumeMount{ {Name: "vol1", MountPath: "/mnt/vol1"}, }) createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") ctx := context.Background() - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } // Suspend once so the actor owns an external snapshot, then resume it. - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } - if _, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ + if _, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{ Actor: actorRef, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }); err != nil { t.Fatalf("SuspendActor failed: %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("second ResumeActor failed: %v", err) } - running, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actorRef}) + running, err := tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if got := running.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := running.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Fatalf("actor state = %v, want ACTOR_STATE_RUNNING", got) } actorUID := running.GetMetadata().GetUid() @@ -1302,7 +1302,7 @@ func TestDeleteActor_Running(t *testing.T) { plugin.deleted = nil plugin.mu.Unlock() - if _, err := tc.client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: actorRef}); err != nil { t.Fatalf("DeleteActor of a running actor failed: %v", err) } if !tc.fakeAtelet.TerminateCalled { @@ -1318,7 +1318,7 @@ func TestDeleteActor_Running(t *testing.T) { if worker, err := tc.persistence.FindWorkerHostingActor(ctx, actorUID); !errors.Is(err, store.ErrNotFound) { t.Errorf("FindWorkerHostingActor after delete = (%q, %v), want ErrNotFound", worker, err) } - _, err = tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actorRef}) + _, err = tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: actorRef}) assertGrpcError(t, err, codes.NotFound, "Actor test-atespace/id1 not found") } @@ -1331,26 +1331,26 @@ func TestDeleteActor_Crashed(t *testing.T) { createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") ctx := context.Background() - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } // Resume onto worker-1 so AssignedNode is set to "node1", then delete // worker-1 so the actor crashes and loses its WorkerAssignment. - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } deleteWorkerPod(t, tc, ns, "worker-1") - crashed, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actorRef}) + crashed, err := tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if got := crashed.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got := crashed.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Fatalf("state = %v, want CRASHED", got) } if got := crashed.GetStatus().GetAssignedNode(); got != "node1" { @@ -1364,14 +1364,14 @@ func TestDeleteActor_Crashed(t *testing.T) { tc.fakeAtelet.TerminateCalled = false tc.fakeAtelet.Lock.Unlock() - deleted, err := tc.client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ + deleted, err := tc.client.DeleteActor(ctx, &ateapi.DeleteActorRequest{ Actor: actorRef, }) if err != nil { t.Fatalf("DeleteActor of crashed actor failed: %v", err) } - if got := deleted.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_DELETING { - t.Errorf("deleted actor state = %v, want %v", got, ateapipb.ActorState_ACTOR_STATE_DELETING) + if got := deleted.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_DELETING { + t.Errorf("deleted actor state = %v, want %v", got, ateapi.ActorState_ACTOR_STATE_DELETING) } if !tc.fakeAtelet.TerminateCalled { t.Errorf("expected Terminate call to clean up assigned node for crashed actor") @@ -1379,7 +1379,7 @@ func TestDeleteActor_Crashed(t *testing.T) { t.Errorf("TerminateRequest.WorkerPodUid = %q, want empty for crashed actor", gotUID) } - _, err = tc.client.GetActor(ctx, &ateapipb.GetActorRequest{ + _, err = tc.client.GetActor(ctx, &ateapi.GetActorRequest{ Actor: actorRef, }) assertGrpcError(t, err, codes.NotFound, "Actor test-atespace/id1 not found") @@ -1397,32 +1397,32 @@ func TestDeleteActor_RetryAfterWorkerDelete(t *testing.T) { createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") ctx := context.Background() - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } tc.fakeAtelet.Lock.Lock() tc.fakeAtelet.FailTerminate = status.Error(codes.Unavailable, "node unavailable") tc.fakeAtelet.Lock.Unlock() - if _, err := tc.client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: actorRef}); err == nil { + if _, err := tc.client.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: actorRef}); err == nil { t.Fatal("DeleteActor succeeded, want it to fail on Terminate") } // This would crash a RUNNING Actor. But, should keep a DELETING actor // unchanged. deleteWorkerPod(t, tc, ns, "worker-1") - actor, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actorRef}) + actor, err := tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if got := actor.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_DELETING { + if got := actor.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_DELETING { t.Fatalf("state after worker delete = %v, want DELETING", got) } @@ -1431,7 +1431,7 @@ func TestDeleteActor_RetryAfterWorkerDelete(t *testing.T) { tc.fakeAtelet.FailTerminate = nil tc.fakeAtelet.TerminateRequest = nil tc.fakeAtelet.Lock.Unlock() - if _, err := tc.client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: actorRef}); err != nil { t.Fatalf("retried DeleteActor failed: %v", err) } @@ -1444,7 +1444,7 @@ func TestDeleteActor_RetryAfterWorkerDelete(t *testing.T) { } else if gotUID := terminate.GetWorkerPodUid(); gotUID != "" { t.Errorf("TerminateRequest.WorkerPodUid = %q, want empty", gotUID) } - _, err = tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actorRef}) + _, err = tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: actorRef}) assertGrpcError(t, err, codes.NotFound, "Actor test-atespace/id1 not found") } @@ -1453,8 +1453,8 @@ func TestDeleteActor_NotFound(t *testing.T) { tc := setupTest(t, ns) defer tc.cleanup() - _, err := tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "non-existent"}, + _, err := tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "non-existent"}, }) assertGrpcError(t, err, codes.NotFound, "Actor test-atespace/non-existent not found") } @@ -1466,18 +1466,18 @@ func TestDeleteActor_StampsRefSpanIdentity(t *testing.T) { tc := setupTest(t, ns) defer tc.cleanup() createTemplate(t, tc, ns) - if _, err := tc.service.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.service.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }); err != nil { t.Fatalf("seed CreateActor: %v", err) } attrs := recordRootSpanAttrs(t, func(ctx context.Context) { - if _, err := tc.service.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: testActorID}, + if _, err := tc.service.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: testActorID}, }); err != nil { t.Fatalf("DeleteActor: %v", err) } @@ -1493,13 +1493,13 @@ func TestDeleteActor_StateDeleting(t *testing.T) { defer tc.cleanup() createTemplate(t, tc, ns) - deletingActor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ + deletingActor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: testAtespace, Name: "deleting-actor", }, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_DELETING}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_DELETING}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, } if _, err := tc.persistence.CreateActor(context.Background(), deletingActor); err != nil { t.Fatalf("CreateActor: %v", err) @@ -1508,8 +1508,8 @@ func TestDeleteActor_StateDeleting(t *testing.T) { t.Fatalf("MarkActorForDeletion: %v", err) } - if _, err := tc.service.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "deleting-actor"}, + if _, err := tc.service.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "deleting-actor"}, }); err != nil { t.Fatalf("DeleteActor on ACTOR_STATE_DELETING actor failed: %v", err) } @@ -1530,24 +1530,24 @@ func TestDeleteActor_Paused(t *testing.T) { createTemplate(t, tc, ns) createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"} - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"} + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } - if _, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}); err != nil { + if _, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}); err != nil { t.Fatalf("SuspendActor failed: %v", err) } - paused, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: actorRef}) + paused, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if got := paused.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := paused.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("actor state after pause = %v, want ACTOR_STATE_SUSPENDED", got) } if localSnapshot(paused.GetStatus()) == nil { @@ -1555,7 +1555,7 @@ func TestDeleteActor_Paused(t *testing.T) { } tc.fakeAtelet.Reset() - if _, err := tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{Actor: actorRef}); err != nil { t.Fatalf("DeleteActor of a paused actor failed: %v", err) } if !tc.fakeAtelet.TerminateCalled { @@ -1563,7 +1563,7 @@ func TestDeleteActor_Paused(t *testing.T) { } else if got, want := tc.fakeAtelet.TerminateRequest.GetActorUid(), paused.GetMetadata().GetUid(); got != want { t.Errorf("Terminate actor_uid = %q, want %q", got, want) } - if _, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: actorRef}); status.Code(err) != codes.NotFound { + if _, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: actorRef}); status.Code(err) != codes.NotFound { t.Errorf("GetActor after DeleteActor err = %v, want NotFound", err) } } @@ -1589,15 +1589,15 @@ func TestDeleteActor_MultipleVolumeDeletionFailures(t *testing.T) { defer tc.cleanup() createTemplate(t, tc, ns) - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: testAtespace, Name: "multi-vol-actor", }, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, - ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{ + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, + ExternalVolumes: &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol1", StorageVolumeId: "storage-vol-1", VolumeType: "substrate.io/mock"}, {Name: "vol2", StorageVolumeId: "storage-vol-2", VolumeType: "substrate.io/mock"}, }}, @@ -1607,8 +1607,8 @@ func TestDeleteActor_MultipleVolumeDeletionFailures(t *testing.T) { t.Fatalf("CreateActor: %v", err) } - _, err := tc.service.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "multi-vol-actor"}, + _, err := tc.service.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "multi-vol-actor"}, }) if err == nil { t.Fatalf("expected DeleteActor to fail when volume deletion fails, but it succeeded") @@ -1667,15 +1667,15 @@ func TestDeleteActor_VolumeDeletionFailure_RetrySuccess(t *testing.T) { createTemplate(t, tc, ns) // 1. Create suspended actor with a provisioned external volume. - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: testAtespace, Name: "delete-retry-actor", }, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, - ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{ + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, + ExternalVolumes: &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol1", StorageVolumeId: "storage-vol-1", VolumeType: "substrate.io/mock"}, }}, }, @@ -1685,21 +1685,21 @@ func TestDeleteActor_VolumeDeletionFailure_RetrySuccess(t *testing.T) { } // 2. First DeleteActor call should fail due to DeleteVolume error. - _, err := tc.service.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "delete-retry-actor"}, + _, err := tc.service.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "delete-retry-actor"}, }) if err == nil { t.Fatalf("expected DeleteActor to fail, but got nil") } // 3. Verify actor is persisted in ACTOR_STATE_DELETING with its volume still recorded. - getResp, err := tc.service.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "delete-retry-actor"}, + getResp, err := tc.service.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "delete-retry-actor"}, }) if err != nil { t.Fatalf("GetActor after failed delete: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_DELETING { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_DELETING { t.Errorf("actor state = %v, want ACTOR_STATE_DELETING", getResp.GetStatus().GetState()) } if len(getResp.GetStatus().GetExternalVolumes().GetVolumes()) != 1 { @@ -1712,16 +1712,16 @@ func TestDeleteActor_VolumeDeletionFailure_RetrySuccess(t *testing.T) { plugin.mu.Unlock() // 5. Second DeleteActor call (retry) re-attempts deletion and should succeed. - _, err = tc.service.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "delete-retry-actor"}, + _, err = tc.service.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "delete-retry-actor"}, }) if err != nil { t.Fatalf("expected retry DeleteActor to succeed, got: %v", err) } // 6. Verify actor is removed from store. - _, err = tc.service.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "delete-retry-actor"}, + _, err = tc.service.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "delete-retry-actor"}, }) if apierror.Code(err) != codes.NotFound { t.Errorf("GetActor after successful delete retry = %v, want NotFound", err) @@ -1736,9 +1736,9 @@ func TestCreateActor_AtespaceNotFound(t *testing.T) { // The template exists, but "missing-as" was never created. The template // check fires first, so reaching this error proves the atespace check ran. - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "missing-as", Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "missing-as", Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) assertGrpcError(t, err, codes.FailedPrecondition, "Atespace missing-as not found") } @@ -1749,47 +1749,47 @@ func TestValidation_Actor(t *testing.T) { defer tc.cleanup() t.Run("CreateActor", func(t *testing.T) { - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{}) + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "actor: Required value") }) t.Run("GetActor", func(t *testing.T) { - _, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{}) + _, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "actor: Required value") }) t.Run("ResumeActor", func(t *testing.T) { - _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{}) + _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "actor: Required value") }) t.Run("SuspendActor", func(t *testing.T) { - _, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{}) + _, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "actor: Required value") }) t.Run("UpdateActor", func(t *testing.T) { - _, err := tc.client.UpdateActor(context.Background(), &ateapipb.UpdateActorRequest{}) + _, err := tc.client.UpdateActor(context.Background(), &ateapi.UpdateActorRequest{}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "actor: Required value") }) t.Run("DeleteActor", func(t *testing.T) { - _, err := tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{}) + _, err := tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "actor: Required value") }) t.Run("ListActors", func(t *testing.T) { - _, err := tc.client.ListActors(context.Background(), &ateapipb.ListActorsRequest{Options: &ateapipb.ListOptions{PageSize: -1}}) + _, err := tc.client.ListActors(context.Background(), &ateapi.ListActorsRequest{Options: &ateapi.ListOptions{PageSize: -1}}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "page_size: Invalid value") }) t.Run("ListActors invalid token", func(t *testing.T) { - _, err := tc.client.ListActors(context.Background(), &ateapipb.ListActorsRequest{Options: &ateapipb.ListOptions{PageToken: "%%%"}}) + _, err := tc.client.ListActors(context.Background(), &ateapi.ListActorsRequest{Options: &ateapi.ListOptions{PageToken: "%%%"}}) assertGrpcError(t, err, codes.InvalidArgument, "invalid page_token") }) t.Run("ListTags invalid token", func(t *testing.T) { - _, err := tc.client.ListTags(context.Background(), &ateapipb.ListTagsRequest{Options: &ateapipb.ListOptions{PageToken: "%%%"}}) + _, err := tc.client.ListTags(context.Background(), &ateapi.ListTagsRequest{Options: &ateapi.ListOptions{PageToken: "%%%"}}) assertGrpcError(t, err, codes.InvalidArgument, "invalid page_token") }) } @@ -1801,16 +1801,16 @@ func TestActorLifecycle_WithExternalVolumes(t *testing.T) { tc := setupPreviewTest(t, ns) defer tc.cleanup() - volumes := []*ateapipb.Volume{ + volumes := []*ateapi.Volume{ { Name: "data-vol", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "fast", CapacityBytes: 20 << 30, }}, }, } - mounts := []*ateapipb.VolumeMount{ + mounts := []*ateapi.VolumeMount{ { Name: "data-vol", MountPath: "/mnt/data", @@ -1820,16 +1820,16 @@ func TestActorLifecycle_WithExternalVolumes(t *testing.T) { workerName := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") // 1. CreateActor - createResp, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "actor-vol-lc"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + createResp, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "actor-vol-lc"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - if createResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if createResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("expected initial state ACTOR_STATE_SUSPENDED, got %v", createResp.GetStatus().GetState()) } if len(createResp.GetStatus().GetExternalVolumes().GetVolumes()) != 1 || createResp.GetStatus().GetExternalVolumes().GetVolumes()[0].GetStorageVolumeId() != "" { @@ -1837,13 +1837,13 @@ func TestActorLifecycle_WithExternalVolumes(t *testing.T) { } // 2. ResumeActor - resumeResp, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-vol-lc"}, + resumeResp, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-vol-lc"}, }) if err != nil { t.Fatalf("ResumeActor failed: %v", err) } - if resumeResp.GetActor().GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if resumeResp.GetActor().GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Fatalf("expected state ACTOR_STATE_RUNNING after resume, got %v", resumeResp.GetActor().GetStatus().GetState()) } if len(resumeResp.GetActor().GetStatus().GetExternalVolumes().GetVolumes()) != 1 { @@ -1854,14 +1854,14 @@ func TestActorLifecycle_WithExternalVolumes(t *testing.T) { } // 3. Async SuspendActor - pauseResp, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-vol-lc"}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + pauseResp, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-vol-lc"}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } - if pauseResp.GetActor().GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if pauseResp.GetActor().GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("expected state ACTOR_STATE_SUSPENDED after pause, got %v", pauseResp.GetActor().GetStatus().GetState()) } if localSnapshot(pauseResp.GetActor().GetStatus()) == nil { @@ -1871,31 +1871,31 @@ func TestActorLifecycle_WithExternalVolumes(t *testing.T) { // 4. ResumeActor from node-local snapshot waitForWorkerAvailable(t, tc, workerName) - resumeResp2, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-vol-lc"}, + resumeResp2, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-vol-lc"}, }) if err != nil { t.Fatalf("ResumeActor from paused failed: %v", err) } - if resumeResp2.GetActor().GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if resumeResp2.GetActor().GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Fatalf("expected state ACTOR_STATE_RUNNING after second resume, got %v", resumeResp2.GetActor().GetStatus().GetState()) } // 5. Sync SuspendActor - suspendResp, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-vol-lc"}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + suspendResp, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-vol-lc"}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } - if suspendResp.GetActor().GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if suspendResp.GetActor().GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("expected state ACTOR_STATE_SUSPENDED after suspend, got %v", suspendResp.GetActor().GetStatus().GetState()) } // 6. DeleteActor - deleteResp, err := tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-vol-lc"}, + deleteResp, err := tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-vol-lc"}, }) if err != nil { t.Fatalf("DeleteActor failed: %v", err) @@ -1905,8 +1905,8 @@ func TestActorLifecycle_WithExternalVolumes(t *testing.T) { } // Confirm GetActor returns NotFound after deletion - _, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-vol-lc"}, + _, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-vol-lc"}, }) if status.Code(err) != codes.NotFound { t.Errorf("GetActor after delete err = %v, want NotFound", err) @@ -1951,33 +1951,33 @@ func TestResumeActor_VolumeCreationFailure(t *testing.T) { }) defer tc.cleanup() - volumes := []*ateapipb.Volume{ + volumes := []*ateapi.Volume{ { Name: "succ-vol1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }, { Name: "fail-vol2", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }, } - mounts := []*ateapipb.VolumeMount{ + mounts := []*ateapi.VolumeMount{ {Name: "succ-vol1", MountPath: "/mnt/vol1"}, {Name: "fail-vol2", MountPath: "/mnt/vol2"}, } createTemplateWithVolumes(t, tc, ns, volumes, mounts) // Call CreateActor RPC directly - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "fail-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "fail-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }) if err != nil { @@ -1985,22 +1985,22 @@ func TestResumeActor_VolumeCreationFailure(t *testing.T) { } // Call ResumeActor RPC, which should trigger volume provisioning and fail on fail-vol2 - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "fail-actor"}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "fail-actor"}, }) if err == nil { t.Fatalf("expected ResumeActor to fail due to volume creation error, but it succeeded") } // Verify GetActor returns the actor in ACTOR_STATE_SUSPENDED state - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "fail-actor"}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "fail-actor"}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { - t.Errorf("actor state = %v, want %v", getResp.GetStatus().GetState(), ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { + t.Errorf("actor state = %v, want %v", getResp.GetStatus().GetState(), ateapi.ActorState_ACTOR_STATE_SUSPENDED) } actorUID := getResp.GetMetadata().GetUid() @@ -2012,7 +2012,7 @@ func TestResumeActor_VolumeCreationFailure(t *testing.T) { if len(getResp.GetStatus().GetExternalVolumes().GetVolumes()) != 2 { t.Fatalf("expected 2 volumes on actor, got %d", len(getResp.GetStatus().GetExternalVolumes().GetVolumes())) } - volsByName := make(map[string]*ateapipb.ExternalVolumeStatus) + volsByName := make(map[string]*ateapi.ExternalVolumeStatus) for _, v := range getResp.GetStatus().GetExternalVolumes().GetVolumes() { volsByName[v.GetName()] = v } @@ -2024,8 +2024,8 @@ func TestResumeActor_VolumeCreationFailure(t *testing.T) { } // Call DeleteActor on the actor in ACTOR_STATE_SUSPENDED - _, err = tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "fail-actor"}, + _, err = tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "fail-actor"}, }) if err != nil { t.Fatalf("DeleteActor failed: %v", err) @@ -2041,8 +2041,8 @@ func TestResumeActor_VolumeCreationFailure(t *testing.T) { } // Confirm GetActor returns NotFound after deletion - _, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "fail-actor"}, + _, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "fail-actor"}, }) if status.Code(err) != codes.NotFound { t.Errorf("GetActor after DeleteActor err = %v, want NotFound", err) @@ -2095,23 +2095,23 @@ func TestResumeActor_VolumeCreationRetrySuccess(t *testing.T) { }) defer tc.cleanup() - volumes := []*ateapipb.Volume{ + volumes := []*ateapi.Volume{ { Name: "succ-vol1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }, { Name: "retry-vol2", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }, } - retryMounts := []*ateapipb.VolumeMount{ + retryMounts := []*ateapi.VolumeMount{ {Name: "succ-vol1", MountPath: "/mnt/vol1"}, {Name: "retry-vol2", MountPath: "/mnt/vol2"}, } @@ -2119,10 +2119,10 @@ func TestResumeActor_VolumeCreationRetrySuccess(t *testing.T) { createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") // Call CreateActor RPC directly - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "retry-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "retry-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }) if err != nil { @@ -2130,25 +2130,25 @@ func TestResumeActor_VolumeCreationRetrySuccess(t *testing.T) { } // First call to ResumeActor RPC, which should fail on retry-vol2 (attempt 1) - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "retry-actor"}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "retry-actor"}, }) if err == nil { t.Fatalf("expected first ResumeActor to fail due to temporary volume creation error, but it succeeded") } // Verify GetActor returns the actor in ACTOR_STATE_SUSPENDED state with succ-vol1 created and retry-vol2 pending - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "retry-actor"}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "retry-actor"}, }) if err != nil { t.Fatalf("GetActor after first resume failed: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { - t.Errorf("actor state after first resume = %v, want %v", getResp.GetStatus().GetState(), ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { + t.Errorf("actor state after first resume = %v, want %v", getResp.GetStatus().GetState(), ateapi.ActorState_ACTOR_STATE_SUSPENDED) } - volsByName := make(map[string]*ateapipb.ExternalVolumeStatus) + volsByName := make(map[string]*ateapi.ExternalVolumeStatus) for _, v := range getResp.GetStatus().GetExternalVolumes().GetVolumes() { volsByName[v.GetName()] = v } @@ -2160,22 +2160,22 @@ func TestResumeActor_VolumeCreationRetrySuccess(t *testing.T) { } // Second call to ResumeActor RPC, which should succeed on retry-vol2 (attempt 2) - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "retry-actor"}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "retry-actor"}, }) if err != nil { t.Fatalf("expected second ResumeActor to succeed, got: %v", err) } // Verify GetActor returns the actor in ACTOR_STATE_RUNNING state with both volumes CREATED - getResp, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "retry-actor"}, + getResp, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "retry-actor"}, }) if err != nil { t.Fatalf("GetActor after second resume failed: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { - t.Errorf("actor state after second resume = %v, want %v", getResp.GetStatus().GetState(), ateapipb.ActorState_ACTOR_STATE_RUNNING) + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { + t.Errorf("actor state after second resume = %v, want %v", getResp.GetStatus().GetState(), ateapi.ActorState_ACTOR_STATE_RUNNING) } for _, v := range getResp.GetStatus().GetExternalVolumes().GetVolumes() { if v.GetStorageVolumeId() == "" { @@ -2184,14 +2184,14 @@ func TestResumeActor_VolumeCreationRetrySuccess(t *testing.T) { } // Clean up by suspending and deleting the actor - _, err = tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "retry-actor"}, + _, err = tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "retry-actor"}, }) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } - _, err = tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "retry-actor"}, + _, err = tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "retry-actor"}, }) if err != nil { t.Fatalf("DeleteActor failed: %v", err) @@ -2256,26 +2256,26 @@ func TestResumeActor_VolumeAttachFailureAndRetry(t *testing.T) { }) defer tc.cleanup() - volumes := []*ateapipb.Volume{ + volumes := []*ateapi.Volume{ { Name: "vol1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }, } - mounts := []*ateapipb.VolumeMount{ + mounts := []*ateapi.VolumeMount{ {Name: "vol1", MountPath: "/mnt/vol1"}, } createTemplateWithVolumes(t, tc, ns, volumes, mounts) createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") // Call CreateActor RPC directly - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "attach-retry-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "attach-retry-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }) if err != nil { @@ -2283,8 +2283,8 @@ func TestResumeActor_VolumeAttachFailureAndRetry(t *testing.T) { } // First call to ResumeActor: provisioning succeeds, worker is assigned, but AttachVolume fails (attempt 1) - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "attach-retry-actor"}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "attach-retry-actor"}, }) if err == nil { t.Fatalf("expected first ResumeActor to fail due to attach failure, but it succeeded") @@ -2294,13 +2294,13 @@ func TestResumeActor_VolumeAttachFailureAndRetry(t *testing.T) { } // Verify actor status after failed attach: in ACTOR_STATE_RESUMING, worker assigned, volume CREATED - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "attach-retry-actor"}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "attach-retry-actor"}, }) if err != nil { t.Fatalf("GetActor after failed attach: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RESUMING { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RESUMING { t.Errorf("actor state after failed attach = %v, want ACTOR_STATE_RESUMING", getResp.GetStatus().GetState()) } if getResp.GetStatus().GetWorkerAssignment() == nil || getResp.GetStatus().GetWorkerAssignment().GetWorkerPod() != "worker-1" { @@ -2315,32 +2315,32 @@ func TestResumeActor_VolumeAttachFailureAndRetry(t *testing.T) { } // Second call to ResumeActor: reuses assigned worker, re-attempts volume attach, succeeds (attempt 2), transitions to RUNNING - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "attach-retry-actor"}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "attach-retry-actor"}, }) if err != nil { t.Fatalf("expected second ResumeActor to succeed, got: %v", err) } - getResp, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "attach-retry-actor"}, + getResp, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "attach-retry-actor"}, }) if err != nil { t.Fatalf("GetActor after successful retry: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("actor state after retry = %v, want ACTOR_STATE_RUNNING", getResp.GetStatus().GetState()) } // Clean up by suspending and deleting the actor - _, err = tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "attach-retry-actor"}, + _, err = tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "attach-retry-actor"}, }) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } - _, err = tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "attach-retry-actor"}, + _, err = tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "attach-retry-actor"}, }) if err != nil { t.Fatalf("DeleteActor failed: %v", err) @@ -2359,26 +2359,26 @@ func TestResumeActor_VolumeAttachFailure_DeleteActor(t *testing.T) { }) defer tc.cleanup() - volumes := []*ateapipb.Volume{ + volumes := []*ateapi.Volume{ { Name: "vol1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }, } - mounts := []*ateapipb.VolumeMount{ + mounts := []*ateapi.VolumeMount{ {Name: "vol1", MountPath: "/mnt/vol1"}, } createTemplateWithVolumes(t, tc, ns, volumes, mounts) createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") // Call CreateActor RPC - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "attach-fail-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "attach-fail-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }) if err != nil { @@ -2386,28 +2386,28 @@ func TestResumeActor_VolumeAttachFailure_DeleteActor(t *testing.T) { } // Call ResumeActor RPC, which assigns worker-1 and fails on AttachVolume - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "attach-fail-actor"}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "attach-fail-actor"}, }) if err == nil { t.Fatalf("expected ResumeActor to fail due to attach failure, but it succeeded") } // Verify actor is in ACTOR_STATE_RESUMING - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "attach-fail-actor"}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "attach-fail-actor"}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RESUMING { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RESUMING { t.Fatalf("actor state = %v, want ACTOR_STATE_RESUMING", getResp.GetStatus().GetState()) } actorUID := getResp.GetMetadata().GetUid() // DeleteActor on the RESUMING actor should succeed and cleanly tear down - _, err = tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "attach-fail-actor"}, + _, err = tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "attach-fail-actor"}, }) if err != nil { t.Fatalf("DeleteActor failed: %v", err) @@ -2423,8 +2423,8 @@ func TestResumeActor_VolumeAttachFailure_DeleteActor(t *testing.T) { } // Confirm GetActor returns NotFound after deletion - _, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "attach-fail-actor"}, + _, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "attach-fail-actor"}, }) if status.Code(err) != codes.NotFound { t.Errorf("GetActor after DeleteActor err = %v, want NotFound", err) @@ -2509,23 +2509,23 @@ func TestResumeActor_MultiVolumePartialAttachFailure_Retry(t *testing.T) { defer tc.cleanup() // 1. Create a template with two external volumes and a worker pod. - volumes := []*ateapipb.Volume{ + volumes := []*ateapi.Volume{ { Name: "vol1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }, { Name: "vol2", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }, } - mounts := []*ateapipb.VolumeMount{ + mounts := []*ateapi.VolumeMount{ {Name: "vol1", MountPath: "/mnt/vol1"}, {Name: "vol2", MountPath: "/mnt/vol2"}, } @@ -2533,10 +2533,10 @@ func TestResumeActor_MultiVolumePartialAttachFailure_Retry(t *testing.T) { createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") // 2. Create the actor. - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "multi-attach-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "multi-attach-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }) if err != nil { @@ -2544,8 +2544,8 @@ func TestResumeActor_MultiVolumePartialAttachFailure_Retry(t *testing.T) { } // 3. Attempt 1: vol1 attaches, vol2 fails attach. - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "multi-attach-actor"}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "multi-attach-actor"}, }) if err == nil { t.Fatalf("expected ResumeActor to fail due to partial attach failure, got nil") @@ -2555,13 +2555,13 @@ func TestResumeActor_MultiVolumePartialAttachFailure_Retry(t *testing.T) { } // 4. Verify actor state is ACTOR_STATE_RESUMING, worker assignment is held, and partial attachment state. - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "multi-attach-actor"}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "multi-attach-actor"}, }) if err != nil { t.Fatalf("GetActor after failed attach: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RESUMING { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RESUMING { t.Errorf("actor state = %v, want ACTOR_STATE_RESUMING", getResp.GetStatus().GetState()) } if getResp.GetStatus().GetWorkerAssignment() == nil || getResp.GetStatus().GetWorkerAssignment().GetWorkerPod() != "worker-1" { @@ -2582,33 +2582,33 @@ func TestResumeActor_MultiVolumePartialAttachFailure_Retry(t *testing.T) { plugin.mu.Unlock() // 5. Attempt 2 (retry): re-attempts attach, both succeed, actor reaches RUNNING. - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "multi-attach-actor"}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "multi-attach-actor"}, }) if err != nil { t.Fatalf("expected second ResumeActor to succeed, got: %v", err) } // 6. Verify actor state is RUNNING. - getResp, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "multi-attach-actor"}, + getResp, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "multi-attach-actor"}, }) if err != nil { t.Fatalf("GetActor after second resume: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("actor state after retry = %v, want ACTOR_STATE_RUNNING", getResp.GetStatus().GetState()) } // 7. Clean up by suspending and deleting. - _, err = tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "multi-attach-actor"}, + _, err = tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "multi-attach-actor"}, }) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } - _, err = tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "multi-attach-actor"}, + _, err = tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "multi-attach-actor"}, }) if err != nil { t.Fatalf("DeleteActor failed: %v", err) @@ -2681,42 +2681,42 @@ func TestSuspendActor_VolumeDetachFailure_RetrySuccess(t *testing.T) { defer tc.cleanup() // 1. Create template with external volume and a mock worker pod. - volumes := []*ateapipb.Volume{ + volumes := []*ateapi.Volume{ { Name: "vol1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }, } - mounts := []*ateapipb.VolumeMount{ + mounts := []*ateapi.VolumeMount{ {Name: "vol1", MountPath: "/mnt/vol1"}, } createTemplateWithVolumes(t, tc, ns, volumes, mounts) createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") // 2. Create and resume actor to ACTOR_STATE_RUNNING. - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "suspend-detach-retry-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "suspend-detach-retry-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "suspend-detach-retry-actor"}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "suspend-detach-retry-actor"}, }) if err != nil { t.Fatalf("ResumeActor failed: %v", err) } // 3. Attempt 1: SuspendActor fails on DetachVolume. - _, err = tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "suspend-detach-retry-actor"}, + _, err = tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "suspend-detach-retry-actor"}, }) if err == nil { t.Fatalf("expected first SuspendActor to fail, got nil") @@ -2726,13 +2726,13 @@ func TestSuspendActor_VolumeDetachFailure_RetrySuccess(t *testing.T) { } // 4. Verify actor state after failed detach: left in ACTOR_STATE_SUSPENDING, worker assignment preserved. - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "suspend-detach-retry-actor"}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "suspend-detach-retry-actor"}, }) if err != nil { t.Fatalf("GetActor after failed detach: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDING { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDING { t.Errorf("actor state = %v, want ACTOR_STATE_SUSPENDING", getResp.GetStatus().GetState()) } if getResp.GetStatus().GetWorkerAssignment() == nil || getResp.GetStatus().GetWorkerAssignment().GetWorkerPod() != "worker-1" { @@ -2740,21 +2740,21 @@ func TestSuspendActor_VolumeDetachFailure_RetrySuccess(t *testing.T) { } // 5. Attempt 2 (retry): SuspendActor retry succeeds, volume is detached. - _, err = tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "suspend-detach-retry-actor"}, + _, err = tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "suspend-detach-retry-actor"}, }) if err != nil { t.Fatalf("expected retry SuspendActor to succeed, got: %v", err) } // 6. Verify actor state transitions to ACTOR_STATE_SUSPENDED and worker is released. - getResp, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "suspend-detach-retry-actor"}, + getResp, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "suspend-detach-retry-actor"}, }) if err != nil { t.Fatalf("GetActor after successful suspend retry: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("actor state = %v, want ACTOR_STATE_SUSPENDED", getResp.GetStatus().GetState()) } if getResp.GetStatus().GetWorkerAssignment() != nil && getResp.GetStatus().GetWorkerAssignment().GetWorkerPod() != "" { @@ -2762,8 +2762,8 @@ func TestSuspendActor_VolumeDetachFailure_RetrySuccess(t *testing.T) { } // 7. Clean up by deleting actor. - _, err = tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "suspend-detach-retry-actor"}, + _, err = tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "suspend-detach-retry-actor"}, }) if err != nil { t.Fatalf("DeleteActor failed: %v", err) @@ -2791,53 +2791,53 @@ func TestSuspendActor_VolumeDetachFailure_DeleteActor(t *testing.T) { defer tc.cleanup() // 1. Create template with external volume and a mock worker pod. - volumes := []*ateapipb.Volume{ + volumes := []*ateapi.Volume{ { Name: "vol1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }, } - mounts := []*ateapipb.VolumeMount{ + mounts := []*ateapi.VolumeMount{ {Name: "vol1", MountPath: "/mnt/vol1"}, } createTemplateWithVolumes(t, tc, ns, volumes, mounts) createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") // 2. Create and resume actor to ACTOR_STATE_RUNNING. - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "suspend-del-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "suspend-del-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "suspend-del-actor"}, + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "suspend-del-actor"}, }); err != nil { t.Fatalf("ResumeActor failed: %v", err) } // 3. Attempt SuspendActor; fails on volume detachment, leaving actor in ACTOR_STATE_SUSPENDING. - _, err = tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "suspend-del-actor"}, + _, err = tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "suspend-del-actor"}, }) if err == nil { t.Fatalf("expected SuspendActor to fail, got nil") } - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "suspend-del-actor"}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "suspend-del-actor"}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDING { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDING { t.Fatalf("actor state = %v, want ACTOR_STATE_SUSPENDING", getResp.GetStatus().GetState()) } @@ -2846,16 +2846,16 @@ func TestSuspendActor_VolumeDetachFailure_DeleteActor(t *testing.T) { plugin.failUntil = 0 plugin.mu.Unlock() - _, err = tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "suspend-del-actor"}, + _, err = tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "suspend-del-actor"}, }) if err != nil { t.Fatalf("DeleteActor failed: %v", err) } // 5. Verify actor is NotFound. - _, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "suspend-del-actor"}, + _, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "suspend-del-actor"}, }) if status.Code(err) != codes.NotFound { t.Errorf("GetActor after delete err = %v, want NotFound", err) @@ -2882,26 +2882,26 @@ func TestSuspendActorAsync_VolumeLifecycle_DetachResumeAndMigrate(t *testing.T) defer tc.cleanup() // 1. Create template with external volume and a mock worker pod. - volumes := []*ateapipb.Volume{ + volumes := []*ateapi.Volume{ { Name: "vol1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }, } - mounts := []*ateapipb.VolumeMount{ + mounts := []*ateapi.VolumeMount{ {Name: "vol1", MountPath: "/mnt/vol1"}, } createTemplateWithVolumes(t, tc, ns, volumes, mounts) workerName := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") // 2. Create actor and resume to RUNNING; volume is attached to node1. - createResp, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "pause-vol-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + createResp, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "pause-vol-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }) if err != nil { @@ -2909,8 +2909,8 @@ func TestSuspendActorAsync_VolumeLifecycle_DetachResumeAndMigrate(t *testing.T) } actorUID := createResp.GetMetadata().GetUid() - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, }) if err != nil { t.Fatalf("ResumeActor failed: %v", err) @@ -2925,21 +2925,21 @@ func TestSuspendActorAsync_VolumeLifecycle_DetachResumeAndMigrate(t *testing.T) } // 3. Async SuspendActor: volume is detached from node1 and actor transitions to ACTOR_STATE_SUSPENDED with a local snapshot. - _, err = tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + _, err = tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("actor state = %v, want ACTOR_STATE_SUSPENDED", getResp.GetStatus().GetState()) } if localSnapshot(getResp.GetStatus()) == nil { @@ -2954,20 +2954,20 @@ func TestSuspendActorAsync_VolumeLifecycle_DetachResumeAndMigrate(t *testing.T) // 4. ResumeActor from local snapshot: volume is re-attached to node1 and actor transitions to ACTOR_STATE_RUNNING. tc.fakeAtelet.Reset() - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, }) if err != nil { t.Fatalf("ResumeActor from pause failed: %v", err) } - getResp, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, + getResp, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, }) if err != nil { t.Fatalf("GetActor after second resume: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("actor state after retry = %v, want ACTOR_STATE_RUNNING", getResp.GetStatus().GetState()) } plugin.mu.Lock() @@ -2981,9 +2981,9 @@ func TestSuspendActorAsync_VolumeLifecycle_DetachResumeAndMigrate(t *testing.T) } // 5. Suspend to detach from node1 and clear local snapshot, then migrate to node2. - _, err = tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + _, err = tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }) if err != nil { t.Fatalf("SuspendActor before migration failed: %v", err) @@ -2999,8 +2999,8 @@ func TestSuspendActorAsync_VolumeLifecycle_DetachResumeAndMigrate(t *testing.T) deleteWorkerPod(t, tc, ns, "worker-1") tc.fakeAtelet.Reset() - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, }) if err != nil { t.Fatalf("ResumeActor on migration failed: %v", err) @@ -3015,9 +3015,9 @@ func TestSuspendActorAsync_VolumeLifecycle_DetachResumeAndMigrate(t *testing.T) } // 6. Suspend and delete the actor on node2. - _, err = tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + _, err = tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }) if err != nil { t.Fatalf("SuspendActor after migration failed: %v", err) @@ -3028,8 +3028,8 @@ func TestSuspendActorAsync_VolumeLifecycle_DetachResumeAndMigrate(t *testing.T) } plugin.mu.Unlock() - _, err = tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, + _, err = tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-vol-actor"}, }) if err != nil { t.Fatalf("DeleteActor failed: %v", err) @@ -3072,42 +3072,42 @@ func TestSuspendActorAsync_VolumeDetachFailure_RetrySuccess(t *testing.T) { defer tc.cleanup() // 1. Create template with external volume and a mock worker pod. - volumes := []*ateapipb.Volume{ + volumes := []*ateapi.Volume{ { Name: "vol1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }, } - mounts := []*ateapipb.VolumeMount{ + mounts := []*ateapi.VolumeMount{ {Name: "vol1", MountPath: "/mnt/vol1"}, } createTemplateWithVolumes(t, tc, ns, volumes, mounts) createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") // 2. Create and resume actor to ACTOR_STATE_RUNNING. - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "pause-detach-retry-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "pause-detach-retry-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-detach-retry-actor"}, + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-detach-retry-actor"}, }); err != nil { t.Fatalf("ResumeActor failed: %v", err) } // 3. Attempt 1: async SuspendActor fails on DetachVolume. - _, err = tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-detach-retry-actor"}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + _, err = tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-detach-retry-actor"}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }) if err == nil { t.Fatalf("expected first async SuspendActor to fail, got nil") @@ -3117,33 +3117,33 @@ func TestSuspendActorAsync_VolumeDetachFailure_RetrySuccess(t *testing.T) { } // 4. Verify actor state is ACTOR_STATE_SUSPENDING. - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-detach-retry-actor"}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-detach-retry-actor"}, }) if err != nil { t.Fatalf("GetActor after failed pause: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDING { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDING { t.Errorf("actor state = %v, want ACTOR_STATE_SUSPENDING", getResp.GetStatus().GetState()) } // 5. Attempt 2 (retry): async SuspendActor retry succeeds, detaching volume. - _, err = tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-detach-retry-actor"}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + _, err = tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-detach-retry-actor"}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }) if err != nil { t.Fatalf("expected retry async SuspendActor to succeed, got: %v", err) } // 6. Verify actor state transitions to ACTOR_STATE_SUSPENDED with a local snapshot. - getResp, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-detach-retry-actor"}, + getResp, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-detach-retry-actor"}, }) if err != nil { t.Fatalf("GetActor after successful pause retry: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("actor state = %v, want ACTOR_STATE_SUSPENDED", getResp.GetStatus().GetState()) } if localSnapshot(getResp.GetStatus()) == nil { @@ -3151,8 +3151,8 @@ func TestSuspendActorAsync_VolumeDetachFailure_RetrySuccess(t *testing.T) { } // 7. Clean up by deleting the actor. - _, err = tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "pause-detach-retry-actor"}, + _, err = tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "pause-detach-retry-actor"}, }) if err != nil { t.Fatalf("DeleteActor failed: %v", err) @@ -3179,16 +3179,16 @@ func TestResumeActor(t *testing.T) { podUID := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") name := "id1" - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("ResumeActor failed: %v", err) @@ -3198,24 +3198,24 @@ func TestResumeActor(t *testing.T) { t.Errorf("expected Restore to be called") } - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) } - want := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: name, Atespace: testAtespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, + want := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: name, Atespace: testAtespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, AssignedNode: "node1", LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)), + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)), }, - WorkerAssignment: &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: podUID}, + WorkerAssignment: &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: podUID}, WorkerNamespace: ns, WorkerPool: "pool1", WorkerPod: "worker-1", @@ -3232,11 +3232,11 @@ func TestResumeActor(t *testing.T) { } // Verify that the worker record also has the assigned actor details - listWorkersResp, err := tc.client.ListWorkers(context.Background(), &ateapipb.ListWorkersRequest{}) + listWorkersResp, err := tc.client.ListWorkers(context.Background(), &ateapi.ListWorkersRequest{}) if err != nil { t.Fatalf("ListWorkers failed: %v", err) } - var actorWorker *ateapipb.Worker + var actorWorker *ateapi.Worker for _, w := range listWorkersResp.GetWorkers() { if w.GetWorkerNamespace() == ns && w.GetWorkerPod() == "worker-1" { actorWorker = w @@ -3247,23 +3247,23 @@ func TestResumeActor(t *testing.T) { t.Fatalf("expected worker-1 in namespace %s not found in ListWorkers", ns) } - wantWorker := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: podUID}, + wantWorker := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: podUID}, WorkerNamespace: ns, WorkerPool: "pool1", WorkerPod: "worker-1", WorkerPodUid: podUID, NodeName: "node1", Labels: map[string]string{poolLabelKey: ns}, - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, RegisteredEpoch: reportedEpoch, Ips: []string{"127.0.0.1"}, // Only the ceiling the worker reported. - Capacity: &ateapipb.WorkerResources{Actors: 1, CpuMillicores: 1000, MemoryBytes: 512 << 20}, + Capacity: &ateapi.WorkerResources{Actors: 1, CpuMillicores: 1000, MemoryBytes: 512 << 20}, // All a listing reports of the assignments: one actor and the // compute its template declares. - Allocated: &ateapipb.WorkerResources{Actors: 1, CpuMillicores: 1000, MemoryBytes: 512 << 20}, + Allocated: &ateapi.WorkerResources{Actors: 1, CpuMillicores: 1000, MemoryBytes: 512 << 20}, SandboxClasses: workerSandboxClasses(defaultWorkerRuntime("gvisor")), }, } @@ -3278,12 +3278,12 @@ func TestResumeActorPassesLiteralEnv(t *testing.T) { tc := setupTest(t, ns) defer tc.cleanup() - createTemplateWithContainers(t, tc, ns, []*ateapipb.Container{ + createTemplateWithContainers(t, tc, ns, []*ateapi.Container{ { Name: "main", Image: "main@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", Command: []string{"/main"}, - Env: []*ateapipb.EnvVar{ + Env: []*ateapi.EnvVar{ { Name: "LITERAL", Value: "plain", @@ -3293,15 +3293,15 @@ func TestResumeActorPassesLiteralEnv(t *testing.T) { }) createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"}, }) if err != nil { t.Fatalf("ResumeActor failed: %v", err) @@ -3329,29 +3329,29 @@ func TestResumeActorPassesLiteralEnv(t *testing.T) { // createDataFidelityTemplate creates "tmpl1" like createTemplate, but with // preferredFidelity DATA, so a resumed-after-suspend actor restores from a DATA // snapshot while the template also has a golden snapshot. -func createDataFidelityTemplate(t *testing.T, tc *testContext, ns string) *ateapipb.ActorTemplate { +func createDataFidelityTemplate(t *testing.T, tc *testContext, ns string) *ateapi.ActorTemplate { t.Helper() createWorkerPool(t, tc, ns, "pool1", map[string]string{poolLabelKey: ns}) - created, err := tc.client.CreateActorTemplate(context.Background(), &ateapipb.CreateActorTemplateRequest{ - ActorTemplate: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{ + created, err := tc.client.CreateActorTemplate(context.Background(), &ateapi.CreateActorTemplateRequest{ + ActorTemplate: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{ Atespace: testAtespace, Name: "tmpl1", }, - SnapshotConfig: &ateapipb.SnapshotConfig{ + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: testStorageLocation, - PreferredFidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, + PreferredFidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, }, - Containers: []*ateapipb.Container{{ + Containers: []*ateapi.Container{{ Name: "main", Image: "main@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", Command: []string{"/main"}, }}, - WorkerSelector: &ateapipb.Selector{ + WorkerSelector: &ateapi.Selector{ MatchLabels: map[string]string{poolLabelKey: ns}, }, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, }, }) if err != nil { @@ -3360,12 +3360,12 @@ func createDataFidelityTemplate(t *testing.T, tc *testContext, ns string) *ateap // Publish the golden snapshot as a tag and point the template at it, as // createTemplateWithContainersAndVolumes does. - tag, err := tc.persistence.CreateTag(context.Background(), &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: created.GetMetadata().GetUid()}, - SourceActor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: created.GetMetadata().GetUid()}, - Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED, - Status: &ateapipb.TagStatus{ - Snapshot: newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, created.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)), + tag, err := tc.persistence.CreateTag(context.Background(), &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: created.GetMetadata().GetUid()}, + SourceActor: &ateapi.ObjectRef{Atespace: testAtespace, Name: created.GetMetadata().GetUid()}, + Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED, + Status: &ateapi.TagStatus{ + Snapshot: newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, created.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)), ActorTemplateUid: created.GetMetadata().GetUid(), }, }) @@ -3374,9 +3374,9 @@ func createDataFidelityTemplate(t *testing.T, tc *testContext, ns string) *ateap } updated, err := tc.persistence.UpdateActorTemplate(context.Background(), resources.ActorTemplateRefFromActorTemplate(created), store.PreconditionFrom(created), - func(dbTemplate *ateapipb.ActorTemplate) error { - dbTemplate.Status = &ateapipb.ActorTemplateStatus{ - GoldenSnapshotStatus: &ateapipb.GoldenSnapshotStatus{ + func(dbTemplate *ateapi.ActorTemplate) error { + dbTemplate.Status = &ateapi.ActorTemplateStatus{ + GoldenSnapshotStatus: &ateapi.GoldenSnapshotStatus{ GoldenTag: resources.TagRefFromTag(tag).ToObjectRef(), }, } @@ -3400,20 +3400,20 @@ func TestResumeActor_DataSnapshotIgnoresGolden(t *testing.T) { workerName := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") const name = "id1" - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: name} - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: name} + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } // First resume runs fresh from the golden; the suspend then commits a // DATA snapshot per preferredFidelity. - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor (first) failed: %v", err) } - suspended, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + suspended, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } @@ -3424,7 +3424,7 @@ func TestResumeActor_DataSnapshotIgnoresGolden(t *testing.T) { } // Second resume restores the actor's DATA snapshot on its own. - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor (second) failed: %v", err) } restoreReq := tc.fakeAtelet.lastRestoreRequest() @@ -3458,20 +3458,20 @@ func TestSuspendActor_ReplacedSnapshotReleaseFailure(t *testing.T) { workerName := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") const name = "id1" - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: name} - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: name} + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } // A first suspend gives the actor an external snapshot of its own for the // second one to replace. - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor (first) failed: %v", err) } - first, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + first, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatalf("SuspendActor (first) failed: %v", err) } @@ -3479,19 +3479,19 @@ func TestSuspendActor_ReplacedSnapshotReleaseFailure(t *testing.T) { replacedURI := durableSnapshotURI(first.GetActor().GetStatus()) assertSnapshotOwnedByActor(t, first.GetActor(), replacedURI) - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor (second) failed: %v", err) } tc.objectStore.OnDelete = func(string, string) error { return status.Error(codes.Unavailable, "object storage is unavailable") } - second, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + second, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) tc.objectStore.OnDelete = nil if err != nil { t.Fatalf("SuspendActor (second) failed: %v", err) } waitForWorkerAvailable(t, tc, workerName) - if got := second.GetActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := second.GetActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state after the second suspend = %v, want SUSPENDED", got) } freshURI := durableSnapshotURI(second.GetActor().GetStatus()) @@ -3501,7 +3501,7 @@ func TestSuspendActor_ReplacedSnapshotReleaseFailure(t *testing.T) { assertSnapshotPresent(t, tc, freshURI) assertSnapshotPresent(t, tc, replacedURI) - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor after the release failure failed: %v", err) } if got := tc.fakeAtelet.lastRestoreRequest().GetSnapshot().GetObject().GetSnapshotUri(); got != freshURI { @@ -3511,7 +3511,7 @@ func TestSuspendActor_ReplacedSnapshotReleaseFailure(t *testing.T) { // A later suspend releases only the snapshot it replaces; the one the // failed release left behind stays until the actor is deleted, which // collects everything under the actor's prefix. - third, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + third, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatalf("SuspendActor (third) failed: %v", err) } @@ -3520,7 +3520,7 @@ func TestSuspendActor_ReplacedSnapshotReleaseFailure(t *testing.T) { assertSnapshotCollected(t, tc, freshURI) assertSnapshotPresent(t, tc, replacedURI) - if _, err := tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{Actor: actorRef}); err != nil { t.Fatalf("DeleteActor failed: %v", err) } assertSnapshotCollected(t, tc, replacedURI) @@ -3540,9 +3540,9 @@ func TestResumeActor_NoWorkers(t *testing.T) { createTemplate(t, tc, ns) - createResp, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + createResp, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) @@ -3550,8 +3550,8 @@ func TestResumeActor_NoWorkers(t *testing.T) { name := createResp.GetMetadata().GetName() - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) assertGrpcError(t, err, codes.ResourceExhausted, "no worker has room for the actor") } @@ -3566,17 +3566,17 @@ func TestResumeActor_MultiPoolSelector(t *testing.T) { createWorkerPool(t, tc, ns, "pool-a", map[string]string{"group": ns, "tier": "a"}) createWorkerPool(t, tc, ns, "pool-b", map[string]string{"group": ns, "tier": "b"}) - createTemplateWithSelector(t, tc, "tmpl1", &ateapipb.Selector{ + createTemplateWithSelector(t, tc, "tmpl1", &ateapi.Selector{ MatchLabels: map[string]string{"group": ns}, }) createWorkerPod(t, tc, ns, "worker-a", "node1", "pool-a") createWorkerPod(t, tc, ns, "worker-b", "node1", "pool-b") - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - WorkerSelector: &ateapipb.Selector{ + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + WorkerSelector: &ateapi.Selector{ MatchLabels: map[string]string{"tier": "b"}, }, }}) @@ -3584,12 +3584,12 @@ func TestResumeActor_MultiPoolSelector(t *testing.T) { t.Fatalf("CreateActor failed: %v", err) } - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"}}) + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"}}) if err != nil { t.Fatalf("ResumeActor failed: %v", err) } - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"}}) + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"}}) if err != nil { t.Fatalf("GetActor failed: %v", err) } @@ -3615,7 +3615,7 @@ func TestResumeActor_RequiresBothSelectorsToMatch(t *testing.T) { createWorkerPool(t, tc, ns, "pool-both", map[string]string{"group": ns, "tier": "b"}) createWorkerPool(t, tc, ns, "pool-template-only", map[string]string{"group": ns, "tier": "a"}) createWorkerPool(t, tc, ns, "pool-actor-only", map[string]string{"tier": "b"}) - createTemplateWithSelector(t, tc, "tmpl1", &ateapipb.Selector{ + createTemplateWithSelector(t, tc, "tmpl1", &ateapi.Selector{ MatchLabels: map[string]string{"group": ns}, }) @@ -3623,10 +3623,10 @@ func TestResumeActor_RequiresBothSelectorsToMatch(t *testing.T) { createWorkerPod(t, tc, ns, "worker-template-only", "node1", "pool-template-only") createWorkerPod(t, tc, ns, "worker-actor-only", "node1", "pool-actor-only") - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - WorkerSelector: &ateapipb.Selector{ + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + WorkerSelector: &ateapi.Selector{ MatchLabels: map[string]string{"tier": "b"}, }, }}) @@ -3634,11 +3634,11 @@ func TestResumeActor_RequiresBothSelectorsToMatch(t *testing.T) { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"}}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"}}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"}}) + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"}}) if err != nil { t.Fatalf("GetActor failed: %v", err) } @@ -3660,9 +3660,9 @@ func TestResumeActor_AteletFailureCrashesActor(t *testing.T) { podUID := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") name := "id1" - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) @@ -3670,8 +3670,8 @@ func TestResumeActor_AteletFailureCrashesActor(t *testing.T) { // STEP 1: Make Atelet FAIL on Restore! tc.fakeAtelet.FailRestore = status.Error(codes.Internal, "mock atelet failure") - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err == nil { t.Fatal("expected ResumeActor to fail due to atelet error") @@ -3686,7 +3686,7 @@ func TestResumeActor_AteletFailureCrashesActor(t *testing.T) { if err != nil { t.Fatalf("failed to get actor from store: %v", err) } - if actor.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if actor.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("expected state CRASHED, got %v", actor.GetStatus().GetState()) } if actor.GetStatus().GetWorkerAssignment() != nil { @@ -3729,11 +3729,11 @@ func TestResumeActor_AteletTransportErrorLeavesActorResuming(t *testing.T) { podUID := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") name := "id1" - ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: name} + ref := &ateapi.ObjectRef{Atespace: testAtespace, Name: name} actorRef := resources.ActorRef{Atespace: testAtespace, Name: name} - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } @@ -3746,7 +3746,7 @@ func TestResumeActor_AteletTransportErrorLeavesActorResuming(t *testing.T) { ctx, cancel = context.WithTimeout(ctx, tt.deadline) defer cancel() } - _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}) + _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}) if got := status.Code(err); got != tt.wantCode { t.Fatalf("ResumeActor status code = %v, want %v (err: %v)", got, tt.wantCode, err) } @@ -3755,7 +3755,7 @@ func TestResumeActor_AteletTransportErrorLeavesActorResuming(t *testing.T) { if err != nil { t.Fatalf("failed to get actor from store: %v", err) } - if got := actor.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RESUMING { + if got := actor.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RESUMING { t.Fatalf("state after %s = %v, want RESUMING", tt.name, got) } if crash := actor.GetStatus().GetCrash(); crash != nil { @@ -3770,14 +3770,14 @@ func TestResumeActor_AteletTransportErrorLeavesActorResuming(t *testing.T) { tc.fakeAtelet.FailRestore = nil tc.fakeAtelet.RestoreDelay = 0 tc.fakeAtelet.Lock.Unlock() - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("retried ResumeActor failed: %v", err) } actor, err = tc.persistence.GetActor(context.Background(), actorRef) if err != nil { t.Fatalf("failed to get actor from store: %v", err) } - if got := actor.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := actor.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("state after retry = %v, want RUNNING", got) } if got := actor.GetStatus().GetWorkerAssignment().GetWorker().GetName(); got != podUID { @@ -3798,17 +3798,17 @@ func TestResumeActor_LocalRestoreFailureCrashesActor(t *testing.T) { podUID := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") name := "id1" - ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: name} - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + ref := &ateapi.ObjectRef{Atespace: testAtespace, Name: name} + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } - pauseResp, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: ref, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}) + pauseResp, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: ref, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } @@ -3819,18 +3819,18 @@ func TestResumeActor_LocalRestoreFailureCrashesActor(t *testing.T) { tc.fakeAtelet.Reset() tc.fakeAtelet.FailRestore = status.Error(codes.Internal, "injected restore failure") - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: ref}); status.Code(err) != codes.Internal { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: ref}); status.Code(err) != codes.Internal { t.Fatalf("ResumeActor status code = %v, want Internal (err: %v)", status.Code(err), err) } if got := tc.fakeAtelet.RestoreRequest.GetSnapshot(); got.GetSnapshotUuid() != paused.GetUuid() || got.GetObject().GetSnapshotUri() != paused.GetDurableSnapshot().GetObject().GetSnapshotUri() { t.Fatalf("restore snapshot = %v, want the local snapshot %v, naming its upload", got, paused) } - actor, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: ref}) + actor, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: ref}) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if actor.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if actor.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Fatalf("state after failed restore = %v, want CRASHED", actor.GetStatus().GetState()) } if actor.GetStatus().GetWorkerAssignment() != nil { @@ -3855,8 +3855,8 @@ func TestResumeActor_ErrorStillStampsRefSpanIdentity(t *testing.T) { defer tc.cleanup() attrs := recordRootSpanAttrs(t, func(ctx context.Context) { - if _, err := tc.service.ResumeActor(ctx, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "missing"}, + if _, err := tc.service.ResumeActor(ctx, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "missing"}, }); err == nil { t.Fatal("expected error resuming missing actor") } @@ -3886,26 +3886,26 @@ func TestSuspendActor(t *testing.T) { workerName := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") name := "id1" - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) } // Resume first to make it running - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("ResumeActor failed: %v", err) } // Suspend - suspended, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + suspended, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }) if err != nil { t.Fatalf("SuspendActor failed: %v", err) @@ -3927,12 +3927,12 @@ func TestSuspendActor(t *testing.T) { // Tagging is a separate call over whatever snapshot the Actor holds by then, // which here is the one the suspend above left behind. const tagName = "before-upgrade" - tagRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: tagName} - tagged, err := tc.client.CreateTag(context.Background(), &ateapipb.CreateTagRequest{ - Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: tagName}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - SourceActor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + tagRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: tagName} + tagged, err := tc.client.CreateTag(context.Background(), &ateapi.CreateTagRequest{ + Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: tagName}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + SourceActor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }, }) if err != nil { @@ -3948,25 +3948,25 @@ func TestSuspendActor(t *testing.T) { assertSnapshotPresent(t, tc, snapshotURI) assertSnapshotPresent(t, tc, taggedSnapshotURI) - wantTagSnap := newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, durableSnapshot(sourceActor.GetStatus()).GetFidelity(), "", snapshotName(t, taggedSnapshotURI), taggedSnapshotURI) + wantTagSnap := newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, durableSnapshot(sourceActor.GetStatus()).GetFidelity(), "", snapshotName(t, taggedSnapshotURI), taggedSnapshotURI) wantTagSnap.SandboxRuntime = defaultWorkerRuntime("gvisor") - wantTag := &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: tagName}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - SourceActor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, - Status: &ateapipb.TagStatus{ + wantTag := &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: tagName}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + SourceActor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, + Status: &ateapi.TagStatus{ Snapshot: wantTagSnap, ActorTemplateUid: tmpl.GetMetadata().GetUid(), }, } - stored, err := tc.client.GetTag(context.Background(), &ateapipb.GetTagRequest{Tag: tagRef}) + stored, err := tc.client.GetTag(context.Background(), &ateapi.GetTagRequest{Tag: tagRef}) if err != nil { t.Fatalf("GetTag failed: %v", err) } if diff := cmp.Diff(wantTag, stored, protocmp.Transform(), ignoreUID, ignoreVersion, ignoreTimestamps); diff != "" { t.Errorf("stored tag mismatch (-want +got):\n%s", diff) } - listed, err := tc.client.ListTags(context.Background(), &ateapipb.ListTagsRequest{Atespace: testAtespace, Options: &ateapipb.ListOptions{PageSize: 1}}) + listed, err := tc.client.ListTags(context.Background(), &ateapi.ListTagsRequest{Atespace: testAtespace, Options: &ateapi.ListOptions{PageSize: 1}}) if err != nil || len(listed.GetTags()) != 1 { t.Fatalf("ListTags = (%v, %v), want one", listed, err) } @@ -3974,21 +3974,21 @@ func TestSuspendActor(t *testing.T) { // A tag is born ATESPACE-scoped, so it cannot seed an Actor elsewhere until // it is published. createAtespace(t, tc, "other") - crossAtespaceClone := &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "other", Name: "cross-atespace"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + crossAtespaceClone := &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "other", Name: "cross-atespace"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, SourceTag: tagRef, }, } if _, err := tc.client.CreateActor(context.Background(), crossAtespaceClone); status.Code(err) != codes.FailedPrecondition { t.Fatalf("cross-atespace CreateActor status = %v, want FailedPrecondition", status.Code(err)) } - tagged.Scope = ateapipb.TagScope_TAG_SCOPE_PUBLISHED - updated, err := tc.client.UpdateTag(context.Background(), &ateapipb.UpdateTagRequest{ + tagged.Scope = ateapi.TagScope_TAG_SCOPE_PUBLISHED + updated, err := tc.client.UpdateTag(context.Background(), &ateapi.UpdateTagRequest{ Tag: tagged, }) - if err != nil || updated.GetScope() != ateapipb.TagScope_TAG_SCOPE_PUBLISHED { + if err != nil || updated.GetScope() != ateapi.TagScope_TAG_SCOPE_PUBLISHED { t.Fatalf("UpdateTag = (%v, %v), want published", updated, err) } if tagSnapshotURI(updated) != taggedSnapshotURI { @@ -4001,10 +4001,10 @@ func TestSuspendActor(t *testing.T) { // A clone borrows the tag's external snapshot rather than copying it. The // snapshot stays under the tag's prefix, which is what keeps the clone's own // lifecycle from ever releasing it. - clone, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "clone"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + clone, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "clone"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, SourceTag: tagRef, }, }) @@ -4020,7 +4020,7 @@ func TestSuspendActor(t *testing.T) { if !proto.Equal(clone.GetSourceTag(), tagRef) { t.Errorf("clone source tag = %v, want %v", clone.GetSourceTag(), tagRef) } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "clone"}}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "clone"}}); err != nil { t.Fatalf("ResumeActor clone failed: %v", err) } if !tc.fakeAtelet.RestoreCalled { @@ -4029,7 +4029,7 @@ func TestSuspendActor(t *testing.T) { // The clone's first suspend writes a snapshot of its own and stops // borrowing, which is what makes the tag's snapshot collectable later. - cloneSuspended, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "clone"}, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + cloneSuspended, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "clone"}, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatalf("SuspendActor clone failed: %v", err) } @@ -4042,7 +4042,7 @@ func TestSuspendActor(t *testing.T) { assertSnapshotPresent(t, tc, taggedSnapshotURI) assertSnapshotPresent(t, tc, cloneSnapshotURI) // The untagged suspend created no tag: only the golden and explicit tag remain. - listed, err = tc.client.ListTags(context.Background(), &ateapipb.ListTagsRequest{Atespace: testAtespace}) + listed, err = tc.client.ListTags(context.Background(), &ateapi.ListTagsRequest{Atespace: testAtespace}) if err != nil || len(listed.GetTags()) != 2 { t.Fatalf("ListTags after clone suspension = (%v, %v), want golden and explicit tags", listed, err) } @@ -4052,21 +4052,21 @@ func TestSuspendActor(t *testing.T) { } } - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) } - wantActorSnap := newDurableSnapshot(2, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, durableSnapshot(sourceActor.GetStatus()).GetFidelity(), tmpl.GetMetadata().GetUid(), snapshotName(t, snapshotURI), snapshotURI) + wantActorSnap := newDurableSnapshot(2, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, durableSnapshot(sourceActor.GetStatus()).GetFidelity(), tmpl.GetMetadata().GetUid(), snapshotName(t, snapshotURI), snapshotURI) wantActorSnap.SandboxRuntime = defaultWorkerRuntime("gvisor") - want := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: name, Atespace: testAtespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + want := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: name, Atespace: testAtespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, LastAssignedGeneration: 2, - Snapshots: []*ateapipb.Snapshot{ + Snapshots: []*ateapi.Snapshot{ wantActorSnap, }, }, @@ -4082,20 +4082,20 @@ func TestSuspendActor(t *testing.T) { } // The tag outlives the Actor it was taken from: it holds the snapshot on its // own, and deleting it is what ends that snapshot's life. - if _, err := tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}}); err != nil { + if _, err := tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}}); err != nil { t.Fatalf("DeleteActor source failed: %v", err) } - if _, err := tc.client.GetTag(context.Background(), &ateapipb.GetTagRequest{Tag: tagRef}); err != nil { + if _, err := tc.client.GetTag(context.Background(), &ateapi.GetTagRequest{Tag: tagRef}); err != nil { t.Fatalf("source tag disappeared with source Actor: %v", err) } // The Actor took only what it owned with it. assertSnapshotCollected(t, tc, snapshotURI) assertSnapshotPresent(t, tc, taggedSnapshotURI) - if deleted, err := tc.client.DeleteTag(context.Background(), &ateapipb.DeleteTagRequest{Tag: tagRef}); err != nil || deleted.GetMetadata().GetName() != tagRef.GetName() { + if deleted, err := tc.client.DeleteTag(context.Background(), &ateapi.DeleteTagRequest{Tag: tagRef}); err != nil || deleted.GetMetadata().GetName() != tagRef.GetName() { t.Fatalf("DeleteTag = (%v, %v)", deleted, err) } - if _, err := tc.client.GetTag(context.Background(), &ateapipb.GetTagRequest{Tag: tagRef}); status.Code(err) != codes.NotFound { + if _, err := tc.client.GetTag(context.Background(), &ateapi.GetTagRequest{Tag: tagRef}); status.Code(err) != codes.NotFound { t.Fatalf("deleted tag status = %v, want NotFound", status.Code(err)) } // Deleting the tag is what ends its snapshot's life. The clone that @@ -4169,9 +4169,9 @@ func TestResumeActor_SyncSuspendKeepsLocalCopy(t *testing.T) { tmpl := createTemplate(t, tc, ns) if tt.repoint { replacement := proto.CloneOf(tmpl) - replacement.Metadata = &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "tmpl2"} + replacement.Metadata = &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "tmpl2"} replacement.Status = nil - if _, err := tc.client.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ActorTemplate: replacement}); err != nil { + if _, err := tc.client.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ActorTemplate: replacement}); err != nil { t.Fatalf("CreateActorTemplate(tmpl2): %v", err) } } @@ -4180,27 +4180,27 @@ func TestResumeActor_SyncSuspendKeepsLocalCopy(t *testing.T) { tc.fakeAtelet.KeepCheckpointLocal = true tc.fakeAtelet.Lock.Unlock() - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-1"} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: actorRef.GetName()}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-1"} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: actorRef.GetName()}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor: %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("initial ResumeActor: %v", err) } - if _, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ + if _, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{ Actor: actorRef, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }); err != nil { t.Fatalf("sync SuspendActor: %v", err) } - suspended, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actorRef}) + suspended, err := tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("GetActor after suspend: %v", err) } - if got := suspended.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := suspended.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("state after suspend = %v, want SUSPENDED", got) } if got := suspended.GetStatus().GetAssignedNode(); got != "node1" { @@ -4213,7 +4213,7 @@ func TestResumeActor_SyncSuspendKeepsLocalCopy(t *testing.T) { if snap == nil || snap.GetLocality() != "node1" { t.Fatalf("sync snapshot = %v, want its local copy on node1 recorded", snap) } - if got := snap.GetDurableSnapshot().GetStatus(); got != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { + if got := snap.GetDurableSnapshot().GetStatus(); got != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { t.Fatalf("sync snapshot durable status = %v, want COMPLETED", got) } if got := snap.GetActorTemplateUid(); got != tmpl.GetMetadata().GetUid() { @@ -4227,8 +4227,8 @@ func TestResumeActor_SyncSuspendKeepsLocalCopy(t *testing.T) { if tt.repoint { toUpdate := proto.CloneOf(suspended) - toUpdate.ActorTemplate = &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl2"} - updated, err := tc.client.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: toUpdate}) + toUpdate.ActorTemplate = &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl2"} + updated, err := tc.client.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: toUpdate}) if err != nil { t.Fatalf("UpdateActor with durable local snapshot: %v", err) } @@ -4238,14 +4238,14 @@ func TestResumeActor_SyncSuspendKeepsLocalCopy(t *testing.T) { } if tt.relocate { // Fill node1 so resume must detach before moving to node2. - squatterRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "squatter"} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: squatterRef.GetName()}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + squatterRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "squatter"} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: squatterRef.GetName()}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor(squatter): %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: squatterRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: squatterRef}); err != nil { t.Fatalf("ResumeActor(squatter): %v", err) } createWorkerPod(t, tc, ns, "worker-2", "node2", "pool1") @@ -4253,11 +4253,11 @@ func TestResumeActor_SyncSuspendKeepsLocalCopy(t *testing.T) { } before := resumeKinds() - resumed, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}) + resumed, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("ResumeActor with durable local snapshot: %v", err) } - if got := resumed.GetActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := resumed.GetActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("state after resume = %v, want RUNNING", got) } if got := resumed.GetActor().GetStatus().GetWorkerAssignment().GetNodeName(); got != tt.wantNode { @@ -4350,36 +4350,36 @@ func TestResumeActor_RepointTemplateBeforeResume(t *testing.T) { tmpl := createTemplate(t, tc, ns) // The tmpl2 copies tmpl1 so the repoint clears the sandbox // class and volume compatibility checks; only the name differs. - tmpl2 := proto.Clone(tmpl).(*ateapipb.ActorTemplate) - tmpl2.Metadata = &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "tmpl2"} + tmpl2 := proto.Clone(tmpl).(*ateapi.ActorTemplate) + tmpl2.Metadata = &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "tmpl2"} tmpl2.Status = nil - if _, err := tc.client.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ActorTemplate: tmpl2}); err != nil { + if _, err := tc.client.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ActorTemplate: tmpl2}); err != nil { t.Fatalf("CreateActorTemplate(tmpl2) failed: %v", err) } worker := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") // Run and suspend a source Actor, so we have an external snapshot we can tag const sourceActorName = "source-actor" - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: sourceActorName}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: sourceActorName}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor(%s) failed: %v", sourceActorName, err) } - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: sourceActorName} - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: sourceActorName} + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor(%s) failed: %v", sourceActorName, err) } - if _, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}); err != nil { + if _, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}); err != nil { t.Fatalf("SuspendActor(%s) failed: %v", sourceActorName, err) } waitForWorkerAvailable(t, tc, worker) const tagName = "before-upgrade" - if _, err := tc.client.CreateTag(ctx, &ateapipb.CreateTagRequest{ - Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: tagName}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, + if _, err := tc.client.CreateTag(ctx, &ateapi.CreateTagRequest{ + Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: tagName}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, SourceActor: actorRef, }, }); err != nil { @@ -4387,26 +4387,26 @@ func TestResumeActor_RepointTemplateBeforeResume(t *testing.T) { } const cloneActorName = "clone" - cloneActor, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: cloneActorName}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + cloneActor, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: cloneActorName}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, // Seeded from the tag. - SourceTag: &ateapipb.ObjectRef{Atespace: testAtespace, Name: tagName}, + SourceTag: &ateapi.ObjectRef{Atespace: testAtespace, Name: tagName}, }}) if err != nil { t.Fatalf("CreateActor from tag failed: %v", err) } if tt.moveActorToAnotherTemplate { // Change clonetActor's template - toUpdate := proto.Clone(cloneActor).(*ateapipb.Actor) - toUpdate.ActorTemplate = &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl2"} - if _, err := tc.client.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: toUpdate}); err != nil { + toUpdate := proto.Clone(cloneActor).(*ateapi.Actor) + toUpdate.ActorTemplate = &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl2"} + if _, err := tc.client.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: toUpdate}); err != nil { t.Fatalf("UpdateActor repointing the clone at tmpl2 failed: %v", err) } } - cloneRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: cloneActorName} - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: cloneRef}); err != nil { + cloneRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: cloneActorName} + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: cloneRef}); err != nil { t.Fatalf("ResumeActor(%s) failed: %v", cloneActorName, err) } @@ -4444,48 +4444,48 @@ func TestResumeActor_PausedAfterRepointUsesLocalProvenance(t *testing.T) { ctx := context.Background() tmpl := createTemplate(t, tc, ns) - tmpl2 := proto.Clone(tmpl).(*ateapipb.ActorTemplate) - tmpl2.Metadata = &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "tmpl2"} + tmpl2 := proto.Clone(tmpl).(*ateapi.ActorTemplate) + tmpl2.Metadata = &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "tmpl2"} tmpl2.Status = nil - if _, err := tc.client.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ActorTemplate: tmpl2}); err != nil { + if _, err := tc.client.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ActorTemplate: tmpl2}); err != nil { t.Fatalf("CreateActorTemplate(tmpl2) failed: %v", err) } worker := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") const name = "actor-1" - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: name} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: name} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor(v1) failed: %v", err) } - suspended, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + suspended, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatalf("SuspendActor(v1) failed: %v", err) } waitForWorkerAvailable(t, tc, worker) // Repoint at v2 while suspended; the external snapshot stays on v1. - toUpdate := proto.Clone(suspended.GetActor()).(*ateapipb.Actor) - toUpdate.ActorTemplate = &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl2"} - if _, err := tc.client.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: toUpdate}); err != nil { + toUpdate := proto.Clone(suspended.GetActor()).(*ateapi.Actor) + toUpdate.ActorTemplate = &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl2"} + if _, err := tc.client.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: toUpdate}); err != nil { t.Fatalf("UpdateActor(tmpl2) failed: %v", err) } // Resume on v2 (this restore is DATA, from the v1 external snapshot), then // suspend asynchronously; the local checkpoint is captured on v2 while the // external snapshot still says v1. - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor(v2 from v1 snapshot) failed: %v", err) } if got := tc.fakeAtelet.lastRestoreRequest().GetSnapshot().GetFidelity(); got != ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES { t.Fatalf("first resume on v2 had scope = %v, want DATA", got) } - pauseResp, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}) + pauseResp, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } @@ -4497,7 +4497,7 @@ func TestResumeActor_PausedAfterRepointUsesLocalProvenance(t *testing.T) { // Resume from local snapshot: the local checkpoint was captured on v2 and // the actor's template is v2, so the restore must be FULL. - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor(from v2 pause) failed: %v", err) } restoreReq := tc.fakeAtelet.lastRestoreRequest() @@ -4510,11 +4510,11 @@ func TestResumeActor_PausedAfterRepointUsesLocalProvenance(t *testing.T) { } func TestResumeActor_PausedLocalSnapshotRuntimeFallback(t *testing.T) { - rtA := &ateapipb.ActorSandboxRuntime{ + rtA := &ateapi.ActorSandboxRuntime{ SandboxClass: "gvisor", - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{ + Attributes: []*ateapi.AttributeEntry{ {Key: "architecture", Value: "amd64"}, {Key: "sandbox_bundle_hash", Value: "hash-a"}, }, @@ -4529,7 +4529,7 @@ func TestResumeActor_PausedLocalSnapshotRuntimeFallback(t *testing.T) { failDetach bool wantWorker string wantNode string - wantRuntime *ateapipb.ActorSandboxRuntime + wantRuntime *ateapi.ActorSandboxRuntime wantFidelity ateletpb.SnapshotFidelity }{ { @@ -4567,19 +4567,19 @@ func TestResumeActor_PausedLocalSnapshotRuntimeFallback(t *testing.T) { workerPod := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") reportWorkerRuntime(t, tc, workerPod, rtA) - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-1"} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: actorRef.GetName()}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-1"} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: actorRef.GetName()}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor: %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("initial ResumeActor: %v", err) } - pauseResp, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ + pauseResp, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{ Actor: actorRef, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }) if err != nil { t.Fatalf("SuspendActor: %v", err) @@ -4590,13 +4590,13 @@ func TestResumeActor_PausedLocalSnapshotRuntimeFallback(t *testing.T) { } waitForWorkerAvailable(t, tc, workerPod) - upload := &ateapipb.SnapshotReport{ + upload := &ateapi.SnapshotReport{ Uuid: paused.GetUuid(), Generation: paused.GetGeneration(), Fidelity: paused.GetFidelity(), Object: paused.GetDurableSnapshot().GetObject(), } - if err := tc.service.ApplyActorSnapshotState(ctx, resources.ActorRefFromActor(pauseResp.GetActor()), pauseResp.GetActor().GetMetadata().GetUid(), "node1", &ateapipb.ActorSnapshotState{ + if err := tc.service.ApplyActorSnapshotState(ctx, resources.ActorRefFromActor(pauseResp.GetActor()), pauseResp.GetActor().GetMetadata().GetUid(), "node1", &ateapi.ActorSnapshotState{ LatestLocal: upload, LatestDurable: upload, }); err != nil { @@ -4614,7 +4614,7 @@ func TestResumeActor_PausedLocalSnapshotRuntimeFallback(t *testing.T) { tc.fakeAtelet.Lock.Unlock() } - resumed, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}) + resumed, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("ResumeActor after runtime change: %v", err) } @@ -4656,21 +4656,21 @@ func TestResumeActor_PausedPendingSnapshotRefusesRuntimeFallback(t *testing.T) { ctx := context.Background() createTemplate(t, tc, ns) - rtA := &ateapipb.ActorSandboxRuntime{ + rtA := &ateapi.ActorSandboxRuntime{ SandboxClass: "gvisor", - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{ + Attributes: []*ateapi.AttributeEntry{ {Key: "architecture", Value: "amd64"}, {Key: "sandbox_bundle_hash", Value: "hash-a"}, }, }, } - rtB := &ateapipb.ActorSandboxRuntime{ + rtB := &ateapi.ActorSandboxRuntime{ SandboxClass: "gvisor", - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{ + Attributes: []*ateapi.AttributeEntry{ {Key: "architecture", Value: "amd64"}, {Key: "sandbox_bundle_hash", Value: "hash-b"}, }, @@ -4681,30 +4681,30 @@ func TestResumeActor_PausedPendingSnapshotRefusesRuntimeFallback(t *testing.T) { reportWorkerRuntime(t, tc, workerPod, rtA) const name = "actor-1" - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: name} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: name} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } // Keep an older durable generation beside the pending checkpoint. - if _, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ + if _, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{ Actor: actorRef, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }); err != nil { t.Fatalf("sync SuspendActor failed: %v", err) } waitForWorkerAvailable(t, tc, workerPod) - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor from the durable snapshot failed: %v", err) } - pauseResp, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ + pauseResp, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{ Actor: actorRef, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }) if err != nil { t.Fatalf("pause SuspendActor failed: %v", err) @@ -4713,7 +4713,7 @@ func TestResumeActor_PausedPendingSnapshotRefusesRuntimeFallback(t *testing.T) { if paused == nil { t.Fatalf("pause left no local snapshot: %v", pauseResp.GetActor().GetStatus()) } - if got := paused.GetDurableSnapshot().GetStatus(); got != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING { + if got := paused.GetDurableSnapshot().GetStatus(); got != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING { t.Fatalf("pause checkpoint durable status = %v, want PENDING (not yet uploaded)", got) } durable := durableSnapshot(pauseResp.GetActor().GetStatus()) @@ -4727,7 +4727,7 @@ func TestResumeActor_PausedPendingSnapshotRefusesRuntimeFallback(t *testing.T) { tc.fakeAtelet.Reset() tc.fakeAtelet.FailDetach = status.Error(codes.Unavailable, "checkpoint upload unavailable") - _, err = tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}) + _, err = tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}) assertGrpcError(t, err, codes.Unavailable, "while calling atelet DetachActor: rpc error: code = Unavailable desc = checkpoint upload unavailable") tc.fakeAtelet.Lock.Lock() detachCalled := tc.fakeAtelet.DetachCalled @@ -4743,7 +4743,7 @@ func TestResumeActor_PausedPendingSnapshotRefusesRuntimeFallback(t *testing.T) { if err != nil { t.Fatalf("GetActor: %v", err) } - if got := after.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := after.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state after the refused resume = %v, want SUSPENDED", got) } if got := after.GetStatus().GetWorkerAssignment(); got != nil { @@ -4751,7 +4751,7 @@ func TestResumeActor_PausedPendingSnapshotRefusesRuntimeFallback(t *testing.T) { } stillLocal := localSnapshot(after.GetStatus()) if stillLocal == nil || stillLocal.GetUuid() != paused.GetUuid() || - stillLocal.GetDurableSnapshot().GetStatus() != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING { + stillLocal.GetDurableSnapshot().GetStatus() != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING { t.Errorf("pause checkpoint after the refused resume = %v, want %v still PENDING", stillLocal, paused) } if got := durableSnapshotURI(after.GetStatus()); got != durable.GetDurableSnapshot().GetObject().GetSnapshotUri() { @@ -4767,21 +4767,21 @@ func TestResumeActor_RetryRelaxedPauseAssignmentRestoresSameSnapshot(t *testing. ctx := context.Background() createTemplate(t, tc, ns) - rtA := &ateapipb.ActorSandboxRuntime{ + rtA := &ateapi.ActorSandboxRuntime{ SandboxClass: "gvisor", - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{ + Attributes: []*ateapi.AttributeEntry{ {Key: "architecture", Value: "amd64"}, {Key: "sandbox_bundle_hash", Value: "hash-a"}, }, }, } - rtB := &ateapipb.ActorSandboxRuntime{ + rtB := &ateapi.ActorSandboxRuntime{ SandboxClass: "gvisor", - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{ + Attributes: []*ateapi.AttributeEntry{ {Key: "architecture", Value: "amd64"}, {Key: "sandbox_bundle_hash", Value: "hash-b"}, }, @@ -4792,19 +4792,19 @@ func TestResumeActor_RetryRelaxedPauseAssignmentRestoresSameSnapshot(t *testing. reportWorkerRuntime(t, tc, workerPod, rtA) const name = "actor-1" - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: name} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: name} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } - pauseResp, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ + pauseResp, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{ Actor: actorRef, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }) if err != nil { t.Fatalf("SuspendActor failed: %v", err) @@ -4816,13 +4816,13 @@ func TestResumeActor_RetryRelaxedPauseAssignmentRestoresSameSnapshot(t *testing. waitForWorkerAvailable(t, tc, workerPod) // Finish the upload before changing the worker's runtime. - upload := &ateapipb.SnapshotReport{ + upload := &ateapi.SnapshotReport{ Uuid: paused.GetUuid(), Generation: paused.GetGeneration(), Fidelity: paused.GetFidelity(), Object: paused.GetDurableSnapshot().GetObject(), } - if err := tc.service.ApplyActorSnapshotState(ctx, resources.ActorRefFromActor(pauseResp.GetActor()), pauseResp.GetActor().GetMetadata().GetUid(), "node1", &ateapipb.ActorSnapshotState{ + if err := tc.service.ApplyActorSnapshotState(ctx, resources.ActorRefFromActor(pauseResp.GetActor()), pauseResp.GetActor().GetMetadata().GetUid(), "node1", &ateapi.ActorSnapshotState{ LatestLocal: upload, LatestDurable: upload, }); err != nil { @@ -4834,14 +4834,14 @@ func TestResumeActor_RetryRelaxedPauseAssignmentRestoresSameSnapshot(t *testing. tc.fakeAtelet.Lock.Lock() tc.fakeAtelet.FailRestore = status.Error(codes.Unavailable, "restore reply lost") tc.fakeAtelet.Lock.Unlock() - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); status.Code(err) != codes.Unavailable { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); status.Code(err) != codes.Unavailable { t.Fatalf("first ResumeActor status code = %v, want Unavailable (err: %v)", status.Code(err), err) } interrupted, err := tc.persistence.GetActor(ctx, resources.ActorRefFromActor(pauseResp.GetActor())) if err != nil { t.Fatalf("GetActor after the interrupted resume: %v", err) } - if got := interrupted.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RESUMING { + if got := interrupted.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RESUMING { t.Fatalf("state after the interrupted resume = %v, want RESUMING", got) } if got := interrupted.GetStatus().GetWorkerAssignment().GetWorkerPod(); got != "worker-1" { @@ -4855,11 +4855,11 @@ func TestResumeActor_RetryRelaxedPauseAssignmentRestoresSameSnapshot(t *testing. tc.fakeAtelet.Lock.Lock() tc.fakeAtelet.FailRestore = nil tc.fakeAtelet.Lock.Unlock() - resumed, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}) + resumed, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("retried ResumeActor failed: %v", err) } - if got := resumed.GetActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := resumed.GetActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("state after the retry = %v, want RUNNING", got) } if got := resumed.GetActor().GetStatus().GetWorkerAssignment().GetWorkerPod(); got != "worker-1" { @@ -4892,14 +4892,14 @@ func TestResumeActor_RetryRelaxedPauseAssignmentRestoresSameSnapshot(t *testing. func TestSuspendActorAsynchronous(t *testing.T) { tests := []struct { name string - suspend func(ctx context.Context, client ateapipb.ControlClient, ref *ateapipb.ObjectRef) error + suspend func(ctx context.Context, client ateapi.ControlClient, ref *ateapi.ObjectRef) error }{ { name: "SuspendActor asynchronous", - suspend: func(ctx context.Context, client ateapipb.ControlClient, ref *ateapipb.ObjectRef) error { - _, err := client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ + suspend: func(ctx context.Context, client ateapi.ControlClient, ref *ateapi.ObjectRef) error { + _, err := client.SuspendActor(ctx, &ateapi.SuspendActorRequest{ Actor: ref, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }) return err }, @@ -4916,23 +4916,23 @@ func TestSuspendActorAsynchronous(t *testing.T) { createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") name := "id1" - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) } // Resume first to make it running - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("ResumeActor failed: %v", err) } - if err := tt.suspend(context.Background(), tc.client, &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}); err != nil { + if err := tt.suspend(context.Background(), tc.client, &ateapi.ObjectRef{Atespace: testAtespace, Name: name}); err != nil { t.Fatalf("suspend failed: %v", err) } @@ -4940,8 +4940,8 @@ func TestSuspendActorAsynchronous(t *testing.T) { t.Errorf("expected atelet Checkpoint to be called") } - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) @@ -4950,17 +4950,17 @@ func TestSuspendActorAsynchronous(t *testing.T) { if ls.GetUuid() == "" { t.Error("Snapshot.Uuid is empty, want the name the pause checkpointed under") } - wantPausedSnap := newPausedSnapshot(t, 2, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), getResp.GetMetadata().GetUid(), ls.GetUuid(), "node1") + wantPausedSnap := newPausedSnapshot(t, 2, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), getResp.GetMetadata().GetUid(), ls.GetUuid(), "node1") wantPausedSnap.SandboxRuntime = defaultWorkerRuntime("gvisor") - want := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: name, Atespace: testAtespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + want := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: name, Atespace: testAtespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, AssignedNode: "node1", LastAssignedGeneration: 2, - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)), + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)), wantPausedSnap, }, }, @@ -4991,36 +4991,36 @@ func TestResumeActor_PausedLocalSnapshotMissing_Crashes(t *testing.T) { workerName := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") name := "paused-missing-actor" - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }); err != nil { t.Fatalf("ResumeActor failed: %v", err) } - if _, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + if _, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }); err != nil { t.Fatalf("SuspendActor failed: %v", err) } - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("actor state = %v, want ACTOR_STATE_SUSPENDED", getResp.GetStatus().GetState()) } if ls := localSnapshot(getResp.GetStatus()); ls == nil { @@ -5034,8 +5034,8 @@ func TestResumeActor_PausedLocalSnapshotMissing_Crashes(t *testing.T) { // A failed restore crashes the actor, and atelet's code does not reach the // caller. - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err == nil { t.Fatal("expected ResumeActor to fail due to missing local snapshot, but it succeeded") @@ -5045,13 +5045,13 @@ func TestResumeActor_PausedLocalSnapshotMissing_Crashes(t *testing.T) { } // Assert actor transitioned to ACTOR_STATE_CRASHED - getResp, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + getResp, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("actor state after failed restore = %v, want ACTOR_STATE_CRASHED", getResp.GetStatus().GetState()) } @@ -5061,8 +5061,8 @@ func TestResumeActor_PausedLocalSnapshotMissing_Crashes(t *testing.T) { } // Subsequent ResumeActor call on CRASHED actor must be rejected - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) assertGrpcErrorRegex(t, err, codes.FailedPrecondition, "ACTOR_STATE_CRASHED") } @@ -5076,9 +5076,9 @@ func TestSuspendActor_FailedLookupStampsRefIdentityOnly(t *testing.T) { defer tc.cleanup() attrs := recordRootSpanAttrs(t, func(ctx context.Context) { - if _, err := tc.service.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: testActorID}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + if _, err := tc.service.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: testActorID}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }); apierror.Code(err) != codes.NotFound { t.Fatalf("SuspendActor(missing) error = %v, want code NotFound", err) } @@ -5116,56 +5116,56 @@ func TestResumeActor_ReleasesStaleWorkerWhenPoolBecomesIneligible(t *testing.T) createWorkerPool(t, tc, ns, "pool-a", map[string]string{"group": ns, "tier": "a"}) createWorkerPool(t, tc, ns, "pool-b", map[string]string{"group": ns, "tier": "b"}) - createTemplateWithSelector(t, tc, "tmpl1", &ateapipb.Selector{ + createTemplateWithSelector(t, tc, "tmpl1", &ateapi.Selector{ MatchLabels: map[string]string{"group": ns}, }) createWorkerPod(t, tc, ns, "worker-a", "node1", "pool-a") createWorkerPod(t, tc, ns, "worker-b", "node1", "pool-b") name := "id1" - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "a"}}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "a"}}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) } tc.fakeAtelet.FailRun = fmt.Errorf("mock atelet failure") - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}}) + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}}) if err == nil { t.Fatalf("expected first ResumeActor (onto worker-a) to fail") } tc.fakeAtelet.FailRun = nil - current, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}}) + current, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}}) if err != nil { t.Fatalf("GetActor failed: %v", err) } - current.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"tier": "b"}} - if _, err := tc.client.UpdateActor(context.Background(), &ateapipb.UpdateActorRequest{ + current.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"tier": "b"}} + if _, err := tc.client.UpdateActor(context.Background(), &ateapi.UpdateActorRequest{ Actor: current, }); err != nil { t.Fatalf("UpdateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}}); err == nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}}); err == nil { t.Fatalf("expected second ResumeActor to fail: the assigned worker's pool is no longer eligible") } - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}}) + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}}) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if got := getResp.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got := getResp.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("expected actor state CRASHED, got %v", got) } // The failed Run already crashed the actor, so the crash it records is // that one, not the later eligibility check. assertActorCrashStatus(t, tc, name, "resume failed: atelet Run: mock atelet failure") - listResp, err := tc.client.ListWorkers(context.Background(), &ateapipb.ListWorkersRequest{}) + listResp, err := tc.client.ListWorkers(context.Background(), &ateapi.ListWorkersRequest{}) if err != nil { t.Fatalf("ListWorkers failed: %v", err) } @@ -5202,13 +5202,13 @@ func TestResumeActor_CrashesIfAssignedWorkerIsDraining(t *testing.T) { createWorkerPod(t, tc, ns, "worker-b", "node1", "pool1") id := "id1" - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: testAtespace, Name: id, }, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }, }); err != nil { t.Fatalf("CreateActor failed: %v", err) @@ -5223,16 +5223,16 @@ func TestResumeActor_CrashesIfAssignedWorkerIsDraining(t *testing.T) { if err != nil { t.Fatalf("GetActor failed: %v", err) } - if err := tc.persistence.BindActorToWorker(context.Background(), podA, &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: id}, + if err := tc.persistence.BindActorToWorker(context.Background(), podA, &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: id}, ActorUid: suspended.GetMetadata().GetUid(), }, nil); err != nil { t.Fatalf("BindActorToWorker failed: %v", err) } - if _, err := tc.persistence.UpdateActor(context.Background(), actorRef, store.PreconditionFrom(suspended), func(toUpdate *ateapipb.Actor) error { - toUpdate.Status.State = ateapipb.ActorState_ACTOR_STATE_RESUMING - toUpdate.Status.WorkerAssignment = &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: podA}, + if _, err := tc.persistence.UpdateActor(context.Background(), actorRef, store.PreconditionFrom(suspended), func(toUpdate *ateapi.Actor) error { + toUpdate.Status.State = ateapi.ActorState_ACTOR_STATE_RESUMING + toUpdate.Status.WorkerAssignment = &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: podA}, WorkerNamespace: ns, WorkerPool: "pool1", WorkerPod: "worker-a", @@ -5246,7 +5246,7 @@ func TestResumeActor_CrashesIfAssignedWorkerIsDraining(t *testing.T) { // Learn which worker got assigned through the API, then mark it DRAINING // as the syncer would when its pod enters Terminating. - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: id}}) + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: id}}) if err != nil { t.Fatalf("GetActor failed: %v", err) } @@ -5259,8 +5259,8 @@ func TestResumeActor_CrashesIfAssignedWorkerIsDraining(t *testing.T) { if err != nil { t.Fatalf("GetWorker(%s) failed: %v", assignedPod, err) } - if _, err := tc.persistence.UpdateWorker(context.Background(), assigned.GetMetadata().GetName(), store.PreconditionFrom(assigned), func(toUpdate *ateapipb.Worker) error { - toUpdate.Status.State = ateapipb.WorkerState_WORKER_STATE_DRAINING + if _, err := tc.persistence.UpdateWorker(context.Background(), assigned.GetMetadata().GetName(), store.PreconditionFrom(assigned), func(toUpdate *ateapi.Worker) error { + toUpdate.Status.State = ateapi.WorkerState_WORKER_STATE_DRAINING return nil }); err != nil { t.Fatalf("marking worker %s draining failed: %v", assignedPod, err) @@ -5269,13 +5269,13 @@ func TestResumeActor_CrashesIfAssignedWorkerIsDraining(t *testing.T) { // Wait until the DRAINING state is observable, which also gives the store // watch time to propagate it into the scheduler's worker cache. if err := wait.PollUntilContextTimeout(context.Background(), 100*time.Millisecond, 5*time.Second, true, func(ctx context.Context) (bool, error) { - resp, err := tc.client.ListWorkers(ctx, &ateapipb.ListWorkersRequest{}) + resp, err := tc.client.ListWorkers(ctx, &ateapi.ListWorkersRequest{}) if err != nil { return false, nil } for _, w := range resp.GetWorkers() { if w.GetWorkerNamespace() == ns && w.GetWorkerPod() == assignedPod { - return w.GetStatus().GetState() == ateapipb.WorkerState_WORKER_STATE_DRAINING, nil + return w.GetStatus().GetState() == ateapi.WorkerState_WORKER_STATE_DRAINING, nil } } return false, nil @@ -5284,7 +5284,7 @@ func TestResumeActor_CrashesIfAssignedWorkerIsDraining(t *testing.T) { } // The resume must fail and crash the actor because its worker is draining. - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: id}}) + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: id}}) if err == nil { t.Fatalf("expected ResumeActor to fail") } @@ -5292,11 +5292,11 @@ func TestResumeActor_CrashesIfAssignedWorkerIsDraining(t *testing.T) { t.Errorf("expected Aborted/crashed error, got %v", err) } - getResp, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: id}}) + getResp, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: id}}) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if got := getResp.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got := getResp.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("expected actor state CRASHED, got %v", got) } if got := getResp.GetStatus().GetWorkerAssignment().GetWorkerPod(); got != "" { @@ -5305,7 +5305,7 @@ func TestResumeActor_CrashesIfAssignedWorkerIsDraining(t *testing.T) { assertActorCrashStatus(t, tc, id, "resume failed: assigned worker is draining") // The draining worker must have been released. - listResp, err := tc.client.ListWorkers(context.Background(), &ateapipb.ListWorkersRequest{}) + listResp, err := tc.client.ListWorkers(context.Background(), &ateapi.ListWorkersRequest{}) if err != nil { t.Fatalf("ListWorkers failed: %v", err) } @@ -5341,7 +5341,7 @@ func TestUpdateActor_ReassignsPoolAcrossSuspendResume(t *testing.T) { createWorkerPool(t, tc, ns, "pool-a", map[string]string{"group": ns, "tier": "a"}) createWorkerPool(t, tc, ns, "pool-b", map[string]string{"group": ns, "tier": "b"}) - createTemplateWithSelector(t, tc, "tmpl1", &ateapipb.Selector{ + createTemplateWithSelector(t, tc, "tmpl1", &ateapi.Selector{ MatchLabels: map[string]string{"group": ns}, }) @@ -5349,10 +5349,10 @@ func TestUpdateActor_ReassignsPoolAcrossSuspendResume(t *testing.T) { createWorkerPod(t, tc, ns, "worker-b", "node1", "pool-b") name := "id1" - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - WorkerSelector: &ateapipb.Selector{ + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + WorkerSelector: &ateapi.Selector{ MatchLabels: map[string]string{"tier": "a"}, }, }}) @@ -5360,11 +5360,11 @@ func TestUpdateActor_ReassignsPoolAcrossSuspendResume(t *testing.T) { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}}); err != nil { t.Fatalf("first ResumeActor failed: %v", err) } - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}}) + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}}) if err != nil { t.Fatalf("GetActor failed: %v", err) } @@ -5375,21 +5375,21 @@ func TestUpdateActor_ReassignsPoolAcrossSuspendResume(t *testing.T) { t.Fatalf("expected actor to first resume onto worker-a, got worker_assignment.worker_pod=%q", got) } - getResp.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"tier": "b"}} - if _, err := tc.client.UpdateActor(context.Background(), &ateapipb.UpdateActorRequest{ + getResp.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"tier": "b"}} + if _, err := tc.client.UpdateActor(context.Background(), &ateapi.UpdateActorRequest{ Actor: getResp, }); err != nil { t.Fatalf("UpdateActor failed: %v", err) } - if _, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}}); err != nil { + if _, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}}); err != nil { t.Fatalf("SuspendActor failed: %v", err) } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}}); err != nil { t.Fatalf("second ResumeActor failed: %v", err) } - getResp, err = tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}}) + getResp, err = tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}}) if err != nil { t.Fatalf("GetActor failed: %v", err) } @@ -5399,7 +5399,7 @@ func TestUpdateActor_ReassignsPoolAcrossSuspendResume(t *testing.T) { if got := getResp.GetStatus().GetWorkerAssignment().GetWorkerPod(); got != "worker-b" { t.Errorf("expected actor to resume onto worker-b after selector update, got worker_assignment.worker_pod=%q", got) } - if got := getResp.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := getResp.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("expected actor state RUNNING after second resume, got %v", got) } } @@ -5414,9 +5414,9 @@ func TestResumeActor_LeaseConflict(t *testing.T) { createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") name := "id1" - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) @@ -5428,8 +5428,8 @@ func TestResumeActor_LeaseConflict(t *testing.T) { // Launch Request A in a goroutine errChan := make(chan error, 1) go func() { - _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) errChan <- err }() @@ -5438,8 +5438,8 @@ func TestResumeActor_LeaseConflict(t *testing.T) { time.Sleep(200 * time.Millisecond) // Launch Request B (should fail due to lease conflict) - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) assertGrpcError(t, err, codes.Aborted, "another operation is in progress for this actor") @@ -5458,9 +5458,9 @@ func TestResumeActor_DanglingWorker(t *testing.T) { podA := createWorkerPod(t, tc, ns, "worker-a", "node1", "pool1") name := "id1" - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) @@ -5474,16 +5474,16 @@ func TestResumeActor_DanglingWorker(t *testing.T) { if err != nil { t.Fatalf("GetActor failed: %v", err) } - if err := tc.persistence.BindActorToWorker(context.Background(), podA, &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + if err := tc.persistence.BindActorToWorker(context.Background(), podA, &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, ActorUid: suspended.GetMetadata().GetUid(), }, nil); err != nil { t.Fatalf("BindActorToWorker failed: %v", err) } - if _, err := tc.persistence.UpdateActor(context.Background(), actorRef, store.PreconditionFrom(suspended), func(toUpdate *ateapipb.Actor) error { - toUpdate.Status.State = ateapipb.ActorState_ACTOR_STATE_RESUMING - toUpdate.Status.WorkerAssignment = &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: podA}, + if _, err := tc.persistence.UpdateActor(context.Background(), actorRef, store.PreconditionFrom(suspended), func(toUpdate *ateapi.Actor) error { + toUpdate.Status.State = ateapi.ActorState_ACTOR_STATE_RESUMING + toUpdate.Status.WorkerAssignment = &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: podA}, WorkerNamespace: ns, WorkerPool: "pool1", WorkerPod: "worker-a", @@ -5496,14 +5496,14 @@ func TestResumeActor_DanglingWorker(t *testing.T) { } // Verify actor state is RESUMING with worker A assigned - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) } actor := getResp - if actor.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RESUMING { + if actor.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RESUMING { t.Fatalf("expected state RESUMING, got %v", actor.GetStatus().GetState()) } if actor.GetStatus().GetWorkerAssignment().GetWorkerPod() != "worker-a" { @@ -5517,8 +5517,8 @@ func TestResumeActor_DanglingWorker(t *testing.T) { // Call ResumeActor again -> Expect it to fail because it is already CRASHED // by the worker delete. - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err == nil { t.Fatalf("expected ResumeActor to fail because worker is gone") @@ -5532,7 +5532,7 @@ func TestResumeActor_DanglingWorker(t *testing.T) { if err != nil { t.Fatalf("failed to get actor from store: %v", err) } - if actor.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if actor.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("expected state CRASHED, got %v", actor.GetStatus().GetState()) } if actor.GetStatus().GetWorkerAssignment().GetWorkerPod() != "" { @@ -5551,17 +5551,17 @@ func TestSuspendActor_DanglingWorker(t *testing.T) { createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") name := "id1" - _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) } // Resume first to make it running - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("ResumeActor failed: %v", err) @@ -5570,8 +5570,8 @@ func TestSuspendActor_DanglingWorker(t *testing.T) { deleteWorkerPod(t, tc, ns, "worker-1") // 3. Call SuspendActor -> Expect it to fail because it is already CRASHED by background syncer - _, err = tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + _, err = tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err == nil { t.Fatalf("expected SuspendActor to fail because worker is gone") @@ -5581,13 +5581,13 @@ func TestSuspendActor_DanglingWorker(t *testing.T) { } // 4. Verify it becomes CRASHED in the store. - getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + getResp, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if getResp.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if getResp.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("expected status CRASHED, got %v", getResp.GetStatus()) } if getResp.GetStatus().GetWorkerAssignment() != nil { @@ -5601,10 +5601,10 @@ func TestSuspendActor_DanglingWorker(t *testing.T) { func TestSuspendActor_FromPaused(t *testing.T) { tests := []struct { name string - opts *ateapipb.SuspendOptions + opts *ateapi.SuspendOptions }{ - {name: "sync", opts: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}, - {name: "async", opts: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}, + {name: "sync", opts: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}, + {name: "async", opts: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -5615,23 +5615,23 @@ func TestSuspendActor_FromPaused(t *testing.T) { createTemplate(t, tc, ns) createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") - ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"} - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + ref := &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"} + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } - if _, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ + if _, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ Actor: ref, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }); err != nil { t.Fatalf("pause failed: %v", err) } - paused, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: ref}) + paused, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: ref}) if err != nil { t.Fatalf("GetActor failed: %v", err) } @@ -5642,7 +5642,7 @@ func TestSuspendActor_FromPaused(t *testing.T) { // atelet traffic is observable in isolation. tc.fakeAtelet.Reset() - suspended, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: ref, Options: tt.opts}) + suspended, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: ref, Options: tt.opts}) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } @@ -5661,16 +5661,16 @@ func TestSuspendActor_FromPaused(t *testing.T) { func TestSuspendActor_Mode(t *testing.T) { tests := []struct { name string - opts *ateapipb.SuspendOptions + opts *ateapi.SuspendOptions wantUploadMode ateletpb.UploadMode wantLocal bool // wantNode is the node an async suspend keeps the actor pinned to. wantNode string }{ {name: "unset", opts: nil, wantUploadMode: ateletpb.UploadMode_UPLOAD_MODE_DEFERRED, wantLocal: true, wantNode: "node1"}, - {name: "unspecified", opts: &ateapipb.SuspendOptions{}, wantUploadMode: ateletpb.UploadMode_UPLOAD_MODE_DEFERRED, wantLocal: true, wantNode: "node1"}, - {name: "async", opts: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, wantUploadMode: ateletpb.UploadMode_UPLOAD_MODE_DEFERRED, wantLocal: true, wantNode: "node1"}, - {name: "sync", opts: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, wantUploadMode: ateletpb.UploadMode_UPLOAD_MODE_IMMEDIATE, wantLocal: false}, + {name: "unspecified", opts: &ateapi.SuspendOptions{}, wantUploadMode: ateletpb.UploadMode_UPLOAD_MODE_DEFERRED, wantLocal: true, wantNode: "node1"}, + {name: "async", opts: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, wantUploadMode: ateletpb.UploadMode_UPLOAD_MODE_DEFERRED, wantLocal: true, wantNode: "node1"}, + {name: "sync", opts: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, wantUploadMode: ateletpb.UploadMode_UPLOAD_MODE_IMMEDIATE, wantLocal: false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -5681,18 +5681,18 @@ func TestSuspendActor_Mode(t *testing.T) { createTemplate(t, tc, ns) createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") - ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"} - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + ref := &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"} + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } - suspended, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: ref, Options: tt.opts}) + suspended, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: ref, Options: tt.opts}) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } @@ -5703,15 +5703,15 @@ func TestSuspendActor_Mode(t *testing.T) { t.Errorf("Checkpoint upload mode = %v, want %v", gotUploadMode, tt.wantUploadMode) } status := suspended.GetActor().GetStatus() - if got := status.GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { - t.Errorf("state = %v, want %v", got, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + if got := status.GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { + t.Errorf("state = %v, want %v", got, ateapi.ActorState_ACTOR_STATE_SUSPENDED) } // A sync suspend leaves a durable snapshot, an async one a node-local // snapshot whose upload is still pending. if gotLocal := localSnapshot(status) != nil; gotLocal != tt.wantLocal { t.Errorf("has local snapshot = %t, want %t", gotLocal, tt.wantLocal) } - if gotDurable := durableSnapshot(status).GetOwner() == ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR; gotDurable == tt.wantLocal { + if gotDurable := durableSnapshot(status).GetOwner() == ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR; gotDurable == tt.wantLocal { t.Errorf("has completed durable snapshot = %t, want %t", gotDurable, !tt.wantLocal) } if got := status.GetAssignedNode(); got != tt.wantNode { @@ -5725,9 +5725,9 @@ func TestSuspendActor_Mode(t *testing.T) { // conflicts preserve the actor's worker and last completed snapshot, and that // retries send the same pending snapshot until atelet accepts it. func TestSuspendActor_SnapshotConflictPreservesState(t *testing.T) { - for _, mode := range []ateapipb.DurabilityMode{ - ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS, - ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, + for _, mode := range []ateapi.DurabilityMode{ + ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS, + ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, } { t.Run(mode.String(), func(t *testing.T) { ctx := context.Background() @@ -5736,18 +5736,18 @@ func TestSuspendActor_SnapshotConflictPreservesState(t *testing.T) { defer tc.cleanup() createTemplate(t, tc, ns) workerUID := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") - ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + ref := &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor: %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("first ResumeActor: %v", err) } - saved, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: ref, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + saved, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: ref, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }) if err != nil { t.Fatalf("first SuspendActor: %v", err) @@ -5755,7 +5755,7 @@ func TestSuspendActor_SnapshotConflictPreservesState(t *testing.T) { waitForWorkerAvailable(t, tc, workerUID) savedURI := durableSnapshotURI(saved.GetActor().GetStatus()) assertSnapshotPresent(t, tc, savedURI) - running, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}) + running, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}) if err != nil { t.Fatalf("second ResumeActor: %v", err) } @@ -5763,17 +5763,17 @@ func TestSuspendActor_SnapshotConflictPreservesState(t *testing.T) { tc.fakeAtelet.Reset() tc.fakeAtelet.SetObjectStore(tc.objectStore) tc.fakeAtelet.FailCheckpoint = status.Error(codes.Aborted, "stale snapshot generation") - req := &ateapipb.SuspendActorRequest{Actor: ref, Options: &ateapipb.SuspendOptions{Mode: mode}} + req := &ateapi.SuspendActorRequest{Actor: ref, Options: &ateapi.SuspendOptions{Mode: mode}} _, err = tc.client.SuspendActor(ctx, req) if got := status.Code(err); got != codes.Aborted { t.Fatalf("SuspendActor error = %v, want Aborted", err) } - stored, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: ref}) + stored, err := tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: ref}) if err != nil { t.Fatalf("GetActor: %v", err) } st := stored.GetStatus() - if st.GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDING || st.GetCrash() != nil { + if st.GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDING || st.GetCrash() != nil { t.Fatalf("status after conflict = %v, want SUSPENDING without a crash", st) } if !proto.Equal(st.GetWorkerAssignment(), running.GetActor().GetStatus().GetWorkerAssignment()) { @@ -5790,13 +5790,13 @@ func TestSuspendActor_SnapshotConflictPreservesState(t *testing.T) { if got := worker.GetStatus().GetAllocated().GetActors(); got != 1 { t.Errorf("allocated actors = %d, want 1", got) } - var pending *ateapipb.Snapshot + var pending *ateapi.Snapshot for _, snap := range st.GetSnapshots() { if snap.GetGeneration() == st.GetLastAssignedGeneration() { pending = snap } } - if pending.GetDurableSnapshot().GetStatus() != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING || pending.GetLocality() != "" { + if pending.GetDurableSnapshot().GetStatus() != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING || pending.GetLocality() != "" { t.Fatalf("in-progress snapshot = %v, want PENDING without locality", pending) } assertSnapshotCollected(t, tc, pending.GetDurableSnapshot().GetObject().GetSnapshotUri()) @@ -5816,7 +5816,7 @@ func TestSuspendActor_SnapshotConflictPreservesState(t *testing.T) { if conflicted.GetSnapshotUuid() != pending.GetUuid() || conflicted.GetGeneration() != pending.GetGeneration() { t.Errorf("repeated Checkpoint snapshot = %v, want pending snapshot %v", conflicted, pending) } - repeated, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: ref}) + repeated, err := tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: ref}) if err != nil { t.Fatalf("GetActor after repeated conflict: %v", err) } @@ -5842,13 +5842,13 @@ func TestSuspendActor_SnapshotConflictPreservesState(t *testing.T) { if got := retried.GetGeneration(); got != pending.GetGeneration() { t.Errorf("retry snapshot generation = %d, want %d", got, pending.GetGeneration()) } - if got := finished.GetActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := finished.GetActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state after retry = %v, want SUSPENDED", got) } if got := finished.GetActor().GetStatus().GetLastAssignedGeneration(); got != pending.GetGeneration() { t.Errorf("generation after retry = %d, want %d", got, pending.GetGeneration()) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor after retry: %v", err) } }) @@ -5861,21 +5861,21 @@ func TestSuspendActor_SnapshotConflictPreservesState(t *testing.T) { func TestCheckpointFailureCrashes(t *testing.T) { tests := []struct { name string - call func(tc *testContext, ref *ateapipb.ObjectRef) error + call func(tc *testContext, ref *ateapi.ObjectRef) error wantMessage string }{ { name: "pause", - call: func(tc *testContext, ref *ateapipb.ObjectRef) error { - _, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: ref, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}) + call: func(tc *testContext, ref *ateapi.ObjectRef) error { + _, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: ref, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}) return err }, wantMessage: "suspend failed: atelet Checkpoint: injected checkpoint failure", }, { name: "suspend", - call: func(tc *testContext, ref *ateapipb.ObjectRef) error { - _, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: ref, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + call: func(tc *testContext, ref *ateapi.ObjectRef) error { + _, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: ref, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) return err }, wantMessage: "suspend failed: atelet Checkpoint: injected checkpoint failure", @@ -5891,14 +5891,14 @@ func TestCheckpointFailureCrashes(t *testing.T) { podUID := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") name := "id1" - ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: name} - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + ref := &ateapi.ObjectRef{Atespace: testAtespace, Name: name} + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } @@ -5912,11 +5912,11 @@ func TestCheckpointFailureCrashes(t *testing.T) { t.Error("expected atelet Checkpoint to be called") } - crashed, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: ref}) + crashed, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: ref}) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if crashed.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if crashed.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Fatalf("state after failed checkpoint = %v, want CRASHED", crashed.GetStatus().GetState()) } if crashed.GetStatus().GetWorkerAssignment() != nil { @@ -5950,9 +5950,9 @@ func TestResumeActor_RelocatesAfterDetach(t *testing.T) { const pinned, relocated = "actor-pinned", "actor-squatter" for _, name := range []string{pinned, relocated} { - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor(%s) failed: %v", name, err) } @@ -5961,19 +5961,19 @@ func TestResumeActor_RelocatesAfterDetach(t *testing.T) { // The actor under test runs on node1's only worker, then suspends // asynchronously — which frees that worker but pins the actor to node1 via // the local snapshot. - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: pinned}, + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: pinned}, }); err != nil { t.Fatalf("ResumeActor(%s) failed: %v", pinned, err) } - if _, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: pinned}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + if _, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: pinned}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }); err != nil { t.Fatalf("SuspendActor(%s) failed: %v", pinned, err) } - paused, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: pinned}, + paused, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: pinned}, }) if err != nil { t.Fatalf("GetActor(%s) failed: %v", pinned, err) @@ -5985,14 +5985,14 @@ func TestResumeActor_RelocatesAfterDetach(t *testing.T) { // Another actor takes node1's only worker, so the pinned actor's node is full // while free capacity exists elsewhere. - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: relocated}, + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: relocated}, }); err != nil { t.Fatalf("ResumeActor(%s) failed: %v", relocated, err) } // With no room on any node, the resume fails with ResourceExhausted. - _, err = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: pinned}, + _, err = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: pinned}, }) assertGrpcError(t, err, codes.ResourceExhausted, "no worker has room for the actor") createWorkerPod(t, tc, ns, "worker-2", "node2", "pool1") @@ -6001,8 +6001,8 @@ func TestResumeActor_RelocatesAfterDetach(t *testing.T) { // node1's atelet reports the local snapshot uploaded and detached: a report // with only latest_durable. ls := localSnapshot(paused.GetStatus()) - if err := tc.service.ApplyActorSnapshotState(context.Background(), resources.ActorRefFromActor(paused), paused.GetMetadata().GetUid(), "node1", &ateapipb.ActorSnapshotState{ - LatestDurable: &ateapipb.SnapshotReport{ + if err := tc.service.ApplyActorSnapshotState(context.Background(), resources.ActorRefFromActor(paused), paused.GetMetadata().GetUid(), "node1", &ateapi.ActorSnapshotState{ + LatestDurable: &ateapi.SnapshotReport{ Uuid: ls.GetUuid(), Generation: ls.GetGeneration(), Fidelity: ls.GetFidelity(), @@ -6011,8 +6011,8 @@ func TestResumeActor_RelocatesAfterDetach(t *testing.T) { }); err != nil { t.Fatalf("ApplyActorSnapshotState(%s) failed: %v", pinned, err) } - detached, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: pinned}, + detached, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: pinned}, }) if err != nil { t.Fatalf("GetActor(%s) failed: %v", pinned, err) @@ -6025,8 +6025,8 @@ func TestResumeActor_RelocatesAfterDetach(t *testing.T) { } // Resume should succeed now and the actor scheduled on node2. - resumed, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: pinned}, + resumed, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: pinned}, }) if err != nil { t.Fatalf("ResumeActor(%s) after detach failed: %v", pinned, err) @@ -6055,26 +6055,26 @@ func TestResumeActor_DetachesFromFullNode(t *testing.T) { const pinned, squatter = "actor-pinned", "actor-squatter" for _, name := range []string{pinned, squatter} { - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor(%s) failed: %v", name, err) } } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: pinned}, + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: pinned}, }); err != nil { t.Fatalf("ResumeActor(%s) failed: %v", pinned, err) } - if _, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: pinned}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + if _, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: pinned}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }); err != nil { t.Fatalf("SuspendActor(%s) failed: %v", pinned, err) } - paused, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: pinned}, + paused, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: pinned}, }) if err != nil { t.Fatalf("GetActor(%s) failed: %v", pinned, err) @@ -6084,16 +6084,16 @@ func TestResumeActor_DetachesFromFullNode(t *testing.T) { t.Fatalf("paused actor = %v, want a local snapshot on node1", paused.GetStatus()) } waitForWorkerAvailable(t, tc, workerName) - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: squatter}, + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: squatter}, }); err != nil { t.Fatalf("ResumeActor(%s) failed: %v", squatter, err) } createWorkerPod(t, tc, ns, "worker-2", "node2", "pool1") setupAteletOnNode(t, tc, "atelet-node2", "node2") - resumed, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: pinned}, + resumed, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: pinned}, }) if err != nil { t.Fatalf("ResumeActor(%s) on a full node failed: %v", pinned, err) @@ -6125,14 +6125,14 @@ func TestLifecycleOpPoolAttributesOnSuccess(t *testing.T) { name string op string // run performs the operation on an actor that is already RUNNING. - run func(t *testing.T, tc *testContext, actor *ateapipb.ObjectRef) + run func(t *testing.T, tc *testContext, actor *ateapi.ObjectRef) }{ { name: "suspend", op: ateattr.OperationSuspend, - run: func(t *testing.T, tc *testContext, actor *ateapipb.ObjectRef) { + run: func(t *testing.T, tc *testContext, actor *ateapi.ObjectRef) { t.Helper() - if _, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: actor, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}); err != nil { + if _, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: actor, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}); err != nil { t.Fatalf("SuspendActor failed: %v", err) } }, @@ -6140,9 +6140,9 @@ func TestLifecycleOpPoolAttributesOnSuccess(t *testing.T) { { name: "pause", op: ateattr.OperationSuspend, - run: func(t *testing.T, tc *testContext, actor *ateapipb.ObjectRef) { + run: func(t *testing.T, tc *testContext, actor *ateapi.ObjectRef) { t.Helper() - if _, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: actor, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}); err != nil { + if _, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: actor, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}); err != nil { t.Fatalf("SuspendActor failed: %v", err) } }, @@ -6157,14 +6157,14 @@ func TestLifecycleOpPoolAttributesOnSuccess(t *testing.T) { createTemplate(t, tc, ns) createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"} - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.GetAtespace(), Name: actorRef.GetName()}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"} + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.GetAtespace(), Name: actorRef.GetName()}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } @@ -6227,9 +6227,9 @@ func TestCreateActor_RejectsUnknownRequestFields(t *testing.T) { createTemplate(t, tc, ns) - req := &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + req := &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }} unknown := protowire.AppendTag(nil, 9999, protowire.VarintType) req.ProtoReflect().SetUnknown(protowire.AppendVarint(unknown, 42)) @@ -6254,9 +6254,9 @@ func TestDeleteActor_ReleasesAnAssignmentTheActorDoesNotReference(t *testing.T) podUID := createWorkerPod(t, tc, ns, "worker-1", "node-1", "pool-1") ctx := context.Background() - actor, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "orphaned"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actor, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "orphaned"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor failed: %v", err) @@ -6266,15 +6266,15 @@ func TestDeleteActor_ReleasesAnAssignmentTheActorDoesNotReference(t *testing.T) // Bind straight through the store, leaving the Actor's backlink unset: // exactly the state a crash between the two writes leaves behind. - if err := tc.persistence.BindActorToWorker(ctx, podUID, &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "orphaned"}, + if err := tc.persistence.BindActorToWorker(ctx, podUID, &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "orphaned"}, ActorUid: actorUID, }, nil); err != nil { t.Fatalf("BindActorToWorker failed: %v", err) } - if _, err := tc.client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "orphaned"}, + if _, err := tc.client.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "orphaned"}, }); err != nil { t.Fatalf("DeleteActor failed: %v", err) } @@ -6299,22 +6299,22 @@ func TestMintActorJWT_Success(t *testing.T) { createTemplate(t, tc, ns) - createResp, err := tc.client.CreateActor(t.Context(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ + createResp, err := tc.client.CreateActor(t.Context(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: testAtespace, Name: "id1", }, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "free"}}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "free"}}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, }, }) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - mintResp, err := tc.client.MintActorJwt(t.Context(), &ateapipb.MintActorJwtRequest{ - Actor: &ateapipb.ObjectRef{ + mintResp, err := tc.client.MintActorJwt(t.Context(), &ateapi.MintActorJwtRequest{ + Actor: &ateapi.ObjectRef{ Atespace: createResp.GetMetadata().GetAtespace(), Name: createResp.GetMetadata().GetName(), }, @@ -6356,7 +6356,7 @@ func TestMintActorJWT_Success(t *testing.T) { // assertActorJWTLifetime checks that expire_time matches the exp claim and that // the token is valid for want after it was issued. -func assertActorJWTLifetime(t *testing.T, resp *ateapipb.MintActorJwtResponse, claims actoridjwt.WireClaims, want time.Duration) { +func assertActorJWTLifetime(t *testing.T, resp *ateapi.MintActorJwtResponse, claims actoridjwt.WireClaims, want time.Duration) { t.Helper() if got, exp := resp.GetExpireTime().AsTime(), time.Unix(int64(claims.Expiration), 0); !got.Equal(exp) { t.Errorf("expire_time = %v, want the exp claim %v", got, exp) @@ -6390,20 +6390,20 @@ func TestRevertActor(t *testing.T) { ctx := context.Background() const name = "id1" - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: name} + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: name} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } // Run and suspend once, so the revert has a snapshot to return the actor to. - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } - suspended, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + suspended, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } @@ -6414,21 +6414,21 @@ func TestRevertActor(t *testing.T) { } // Run it again, then throw that second execution away. - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("second ResumeActor failed: %v", err) } tc.fakeAtelet.Lock.Lock() tc.fakeAtelet.CheckpointCalled = false tc.fakeAtelet.Lock.Unlock() - reverted, err := tc.client.RevertActor(ctx, &ateapipb.RevertActorRequest{Actor: actorRef}) + reverted, err := tc.client.RevertActor(ctx, &ateapi.RevertActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("RevertActor failed: %v", err) } waitForWorkerAvailable(t, tc, workerName) got := reverted.GetActor().GetStatus() - if got.GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got.GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state = %v, want SUSPENDED", got.GetState()) } if uri := durableSnapshotURI(got); uri != snapshotURI { @@ -6470,22 +6470,22 @@ func TestRevertActor_UnreachableNode(t *testing.T) { tc.fakeAtelet.Lock.Lock() tc.fakeAtelet.KeepCheckpointLocal = true tc.fakeAtelet.Lock.Unlock() - ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-1"} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: ref.GetName()}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + ref := &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-1"} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: ref.GetName()}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatal(err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatal(err) } - mode := ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS + mode := ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS if tt.pending { - mode = ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS + mode = ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS } - suspended, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: ref, Options: &ateapipb.SuspendOptions{Mode: mode}, + suspended, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: ref, Options: &ateapi.SuspendOptions{Mode: mode}, }) if err != nil { t.Fatal(err) @@ -6511,16 +6511,16 @@ func TestRevertActor_UnreachableNode(t *testing.T) { tc.fakeAtelet.FailTerminate = status.Error(codes.Unavailable, "node unavailable") tc.fakeAtelet.Lock.Unlock() } - reverted, err := tc.client.RevertActor(ctx, &ateapipb.RevertActorRequest{Actor: ref}) + reverted, err := tc.client.RevertActor(ctx, &ateapi.RevertActorRequest{Actor: ref}) if tt.pending { if status.Code(err) != codes.Unavailable { t.Fatalf("RevertActor = %v, want Unavailable", err) } - stored, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: ref}) + stored, err := tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: ref}) if err != nil { t.Fatal(err) } - if stored.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_REVERTING || + if stored.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_REVERTING || stored.GetStatus().GetAssignedNode() != sourceNode || !proto.Equal(localSnapshot(stored.GetStatus()), snap) { t.Fatalf("pending checkpoint changed: %v", stored.GetStatus()) } @@ -6530,13 +6530,13 @@ func TestRevertActor_UnreachableNode(t *testing.T) { t.Fatalf("RevertActor on unreachable node: %v", err) } got := reverted.GetActor().GetStatus() - if got.GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED || got.GetAssignedNode() != "" || + if got.GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED || got.GetAssignedNode() != "" || got.GetWorkerAssignment() != nil || localSnapshot(got) != nil { t.Fatalf("reverted status = %v, want unbound SUSPENDED", got) } createWorkerPod(t, tc, ns, "worker-2", "node2", "pool1") setupAteletOnNode(t, tc, "atelet-node2", "node2") - resumed, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}) + resumed, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}) if err != nil { t.Fatalf("ResumeActor after revert: %v", err) } @@ -6566,19 +6566,19 @@ func TestRevertActor_FromPaused(t *testing.T) { ctx := context.Background() const name = "id1" - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: name} + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: name} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } - suspended, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + suspended, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } @@ -6588,10 +6588,10 @@ func TestRevertActor_FromPaused(t *testing.T) { t.Fatalf("SuspendActor wrote no external snapshot: %v", suspended) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("second ResumeActor failed: %v", err) } - if _, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}); err != nil { + if _, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}); err != nil { t.Fatalf("SuspendActor failed: %v", err) } waitForWorkerAvailable(t, tc, workerName) @@ -6600,13 +6600,13 @@ func TestRevertActor_FromPaused(t *testing.T) { tc.fakeAtelet.CheckpointCalled = false tc.fakeAtelet.Lock.Unlock() - reverted, err := tc.client.RevertActor(ctx, &ateapipb.RevertActorRequest{Actor: actorRef}) + reverted, err := tc.client.RevertActor(ctx, &ateapi.RevertActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("RevertActor failed: %v", err) } got := reverted.GetActor().GetStatus() - if got.GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got.GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state = %v, want SUSPENDED", got.GetState()) } if uri := durableSnapshotURI(got); uri != snapshotURI { @@ -6644,19 +6644,19 @@ func TestRevertActor_FromCrashed(t *testing.T) { ctx := context.Background() const name = "id1" - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: name} + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: name} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } - suspended, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + suspended, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } @@ -6667,16 +6667,16 @@ func TestRevertActor_FromCrashed(t *testing.T) { } // Resume onto worker-1, then delete the worker pod so the actor crashes. - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("second ResumeActor failed: %v", err) } deleteWorkerPod(t, tc, ns, "worker-1") - crashed, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actorRef}) + crashed, err := tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if crashed.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if crashed.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Fatalf("state = %v, want CRASHED", crashed.GetStatus().GetState()) } tc.fakeAtelet.Lock.Lock() @@ -6684,13 +6684,13 @@ func TestRevertActor_FromCrashed(t *testing.T) { tc.fakeAtelet.CheckpointCalled = false tc.fakeAtelet.Lock.Unlock() - reverted, err := tc.client.RevertActor(ctx, &ateapipb.RevertActorRequest{Actor: actorRef}) + reverted, err := tc.client.RevertActor(ctx, &ateapi.RevertActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("RevertActor from CRASHED failed: %v", err) } got := reverted.GetActor().GetStatus() - if got.GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got.GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state = %v, want SUSPENDED", got.GetState()) } if uri := durableSnapshotURI(got); uri != snapshotURI { @@ -6714,11 +6714,11 @@ func TestRevertActor_FromCrashed(t *testing.T) { // Verify the recovered actor can be resumed onto a new worker. createWorkerPod(t, tc, ns, "worker-2", "node1", "pool1") - resumed, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}) + resumed, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("ResumeActor after revert from CRASHED failed: %v", err) } - if resumed.GetActor().GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if resumed.GetActor().GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("resumed state = %v, want RUNNING", resumed.GetActor().GetStatus().GetState()) } } @@ -6736,23 +6736,23 @@ func TestRevertActor_TerminateFailureLeavesActorReverting(t *testing.T) { ctx := context.Background() const name = "id1" - ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: name} + ref := &ateapi.ObjectRef{Atespace: testAtespace, Name: name} actorRef := resources.ActorRef{Atespace: testAtespace, Name: name} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } tc.fakeAtelet.Lock.Lock() tc.fakeAtelet.FailTerminate = status.Error(codes.Internal, "injected terminate failure") tc.fakeAtelet.Lock.Unlock() - _, err := tc.client.RevertActor(ctx, &ateapipb.RevertActorRequest{Actor: ref}) + _, err := tc.client.RevertActor(ctx, &ateapi.RevertActorRequest{Actor: ref}) if got := status.Code(err); got != codes.Internal { t.Fatalf("RevertActor status code = %v, want %v (err: %v)", got, codes.Internal, err) } @@ -6761,7 +6761,7 @@ func TestRevertActor_TerminateFailureLeavesActorReverting(t *testing.T) { if err != nil { t.Fatalf("failed to get actor from store: %v", err) } - if got := actor.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_REVERTING { + if got := actor.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_REVERTING { t.Errorf("state after failed terminate = %v, want REVERTING", got) } if crash := actor.GetStatus().GetCrash(); crash != nil { @@ -6775,11 +6775,11 @@ func TestRevertActor_TerminateFailureLeavesActorReverting(t *testing.T) { tc.fakeAtelet.FailTerminate = nil tc.fakeAtelet.TerminateCalled = false tc.fakeAtelet.Lock.Unlock() - reverted, err := tc.client.RevertActor(ctx, &ateapipb.RevertActorRequest{Actor: ref}) + reverted, err := tc.client.RevertActor(ctx, &ateapi.RevertActorRequest{Actor: ref}) if err != nil { t.Fatalf("second RevertActor failed: %v", err) } - if got := reverted.GetActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := reverted.GetActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state after retry = %v, want SUSPENDED", got) } if got := reverted.GetActor().GetStatus().GetWorkerAssignment(); got != nil { @@ -6806,23 +6806,23 @@ func TestDeleteActor_TerminateFailureLeavesActorDeleting(t *testing.T) { ctx := context.Background() const name = "id1" - ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: name} + ref := &ateapi.ObjectRef{Atespace: testAtespace, Name: name} actorRef := resources.ActorRef{Atespace: testAtespace, Name: name} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } tc.fakeAtelet.Lock.Lock() tc.fakeAtelet.FailTerminate = status.Error(codes.Internal, "injected terminate failure") tc.fakeAtelet.Lock.Unlock() - if _, err := tc.client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref}); err == nil { + if _, err := tc.client.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}); err == nil { t.Fatal("DeleteActor succeeded despite failing terminate") } @@ -6830,7 +6830,7 @@ func TestDeleteActor_TerminateFailureLeavesActorDeleting(t *testing.T) { if err != nil { t.Fatalf("failed to get actor from store: %v", err) } - if got := actor.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_DELETING { + if got := actor.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_DELETING { t.Errorf("state after failed terminate = %v, want DELETING", got) } if crash := actor.GetStatus().GetCrash(); crash != nil { @@ -6844,10 +6844,10 @@ func TestDeleteActor_TerminateFailureLeavesActorDeleting(t *testing.T) { tc.fakeAtelet.FailTerminate = nil tc.fakeAtelet.TerminateCalled = false tc.fakeAtelet.Lock.Unlock() - if _, err := tc.client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}); err != nil { t.Fatalf("second DeleteActor failed: %v", err) } - if _, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: ref}); status.Code(err) != codes.NotFound { + if _, err := tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: ref}); status.Code(err) != codes.NotFound { t.Errorf("GetActor after retried delete err = %v, want NotFound", err) } tc.fakeAtelet.Lock.Lock() @@ -6861,8 +6861,8 @@ func TestDeleteActor_TerminateFailureLeavesActorDeleting(t *testing.T) { // assertActorCrashStatus reads the actor through the API and checks the crash it records. func assertActorCrashStatus(t *testing.T, tc *testContext, name, wantMessage string) { t.Helper() - actor, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + actor, err := tc.client.GetActor(context.Background(), &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) @@ -6891,16 +6891,16 @@ func TestRevertActor_RejectsSuspended(t *testing.T) { ctx := context.Background() const name = "id1" - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: name} + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: name} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - _, err := tc.client.RevertActor(ctx, &ateapipb.RevertActorRequest{Actor: actorRef}) + _, err := tc.client.RevertActor(ctx, &ateapi.RevertActorRequest{Actor: actorRef}) if status.Code(err) != codes.FailedPrecondition { t.Fatalf("RevertActor = %v, want FailedPrecondition", err) } @@ -6911,8 +6911,8 @@ func TestRevertActor_NotFound(t *testing.T) { tc := setupTest(t, ns) defer tc.cleanup() - _, err := tc.client.RevertActor(context.Background(), &ateapipb.RevertActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "nope"}, + _, err := tc.client.RevertActor(context.Background(), &ateapi.RevertActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "nope"}, }) if status.Code(err) != codes.NotFound { t.Fatalf("RevertActor = %v, want NotFound", err) @@ -6927,9 +6927,9 @@ func TestDeleteActor_Preconditions(t *testing.T) { tmpl := createTemplate(t, tc, ns) actorRef := resources.ActorRef{Atespace: testAtespace, Name: "id1"} ref := actorRef.ToObjectRef() - create := func() *ateapipb.Actor { - created, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + create := func() *ateapi.Actor { + created, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: resources.ActorTemplateRefFromActorTemplate(tmpl).ToObjectRef(), }}) if err != nil { @@ -6937,44 +6937,44 @@ func TestDeleteActor_Preconditions(t *testing.T) { } return created } - del := func(opts *ateapipb.DeleteOptions) error { - _, err := tc.client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref, Options: opts}) + del := func(opts *ateapi.DeleteOptions) error { + _, err := tc.client.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref, Options: opts}) return err } actor := create() uid, version := actor.GetMetadata().GetUid(), actor.GetMetadata().GetVersion() - assertGrpcError(t, del(&ateapipb.DeleteOptions{Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: uid, Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: foreignUID}), codes.Aborted, "Actor "+actorRef.String()+" does not have uid "+foreignUID) - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: foreignUID, Version: version}), codes.Aborted, "Actor "+actorRef.String()+" does not have uid "+foreignUID) - got, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: ref}) + assertGrpcError(t, del(&ateapi.DeleteOptions{Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: uid, Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: foreignUID}), codes.Aborted, "Actor "+actorRef.String()+" does not have uid "+foreignUID) + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: foreignUID, Version: version}), codes.Aborted, "Actor "+actorRef.String()+" does not have uid "+foreignUID) + got, err := tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: ref}) if err != nil { t.Fatalf("a refused delete removed the actor: %v", err) } - if state := got.GetStatus().GetState(); state != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if state := got.GetStatus().GetState(); state != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("state after the refused deletes = %v, want SUSPENDED", state) } - if err := del(&ateapipb.DeleteOptions{Version: version}); err != nil { + if err := del(&ateapi.DeleteOptions{Version: version}); err != nil { t.Fatalf("DeleteActor with the matching version: %v", err) } actor = create() - if err := del(&ateapipb.DeleteOptions{Uid: actor.GetMetadata().GetUid()}); err != nil { + if err := del(&ateapi.DeleteOptions{Uid: actor.GetMetadata().GetUid()}); err != nil { t.Fatalf("DeleteActor with the matching uid: %v", err) } actor = create() - if err := del(&ateapipb.DeleteOptions{Uid: actor.GetMetadata().GetUid(), Version: actor.GetMetadata().GetVersion()}); err != nil { + if err := del(&ateapi.DeleteOptions{Uid: actor.GetMetadata().GetUid(), Version: actor.GetMetadata().GetVersion()}); err != nil { t.Fatalf("DeleteActor with both guards: %v", err) } - _, err = tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: ref}) + _, err = tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: ref}) assertGrpcError(t, err, codes.NotFound, "Actor "+actorRef.String()+" not found") } // reportWorkerRuntime writes defaultRT and restorableRTs to workerName's status // as its one sandbox class and waits for the worker cache to observe the update. -func reportWorkerRuntime(t *testing.T, tc *testContext, workerName string, defaultRT *ateapipb.ActorSandboxRuntime, restorableRTs ...*ateapipb.ActorSandboxRuntime) { +func reportWorkerRuntime(t *testing.T, tc *testContext, workerName string, defaultRT *ateapi.ActorSandboxRuntime, restorableRTs ...*ateapi.ActorSandboxRuntime) { t.Helper() ctx := context.Background() cur, err := tc.persistence.GetWorker(ctx, workerName) @@ -6982,7 +6982,7 @@ func reportWorkerRuntime(t *testing.T, tc *testContext, workerName string, defau t.Fatalf("GetWorker(%s): %v", workerName, err) } want := workerSandboxClasses(defaultRT, restorableRTs...) - if _, err := tc.persistence.UpdateWorker(ctx, workerName, store.PreconditionFrom(cur), func(toUpdate *ateapipb.Worker) error { + if _, err := tc.persistence.UpdateWorker(ctx, workerName, store.PreconditionFrom(cur), func(toUpdate *ateapi.Worker) error { toUpdate.Status.SandboxClasses = workerSandboxClasses(defaultRT, restorableRTs...) return nil }); err != nil { @@ -6991,7 +6991,7 @@ func reportWorkerRuntime(t *testing.T, tc *testContext, workerName string, defau if err := wait.PollUntilContextTimeout(ctx, 10*time.Millisecond, 5*time.Second, true, func(context.Context) (bool, error) { got, err := tc.workerCache.Worker(workerName) return err == nil && - slices.EqualFunc(got.GetStatus().GetSandboxClasses(), want, func(a, b *ateapipb.WorkerSandboxClass) bool { return proto.Equal(a, b) }), nil + slices.EqualFunc(got.GetStatus().GetSandboxClasses(), want, func(a, b *ateapi.WorkerSandboxClass) bool { return proto.Equal(a, b) }), nil }); err != nil { t.Fatalf("worker %s runtime never reached worker cache: %v", workerName, err) } @@ -7021,21 +7021,21 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) { ctx := context.Background() tmpl := createTemplate(t, tc, ns) - rtA := &ateapipb.ActorSandboxRuntime{ + rtA := &ateapi.ActorSandboxRuntime{ SandboxClass: "gvisor", - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{ + Attributes: []*ateapi.AttributeEntry{ {Key: "architecture", Value: "amd64"}, {Key: "sandbox_bundle_hash", Value: "hash-a"}, }, }, } - rtB := &ateapipb.ActorSandboxRuntime{ + rtB := &ateapi.ActorSandboxRuntime{ SandboxClass: "gvisor", - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{ + Attributes: []*ateapi.AttributeEntry{ {Key: "architecture", Value: "amd64"}, {Key: "sandbox_bundle_hash", Value: "hash-b"}, }, @@ -7046,15 +7046,15 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) { workerA := createWorkerPod(t, tc, ns, "worker-a", "node1", "pool1") reportWorkerRuntime(t, tc, workerA, rtA) - actorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-1"} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "actor-1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-1"} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "actor-1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - resumed1, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}) + resumed1, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("initial ResumeActor failed: %v", err) } @@ -7062,7 +7062,7 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) { t.Fatalf("initial WorkerAssignment.SandboxRuntime = %v, want %v", got, rtA) } - suspended1, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + suspended1, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatalf("first SuspendActor failed: %v", err) } @@ -7076,7 +7076,7 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) { workerB := createWorkerPod(t, tc, ns, "worker-b", "node1", "pool1") reportWorkerRuntime(t, tc, workerB, rtB) - resumed2, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}) + resumed2, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("second ResumeActor failed: %v", err) } @@ -7090,19 +7090,19 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) { t.Fatalf("second RestoreRequest.Fidelity = %v, want MEMORY", got) } - if _, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}); err != nil { + if _, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}); err != nil { t.Fatalf("second SuspendActor failed: %v", err) } waitForWorkerAvailable(t, tc, workerA) // Tag actor-1's rtA snapshot and occupy worker-a with a blocker actor seeded // from that tag so the rtA worker is at capacity. - tagRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tag-rt-a"} - tag, err := tc.client.CreateTag(ctx, &ateapipb.CreateTagRequest{ - Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "tag-rt-a"}, + tagRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "tag-rt-a"} + tag, err := tc.client.CreateTag(ctx, &ateapi.CreateTagRequest{ + Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "tag-rt-a"}, SourceActor: actorRef, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, }, }) if err != nil { @@ -7112,15 +7112,15 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) { t.Fatalf("Tag.Snapshot.SandboxRuntime = %v, want %v", got, rtA) } - blockerRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "blocker"} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "blocker"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + blockerRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "blocker"} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "blocker"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, SourceTag: tagRef, }}); err != nil { t.Fatalf("CreateActor(blocker) failed: %v", err) } - blockerResumed, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: blockerRef}) + blockerResumed, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: blockerRef}) if err != nil { t.Fatalf("ResumeActor(blocker) failed: %v", err) } @@ -7130,7 +7130,7 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) { // With worker-a full, resuming actor-1 must fall back to worker-b, downgrade // the restore to ROOTFS fidelity, and re-stamp rtB on the next suspend. - resumed3, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef}) + resumed3, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("fallback ResumeActor failed: %v", err) } @@ -7144,7 +7144,7 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) { t.Fatalf("fallback RestoreRequest.Fidelity = %v, want ROOTFS", got) } - suspended3, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + suspended3, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatalf("SuspendActor after fallback failed: %v", err) } @@ -7157,13 +7157,13 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) { // verify that a newly created actor borrowing the golden snapshot, when // worker-a is full and it falls back onto worker-b, restores the golden at // ROOTFS fidelity like any other durable snapshot rather than cold-booting. - goldenSnap := newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)) - goldenSnap.SandboxRuntime = proto.Clone(rtA).(*ateapipb.ActorSandboxRuntime) - stampedGoldenTag, err := tc.persistence.CreateTag(ctx, &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "golden-rt-a"}, - SourceActor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: tmpl.GetMetadata().GetUid()}, - Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED, - Status: &ateapipb.TagStatus{ + goldenSnap := newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)) + goldenSnap.SandboxRuntime = proto.Clone(rtA).(*ateapi.ActorSandboxRuntime) + stampedGoldenTag, err := tc.persistence.CreateTag(ctx, &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "golden-rt-a"}, + SourceActor: &ateapi.ObjectRef{Atespace: testAtespace, Name: tmpl.GetMetadata().GetUid()}, + Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED, + Status: &ateapi.TagStatus{ Snapshot: goldenSnap, ActorTemplateUid: tmpl.GetMetadata().GetUid(), }, @@ -7175,17 +7175,17 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) { if err != nil { t.Fatalf("GetActorTemplate: %v", err) } - if _, err := tc.persistence.UpdateActorTemplate(ctx, resources.ActorTemplateRefFromActorTemplate(curTmpl), store.PreconditionFrom(curTmpl), func(dbTemplate *ateapipb.ActorTemplate) error { + if _, err := tc.persistence.UpdateActorTemplate(ctx, resources.ActorTemplateRefFromActorTemplate(curTmpl), store.PreconditionFrom(curTmpl), func(dbTemplate *ateapi.ActorTemplate) error { dbTemplate.Status.GoldenSnapshotStatus.GoldenTag = resources.TagRefFromTag(stampedGoldenTag).ToObjectRef() return nil }); err != nil { t.Fatalf("UpdateActorTemplate(golden): %v", err) } - goldenActorRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "golden-actor"} - goldenCreated, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "golden-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + goldenActorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "golden-actor"} + goldenCreated, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "golden-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}) if err != nil { t.Fatalf("CreateActor(golden-actor) failed: %v", err) @@ -7199,7 +7199,7 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) { tc.fakeAtelet.RestoreCalled = false tc.fakeAtelet.Lock.Unlock() - goldenResumed, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: goldenActorRef}) + goldenResumed, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: goldenActorRef}) if err != nil { t.Fatalf("ResumeActor(golden-actor) failed: %v", err) } @@ -7235,21 +7235,21 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) { // record the matched restorable entry (rtA, not rtB) on WorkerAssignment, // and preserve rtA through async SuspendActor and sync SuspendActor on the // already-SUSPENDED actor. - if _, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: goldenActorRef}); err != nil { + if _, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: goldenActorRef}); err != nil { t.Fatalf("SuspendActor(golden-actor) failed: %v", err) } waitForWorkerAvailable(t, tc, workerB) reportWorkerRuntime(t, tc, workerB, rtB, rtA) - restorableRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "restorable-actor"} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "restorable-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + restorableRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "restorable-actor"} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "restorable-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, SourceTag: tagRef, }}); err != nil { t.Fatalf("CreateActor(restorable-actor) failed: %v", err) } - restorableResumed, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: restorableRef}) + restorableResumed, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: restorableRef}) if err != nil { t.Fatalf("ResumeActor(restorable-actor) failed: %v", err) } @@ -7263,7 +7263,7 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) { t.Fatalf("restorable-actor RestoreRequest.Fidelity = %v, want MEMORY", got) } - pausedResp, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: restorableRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}) + pausedResp, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: restorableRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}) if err != nil { t.Fatalf("SuspendActor(restorable-actor) failed: %v", err) } @@ -7274,7 +7274,7 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) { // A sync suspend of the already-SUSPENDED actor returns it as it is: the // node-local snapshot keeps its runtime stamp. - suspendedFromPaused, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: restorableRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + suspendedFromPaused, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: restorableRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatalf("SuspendActor from PAUSED(restorable-actor) failed: %v", err) } diff --git a/cmd/ateapi/internal/controlapi/functionaltest/actor_volume_detach_test.go b/cmd/ateapi/internal/controlapi/functionaltest/actor_volume_detach_test.go index e12b10fb75..51e3278665 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/actor_volume_detach_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/actor_volume_detach_test.go @@ -21,11 +21,11 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/volume" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -67,20 +67,20 @@ func assertDetachedNodes(t *testing.T, plugin *attachFailVolumePlugin, step stri func createSingleVolumeActor(t *testing.T, tc *testContext, ns, name string) string { t.Helper() preview.InitForTest(t, "ExternalVolumes") - volumes := []*ateapipb.Volume{{ + volumes := []*ateapi.Volume{{ Name: "vol1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", CapacityBytes: 10 << 30, }}, }} - mounts := []*ateapipb.VolumeMount{{Name: "vol1", MountPath: "/mnt/vol1"}} + mounts := []*ateapi.VolumeMount{{Name: "vol1", MountPath: "/mnt/vol1"}} createTemplateWithVolumes(t, tc, ns, volumes, mounts) workerName := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } @@ -91,8 +91,8 @@ func createSingleVolumeActor(t *testing.T, tc *testContext, ns, name string) str // published to node1 and that the store records node1 as its assigned_node. func resumeToRunningOnNode1(t *testing.T, tc *testContext, plugin *attachFailVolumePlugin, name string) { t.Helper() - if _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + if _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }); err != nil { t.Fatalf("ResumeActor failed: %v", err) } @@ -110,7 +110,7 @@ func assertCrashedKeepingAssignedNode(t *testing.T, tc *testContext, name, node if err != nil { t.Fatalf("GetActor(%s) from store: %v", name, err) } - if got := actor.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got := actor.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Fatalf("state = %v, want CRASHED", got) } if got := actor.GetStatus().GetWorkerAssignment(); got != nil { @@ -141,8 +141,8 @@ func TestDeleteActor_CrashedWorkerGone_DetachesAssignedNode(t *testing.T) { assertDetachedNodes(t, plugin, "after the crash") // CRASHED is deletable without AnyState. - if _, err := tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + if _, err := tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }); err != nil { t.Fatalf("DeleteActor failed: %v", err) } @@ -170,8 +170,8 @@ func TestResumeActor_RestoreCrash_DeleteDetaches(t *testing.T) { createSingleVolumeActor(t, tc, ns, name) tc.fakeAtelet.FailRestore = status.Error(codes.Internal, "injected restore failure") - _, err := tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + _, err := tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if got := status.Code(err); got != codes.Internal { t.Fatalf("ResumeActor code = %v, want %v (err: %v)", got, codes.Internal, err) @@ -182,8 +182,8 @@ func TestResumeActor_RestoreCrash_DeleteDetaches(t *testing.T) { assertCrashedKeepingAssignedNode(t, tc, name, "node1") assertDetachedNodes(t, plugin, "after the crash") - if _, err := tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + if _, err := tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }); err != nil { t.Fatalf("DeleteActor failed: %v", err) } @@ -213,14 +213,14 @@ func TestSuspendActor_WorkerRowGone_StillDetaches(t *testing.T) { t.Fatalf("DeleteWorker(%s) from store: %v", workerName, err) } - suspended, err := tc.client.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + suspended, err := tc.client.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }) if err != nil { t.Fatalf("SuspendActor failed: %v", err) } - if got := suspended.GetActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := suspended.GetActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state = %v, want SUSPENDED", got) } assertDetachedNodes(t, plugin, "after suspend", "node1") @@ -249,13 +249,13 @@ func TestRevertActor_Crashed_DetachesAssignedNode(t *testing.T) { tc.fakeAtelet.TerminateCalled = false tc.fakeAtelet.Lock.Unlock() - reverted, err := tc.client.RevertActor(context.Background(), &ateapipb.RevertActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + reverted, err := tc.client.RevertActor(context.Background(), &ateapi.RevertActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("RevertActor failed: %v", err) } - if got := reverted.GetActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := reverted.GetActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state = %v, want SUSPENDED", got) } assertDetachedNodes(t, plugin, "after revert", "node1") @@ -297,13 +297,13 @@ func TestRevertActor_WorkerNoLongerHosts_Detaches(t *testing.T) { tc.fakeAtelet.TerminateCalled = false tc.fakeAtelet.Lock.Unlock() - reverted, err := tc.client.RevertActor(context.Background(), &ateapipb.RevertActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + reverted, err := tc.client.RevertActor(context.Background(), &ateapi.RevertActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }) if err != nil { t.Fatalf("RevertActor failed: %v", err) } - if got := reverted.GetActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := reverted.GetActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state = %v, want SUSPENDED", got) } assertDetachedNodes(t, plugin, "after revert", "node1") diff --git a/cmd/ateapi/internal/controlapi/functionaltest/atespace_test.go b/cmd/ateapi/internal/controlapi/functionaltest/atespace_test.go index 58a0636376..acdeccb723 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/atespace_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/atespace_test.go @@ -20,7 +20,7 @@ import ( "time" "github.com/google/go-cmp/cmp" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/grpc/codes" "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/timestamppb" @@ -32,9 +32,9 @@ func TestCreateAtespace_Success(t *testing.T) { defer tc.cleanup() createTemplate(t, tc, ns) - resp, err := tc.client.CreateAtespace(context.Background(), &ateapipb.CreateAtespaceRequest{ - Atespace: &ateapipb.Atespace{ - Metadata: &ateapipb.ResourceMetadata{ + resp, err := tc.client.CreateAtespace(context.Background(), &ateapi.CreateAtespaceRequest{ + Atespace: &ateapi.Atespace{ + Metadata: &ateapi.ResourceMetadata{ Name: "team-a", Uid: "caller-supplied-uid", Version: 999, @@ -60,12 +60,12 @@ func TestCreateAtespace_Success(t *testing.T) { t.Errorf("uid = %q, want a server-generated value", md.GetUid()) } - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "team-a", Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Errorf("CreateActor into freshly created atespace failed: %v", err) } @@ -76,10 +76,10 @@ func TestCreateAtespace_AlreadyExists(t *testing.T) { tc := setupTest(t, ns) defer tc.cleanup() - if _, err := tc.client.CreateAtespace(context.Background(), &ateapipb.CreateAtespaceRequest{Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "team-a"}}}); err != nil { + if _, err := tc.client.CreateAtespace(context.Background(), &ateapi.CreateAtespaceRequest{Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "team-a"}}}); err != nil { t.Fatalf("first CreateAtespace failed: %v", err) } - _, err := tc.client.CreateAtespace(context.Background(), &ateapipb.CreateAtespaceRequest{Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "team-a"}}}) + _, err := tc.client.CreateAtespace(context.Background(), &ateapi.CreateAtespaceRequest{Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "team-a"}}}) assertGrpcError(t, err, codes.AlreadyExists, "Atespace team-a already exists") } @@ -88,11 +88,11 @@ func TestGetAtespace_Found(t *testing.T) { tc := setupTest(t, ns) defer tc.cleanup() - created, err := tc.client.CreateAtespace(context.Background(), &ateapipb.CreateAtespaceRequest{Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "team-a"}}}) + created, err := tc.client.CreateAtespace(context.Background(), &ateapi.CreateAtespaceRequest{Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "team-a"}}}) if err != nil { t.Fatalf("CreateAtespace failed: %v", err) } - resp, err := tc.client.GetAtespace(context.Background(), &ateapipb.GetAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}}) + resp, err := tc.client.GetAtespace(context.Background(), &ateapi.GetAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}}) if err != nil { t.Fatalf("GetAtespace failed: %v", err) } @@ -106,7 +106,7 @@ func TestGetAtespace_NotFound(t *testing.T) { tc := setupTest(t, ns) defer tc.cleanup() - _, err := tc.client.GetAtespace(context.Background(), &ateapipb.GetAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "nope"}}) + _, err := tc.client.GetAtespace(context.Background(), &ateapi.GetAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "nope"}}) assertGrpcError(t, err, codes.NotFound, "Atespace nope not found") } @@ -116,11 +116,11 @@ func TestListAtespaces(t *testing.T) { defer tc.cleanup() for _, n := range []string{"team-a", "team-b"} { - if _, err := tc.client.CreateAtespace(context.Background(), &ateapipb.CreateAtespaceRequest{Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: n}}}); err != nil { + if _, err := tc.client.CreateAtespace(context.Background(), &ateapi.CreateAtespaceRequest{Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: n}}}); err != nil { t.Fatalf("CreateAtespace(%s) failed: %v", n, err) } } - resp, err := tc.client.ListAtespaces(context.Background(), &ateapipb.ListAtespacesRequest{}) + resp, err := tc.client.ListAtespaces(context.Background(), &ateapi.ListAtespacesRequest{}) if err != nil { t.Fatalf("ListAtespaces failed: %v", err) } @@ -141,10 +141,10 @@ func TestDeleteAtespace_Empty_Success(t *testing.T) { tc := setupTest(t, ns) defer tc.cleanup() - if _, err := tc.client.CreateAtespace(context.Background(), &ateapipb.CreateAtespaceRequest{Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "team-a"}}}); err != nil { + if _, err := tc.client.CreateAtespace(context.Background(), &ateapi.CreateAtespaceRequest{Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "team-a"}}}); err != nil { t.Fatalf("CreateAtespace failed: %v", err) } - deleted, err := tc.client.DeleteAtespace(context.Background(), &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}}) + deleted, err := tc.client.DeleteAtespace(context.Background(), &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}}) if err != nil { t.Fatalf("DeleteAtespace failed: %v", err) } @@ -156,7 +156,7 @@ func TestDeleteAtespace_Empty_Success(t *testing.T) { t.Errorf("the deleted atespace carries no delete_time") } - _, err = tc.client.GetAtespace(context.Background(), &ateapipb.GetAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}}) + _, err = tc.client.GetAtespace(context.Background(), &ateapi.GetAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}}) assertGrpcError(t, err, codes.NotFound, "Atespace team-a not found") } @@ -166,19 +166,19 @@ func TestDeleteAtespace_NonEmpty_Rejected(t *testing.T) { defer tc.cleanup() createTemplate(t, tc, ns) - if _, err := tc.client.CreateAtespace(context.Background(), &ateapipb.CreateAtespaceRequest{Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "team-a"}}}); err != nil { + if _, err := tc.client.CreateAtespace(context.Background(), &ateapi.CreateAtespaceRequest{Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "team-a"}}}); err != nil { t.Fatalf("CreateAtespace failed: %v", err) } - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - _, err := tc.client.DeleteAtespace(context.Background(), &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}}) + _, err := tc.client.DeleteAtespace(context.Background(), &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}}) assertGrpcError(t, err, codes.FailedPrecondition, "Atespace team-a is not empty") // The atespace must survive a rejected delete. - if _, err := tc.client.GetAtespace(context.Background(), &ateapipb.GetAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}}); err != nil { + if _, err := tc.client.GetAtespace(context.Background(), &ateapi.GetAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}}); err != nil { t.Errorf("atespace should survive a rejected delete, got %v", err) } } @@ -195,19 +195,19 @@ func TestDeleteAtespace_ScopedToTargetAtespace(t *testing.T) { createAtespace(t, tc, "team-b") // Actor only in team-b. - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-b", Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-b", Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } // Empty team-a deletes fine despite team-b holding an actor. - if _, err := tc.client.DeleteAtespace(context.Background(), &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}}); err != nil { + if _, err := tc.client.DeleteAtespace(context.Background(), &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}}); err != nil { t.Errorf("DeleteAtespace(team-a, empty) failed: %v", err) } // team-b is still non-empty → rejected. - _, err := tc.client.DeleteAtespace(context.Background(), &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "team-b"}}) + _, err := tc.client.DeleteAtespace(context.Background(), &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "team-b"}}) assertGrpcError(t, err, codes.FailedPrecondition, "Atespace team-b is not empty") } @@ -216,7 +216,7 @@ func TestDeleteAtespace_NotFound(t *testing.T) { tc := setupTest(t, ns) defer tc.cleanup() - _, err := tc.client.DeleteAtespace(context.Background(), &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: "nope"}}) + _, err := tc.client.DeleteAtespace(context.Background(), &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: "nope"}}) assertGrpcError(t, err, codes.NotFound, "Atespace nope not found") } @@ -226,27 +226,27 @@ func TestValidation_Atespace(t *testing.T) { defer tc.cleanup() t.Run("ListAtespaces", func(t *testing.T) { - _, err := tc.client.ListAtespaces(context.Background(), &ateapipb.ListAtespacesRequest{Options: &ateapipb.ListOptions{PageSize: -1}}) + _, err := tc.client.ListAtespaces(context.Background(), &ateapi.ListAtespacesRequest{Options: &ateapi.ListOptions{PageSize: -1}}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "page_size: Invalid value") }) t.Run("ListAtespaces invalid token", func(t *testing.T) { - _, err := tc.client.ListAtespaces(context.Background(), &ateapipb.ListAtespacesRequest{Options: &ateapipb.ListOptions{PageToken: "%%%"}}) + _, err := tc.client.ListAtespaces(context.Background(), &ateapi.ListAtespacesRequest{Options: &ateapi.ListOptions{PageToken: "%%%"}}) assertGrpcError(t, err, codes.InvalidArgument, "invalid page_token") }) t.Run("CreateAtespace", func(t *testing.T) { - _, err := tc.client.CreateAtespace(context.Background(), &ateapipb.CreateAtespaceRequest{}) + _, err := tc.client.CreateAtespace(context.Background(), &ateapi.CreateAtespaceRequest{}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "atespace: Required value") }) t.Run("GetAtespace", func(t *testing.T) { - _, err := tc.client.GetAtespace(context.Background(), &ateapipb.GetAtespaceRequest{}) + _, err := tc.client.GetAtespace(context.Background(), &ateapi.GetAtespaceRequest{}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "atespace: Required value") }) t.Run("DeleteAtespace", func(t *testing.T) { - _, err := tc.client.DeleteAtespace(context.Background(), &ateapipb.DeleteAtespaceRequest{}) + _, err := tc.client.DeleteAtespace(context.Background(), &ateapi.DeleteAtespaceRequest{}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "atespace: Required value") }) } @@ -256,41 +256,41 @@ func TestDeleteAtespace_Preconditions(t *testing.T) { tc := setupTest(t, ns) defer tc.cleanup() ctx := context.Background() - ref := &ateapipb.ObjectRef{Name: "team-a"} - create := func() *ateapipb.Atespace { - created, err := tc.client.CreateAtespace(ctx, &ateapipb.CreateAtespaceRequest{Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: ref.GetName()}}}) + ref := &ateapi.ObjectRef{Name: "team-a"} + create := func() *ateapi.Atespace { + created, err := tc.client.CreateAtespace(ctx, &ateapi.CreateAtespaceRequest{Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: ref.GetName()}}}) if err != nil { t.Fatalf("CreateAtespace failed: %v", err) } return created } - del := func(opts *ateapipb.DeleteOptions) error { - _, err := tc.client.DeleteAtespace(ctx, &ateapipb.DeleteAtespaceRequest{Atespace: ref, Options: opts}) + del := func(opts *ateapi.DeleteOptions) error { + _, err := tc.client.DeleteAtespace(ctx, &ateapi.DeleteAtespaceRequest{Atespace: ref, Options: opts}) return err } atespace := create() uid, version := atespace.GetMetadata().GetUid(), atespace.GetMetadata().GetVersion() - assertGrpcError(t, del(&ateapipb.DeleteOptions{Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: uid, Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: foreignUID}), codes.Aborted, "Atespace team-a does not have uid "+foreignUID) - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: foreignUID, Version: version}), codes.Aborted, "Atespace team-a does not have uid "+foreignUID) - if _, err := tc.client.GetAtespace(ctx, &ateapipb.GetAtespaceRequest{Atespace: ref}); err != nil { + assertGrpcError(t, del(&ateapi.DeleteOptions{Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: uid, Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: foreignUID}), codes.Aborted, "Atespace team-a does not have uid "+foreignUID) + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: foreignUID, Version: version}), codes.Aborted, "Atespace team-a does not have uid "+foreignUID) + if _, err := tc.client.GetAtespace(ctx, &ateapi.GetAtespaceRequest{Atespace: ref}); err != nil { t.Fatalf("a refused delete removed the atespace: %v", err) } - if err := del(&ateapipb.DeleteOptions{Version: version}); err != nil { + if err := del(&ateapi.DeleteOptions{Version: version}); err != nil { t.Fatalf("DeleteAtespace with the matching version: %v", err) } atespace = create() - if err := del(&ateapipb.DeleteOptions{Uid: atespace.GetMetadata().GetUid()}); err != nil { + if err := del(&ateapi.DeleteOptions{Uid: atespace.GetMetadata().GetUid()}); err != nil { t.Fatalf("DeleteAtespace with the matching uid: %v", err) } atespace = create() - if err := del(&ateapipb.DeleteOptions{Uid: atespace.GetMetadata().GetUid(), Version: atespace.GetMetadata().GetVersion()}); err != nil { + if err := del(&ateapi.DeleteOptions{Uid: atespace.GetMetadata().GetUid(), Version: atespace.GetMetadata().GetVersion()}); err != nil { t.Fatalf("DeleteAtespace with both guards: %v", err) } - _, err := tc.client.GetAtespace(ctx, &ateapipb.GetAtespaceRequest{Atespace: ref}) + _, err := tc.client.GetAtespace(ctx, &ateapi.GetAtespaceRequest{Atespace: ref}) assertGrpcError(t, err, codes.NotFound, "Atespace team-a not found") } diff --git a/cmd/ateapi/internal/controlapi/functionaltest/common_test.go b/cmd/ateapi/internal/controlapi/functionaltest/common_test.go index 03b8a777bc..cb950eb5c7 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/common_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/common_test.go @@ -22,6 +22,8 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/ateapi/internal/controlapi" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" @@ -35,10 +37,8 @@ import ( "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/volume" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" "go.ate.dev/substrate/pkg/client/clientset/versioned" "go.ate.dev/substrate/pkg/client/informers/externalversions" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel/attribute" sdkmetric "go.opentelemetry.io/otel/sdk/metric" sdktrace "go.opentelemetry.io/otel/sdk/trace" @@ -73,18 +73,18 @@ const ( ) var ( - ignoreUID = protocmp.IgnoreFields(&ateapipb.ResourceMetadata{}, "uid") - ignoreVersion = protocmp.IgnoreFields(&ateapipb.ResourceMetadata{}, "version") - ignoreTimestamps = protocmp.IgnoreFields(&ateapipb.ResourceMetadata{}, "create_time", "update_time", "delete_time") + ignoreUID = protocmp.IgnoreFields(&ateapi.ResourceMetadata{}, "uid") + ignoreVersion = protocmp.IgnoreFields(&ateapi.ResourceMetadata{}, "version") + ignoreTimestamps = protocmp.IgnoreFields(&ateapi.ResourceMetadata{}, "create_time", "update_time", "delete_time") // ignoreServerMetadata skips the ResourceMetadata fields the store assigns. - ignoreServerMetadata = protocmp.IgnoreFields(&ateapipb.ResourceMetadata{}, "uid", "create_time", "update_time", "delete_time") + ignoreServerMetadata = protocmp.IgnoreFields(&ateapi.ResourceMetadata{}, "uid", "create_time", "update_time", "delete_time") ) type testContext struct { service *controlapi.RPCService - client ateapipb.ControlClient - noOptInClient ateapipb.ControlClient // never sends preview.Header + client ateapi.ControlClient + noOptInClient ateapi.ControlClient // never sends preview.Header k8sClient kubernetes.Interface substrateClient versioned.Interface persistence store.Interface @@ -159,7 +159,7 @@ func setupTestWithOptions(t *testing.T, ns string, options testOptions) *testCon scLister := scFactory.Storage().V1().StorageClasses().Lister() substrateInformerFactory := externalversions.NewSharedInformerFactory(substrateClient, 0) - csiDriverConfigLister := substrateInformerFactory.Api().V1alpha1().CSIDriverConfigs().Lister() + csiDriverConfigLister := substrateInformerFactory.Ate().V1().CSIDriverConfigs().Lister() ctx, cancel := context.WithCancel(context.Background()) @@ -254,7 +254,7 @@ func setupTestWithOptions(t *testing.T, ns string, options testOptions) *testCon ateinterceptors.RejectUnknownFieldsUnaryInterceptor, preview.UnaryServerInterceptor, )) - ateapipb.RegisterControlServer(grpcServer, service) + ateapi.RegisterControlServer(grpcServer, service) lis := bufconn.Listen(8192) @@ -287,7 +287,7 @@ func setupTestWithOptions(t *testing.T, ns string, options testOptions) *testCon } t.Cleanup(func() { noOptInConn.Close() }) - client := ateapipb.NewControlClient(conn) + client := ateapi.NewControlClient(conn) // Call Reset on global mock fakeAtelet.Reset() @@ -308,7 +308,7 @@ func setupTestWithOptions(t *testing.T, ns string, options testOptions) *testCon } // CreateActor now requires the atespace to exist first. - if _, err := client.CreateAtespace(context.Background(), &ateapipb.CreateAtespaceRequest{Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: testAtespace}}}); err != nil { + if _, err := client.CreateAtespace(context.Background(), &ateapi.CreateAtespaceRequest{Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: testAtespace}}}); err != nil { conn.Close() grpcServer.Stop() cancel() @@ -326,7 +326,7 @@ func setupTestWithOptions(t *testing.T, ns string, options testOptions) *testCon return &testContext{ service: service, client: client, - noOptInClient: ateapipb.NewControlClient(noOptInConn), + noOptInClient: ateapi.NewControlClient(noOptInConn), k8sClient: k8sClient, substrateClient: substrateClient, persistence: persistence, @@ -385,7 +385,7 @@ func goldenSnapshotURI(t *testing.T) string { // prefix. That is what says the actor took the snapshot itself rather than // borrowing it from a tag, and so what decides whether its suspends and its // delete may collect it. -func snapshotOwnedByActor(t *testing.T, actor *ateapipb.Actor, snapshotURI string) bool { +func snapshotOwnedByActor(t *testing.T, actor *ateapi.Actor, snapshotURI string) bool { t.Helper() uri, err := resources.ParseSnapshotURI(snapshotURI) if err != nil { @@ -396,7 +396,7 @@ func snapshotOwnedByActor(t *testing.T, actor *ateapipb.Actor, snapshotURI strin // assertSnapshotOwnedByActor fails when snapshotURI is not under the actor's // own prefix. -func assertSnapshotOwnedByActor(t *testing.T, actor *ateapipb.Actor, snapshotURI string) { +func assertSnapshotOwnedByActor(t *testing.T, actor *ateapi.Actor, snapshotURI string) { t.Helper() if !snapshotOwnedByActor(t, actor, snapshotURI) { t.Errorf("external snapshot %s is not under actor %s's own prefix, want it owned by the actor", snapshotURI, resources.ActorRefFromActor(actor)) @@ -418,9 +418,9 @@ func namespaceForTest(baseName string) string { return fmt.Sprintf("%s-%d", baseName, time.Now().UnixNano()) } -func createTemplate(t *testing.T, tc *testContext, ns string) *ateapipb.ActorTemplate { +func createTemplate(t *testing.T, tc *testContext, ns string) *ateapi.ActorTemplate { t.Helper() - return createTemplateWithContainers(t, tc, ns, []*ateapipb.Container{ + return createTemplateWithContainers(t, tc, ns, []*ateapi.Container{ { Name: "main", Image: "main@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", @@ -432,21 +432,21 @@ func createTemplate(t *testing.T, tc *testContext, ns string) *ateapipb.ActorTem // createAtespace creates an atespace via the API. func createAtespace(t *testing.T, tc *testContext, name string) { t.Helper() - if _, err := tc.client.CreateAtespace(context.Background(), &ateapipb.CreateAtespaceRequest{Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: name}}}); err != nil { + if _, err := tc.client.CreateAtespace(context.Background(), &ateapi.CreateAtespaceRequest{Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: name}}}); err != nil { t.Fatalf("CreateAtespace(%s) failed: %v", name, err) } } const poolLabelKey = "pool" -func createTemplateWithContainers(t *testing.T, tc *testContext, ns string, containers []*ateapipb.Container) *ateapipb.ActorTemplate { +func createTemplateWithContainers(t *testing.T, tc *testContext, ns string, containers []*ateapi.Container) *ateapi.ActorTemplate { t.Helper() return createTemplateWithContainersAndVolumes(t, tc, ns, containers, nil) } -func createTemplateWithVolumes(t *testing.T, tc *testContext, ns string, volumes []*ateapipb.Volume, mounts []*ateapipb.VolumeMount) *ateapipb.ActorTemplate { +func createTemplateWithVolumes(t *testing.T, tc *testContext, ns string, volumes []*ateapi.Volume, mounts []*ateapi.VolumeMount) *ateapi.ActorTemplate { t.Helper() - return createTemplateWithContainersAndVolumes(t, tc, ns, []*ateapipb.Container{ + return createTemplateWithContainersAndVolumes(t, tc, ns, []*ateapi.Container{ { Name: "main", Image: "main@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", @@ -460,38 +460,38 @@ func createTemplateWithVolumes(t *testing.T, tc *testContext, ns string, volumes // "tmpl1" in testAtespace, backed by a WorkerPool in ns whose labels match the // template's worker selector, and seeds its golden snapshot. ns keys the pool // labels, so each test's template still selects only its own pool. -func createTemplateWithContainersAndVolumes(t *testing.T, tc *testContext, ns string, containers []*ateapipb.Container, volumes []*ateapipb.Volume) *ateapipb.ActorTemplate { +func createTemplateWithContainersAndVolumes(t *testing.T, tc *testContext, ns string, containers []*ateapi.Container, volumes []*ateapi.Volume) *ateapi.ActorTemplate { t.Helper() createWorkerPool(t, tc, ns, "pool1", map[string]string{poolLabelKey: ns}) - created, err := tc.client.CreateActorTemplate(context.Background(), &ateapipb.CreateActorTemplateRequest{ - ActorTemplate: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{ + created, err := tc.client.CreateActorTemplate(context.Background(), &ateapi.CreateActorTemplateRequest{ + ActorTemplate: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{ Atespace: testAtespace, Name: "tmpl1", }, - SnapshotConfig: &ateapipb.SnapshotConfig{ + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: testStorageLocation, }, Containers: containers, Volumes: volumes, - WorkerSelector: &ateapipb.Selector{ + WorkerSelector: &ateapi.Selector{ MatchLabels: map[string]string{poolLabelKey: ns}, }, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, }, }) if err != nil { t.Fatalf("failed to create actor template: %v", err) } - tag, err := tc.persistence.CreateTag(context.Background(), &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: created.GetMetadata().GetUid()}, - SourceActor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: created.GetMetadata().GetUid()}, - Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED, - Status: &ateapipb.TagStatus{ - Snapshot: newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, created.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)), + tag, err := tc.persistence.CreateTag(context.Background(), &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: created.GetMetadata().GetUid()}, + SourceActor: &ateapi.ObjectRef{Atespace: testAtespace, Name: created.GetMetadata().GetUid()}, + Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED, + Status: &ateapi.TagStatus{ + Snapshot: newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, created.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)), ActorTemplateUid: created.GetMetadata().GetUid(), }, }) @@ -504,9 +504,9 @@ func createTemplateWithContainersAndVolumes(t *testing.T, tc *testContext, ns st // status RPC, and the reconciler does not run in this test environment. updated, err := tc.persistence.UpdateActorTemplate(context.Background(), resources.ActorTemplateRefFromActorTemplate(created), store.PreconditionFrom(created), - func(dbTemplate *ateapipb.ActorTemplate) error { - dbTemplate.Status = &ateapipb.ActorTemplateStatus{ - GoldenSnapshotStatus: &ateapipb.GoldenSnapshotStatus{ + func(dbTemplate *ateapi.ActorTemplate) error { + dbTemplate.Status = &ateapi.ActorTemplateStatus{ + GoldenSnapshotStatus: &ateapi.GoldenSnapshotStatus{ GoldenTag: resources.TagRefFromTag(tag).ToObjectRef(), }, } @@ -518,16 +518,16 @@ func createTemplateWithContainersAndVolumes(t *testing.T, tc *testContext, ns st return updated } -func newDurableSnapshot(gen int32, owner ateapipb.SnapshotOwner, fidelity ateapipb.SnapshotFidelity, templateUID, uuid, uri string) *ateapipb.Snapshot { - return &ateapipb.Snapshot{ +func newDurableSnapshot(gen int32, owner ateapi.SnapshotOwner, fidelity ateapi.SnapshotFidelity, templateUID, uuid, uri string) *ateapi.Snapshot { + return &ateapi.Snapshot{ Uuid: uuid, Generation: gen, Owner: owner, Fidelity: fidelity, ActorTemplateUid: templateUID, - DurableSnapshot: &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: uri}, + DurableSnapshot: &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, + Object: &ateapi.ObjectSnapshot{SnapshotUri: uri}, }, } } @@ -535,31 +535,31 @@ func newDurableSnapshot(gen int32, owner ateapipb.SnapshotOwner, fidelity ateapi // newPausedSnapshot is the snapshot an asynchronous suspend leaves on node // locality: its durable copy, under the actor's own prefix, is PENDING until // atelet uploads it. -func newPausedSnapshot(t *testing.T, gen int32, fidelity ateapipb.SnapshotFidelity, templateUID, actorUID, uuid, locality string) *ateapipb.Snapshot { +func newPausedSnapshot(t *testing.T, gen int32, fidelity ateapi.SnapshotFidelity, templateUID, actorUID, uuid, locality string) *ateapi.Snapshot { t.Helper() uri, err := resources.NewActorSnapshotURI(testStorageLocation, testAtespace, actorUID, uuid) if err != nil { t.Fatalf("NewActorSnapshotURI: %v", err) } - return &ateapipb.Snapshot{ + return &ateapi.Snapshot{ Uuid: uuid, Generation: gen, - Owner: ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, + Owner: ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, Fidelity: fidelity, ActorTemplateUid: templateUID, Locality: locality, - DurableSnapshot: &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: uri.String()}, + DurableSnapshot: &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING, + Object: &ateapi.ObjectSnapshot{SnapshotUri: uri.String()}, }, } } -func durableSnapshot(status *ateapipb.ActorStatus) *ateapipb.Snapshot { - var best *ateapipb.Snapshot +func durableSnapshot(status *ateapi.ActorStatus) *ateapi.Snapshot { + var best *ateapi.Snapshot for _, snap := range status.GetSnapshots() { st := snap.GetDurableSnapshot() - if st.GetStatus() == ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED && + if st.GetStatus() == ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED && st.GetObject().GetSnapshotUri() != "" { if best == nil || snap.GetGeneration() > best.GetGeneration() { best = snap @@ -569,16 +569,16 @@ func durableSnapshot(status *ateapipb.ActorStatus) *ateapipb.Snapshot { return best } -func durableSnapshotStorage(status *ateapipb.ActorStatus) *ateapipb.SnapshotStorage { +func durableSnapshotStorage(status *ateapi.ActorStatus) *ateapi.SnapshotStorage { return durableSnapshot(status).GetDurableSnapshot() } -func durableSnapshotURI(status *ateapipb.ActorStatus) string { +func durableSnapshotURI(status *ateapi.ActorStatus) string { return durableSnapshotStorage(status).GetObject().GetSnapshotUri() } -func localSnapshot(status *ateapipb.ActorStatus) *ateapipb.Snapshot { - var best *ateapipb.Snapshot +func localSnapshot(status *ateapi.ActorStatus) *ateapi.Snapshot { + var best *ateapi.Snapshot for _, snap := range status.GetSnapshots() { if snap.GetLocality() != "" && snap.GetUuid() != "" { if best == nil || snap.GetGeneration() > best.GetGeneration() { @@ -589,47 +589,47 @@ func localSnapshot(status *ateapipb.ActorStatus) *ateapipb.Snapshot { return best } -func tagSnapshotURI(tag *ateapipb.Tag) string { +func tagSnapshotURI(tag *ateapi.Tag) string { return tag.GetStatus().GetSnapshot().GetDurableSnapshot().GetObject().GetSnapshotUri() } func createWorkerPool(t *testing.T, tc *testContext, ns string, name string, labels map[string]string) { t.Helper() - wp := &atev1alpha1.WorkerPool{ + wp := &atev1.WorkerPool{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: ns, Labels: labels, }, - Spec: atev1alpha1.WorkerPoolSpec{ + Spec: atev1.WorkerPoolSpec{ Replicas: 1, WorkerImage: "worker@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - SandboxClasses: []atev1alpha1.WorkerPoolSandboxClass{{Name: atev1alpha1.SandboxClassGvisor}}, + SandboxClasses: []atev1.WorkerPoolSandboxClass{{Name: atev1.SandboxClassGvisor}}, }, } - if _, err := tc.substrateClient.ApiV1alpha1().WorkerPools(ns).Create(context.Background(), wp, metav1.CreateOptions{}); err != nil { + if _, err := tc.substrateClient.AteV1().WorkerPools(ns).Create(context.Background(), wp, metav1.CreateOptions{}); err != nil { t.Fatalf("failed to create WorkerPool: %v", err) } } // createTemplateWithSelector creates a substrate ActorTemplate in // testAtespace with the given worker selector and no golden snapshot. -func createTemplateWithSelector(t *testing.T, tc *testContext, name string, selector *ateapipb.Selector) *ateapipb.ActorTemplate { +func createTemplateWithSelector(t *testing.T, tc *testContext, name string, selector *ateapi.Selector) *ateapi.ActorTemplate { t.Helper() - created, err := tc.client.CreateActorTemplate(context.Background(), &ateapipb.CreateActorTemplateRequest{ - ActorTemplate: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{ + created, err := tc.client.CreateActorTemplate(context.Background(), &ateapi.CreateActorTemplateRequest{ + ActorTemplate: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{ Atespace: testAtespace, Name: name, }, - SnapshotConfig: &ateapipb.SnapshotConfig{ + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: testStorageLocation, }, - Containers: []*ateapipb.Container{ + Containers: []*ateapi.Container{ {Name: "main", Image: "main@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", Command: []string{"/main"}}, }, WorkerSelector: selector, - Resources: &ateapipb.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, + Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, }, }) if err != nil { @@ -679,14 +679,14 @@ func createWorkerPod(t *testing.T, tc *testContext, ns string, name string, node } // The WorkerPool supplies the fields the syncer copies off it. - pool, err := tc.substrateClient.ApiV1alpha1().WorkerPools(ns).Get(context.Background(), poolName, metav1.GetOptions{}) + pool, err := tc.substrateClient.AteV1().WorkerPools(ns).Get(context.Background(), poolName, metav1.GetOptions{}) if err != nil { t.Fatalf("failed to get WorkerPool %s/%s: %v", ns, poolName, err) } - if _, err := tc.client.CreateWorker(context.Background(), &ateapipb.CreateWorkerRequest{ - Worker: &ateapipb.Worker{ + if _, err := tc.client.CreateWorker(context.Background(), &ateapi.CreateWorkerRequest{ + Worker: &ateapi.Worker{ // Workers are global-scoped and named after the pod UID. - Metadata: &ateapipb.ResourceMetadata{Name: string(createdPod.UID)}, + Metadata: &ateapi.ResourceMetadata{Name: string(createdPod.UID)}, WorkerNamespace: ns, WorkerPool: poolName, WorkerPod: name, @@ -702,8 +702,8 @@ func createWorkerPod(t *testing.T, tc *testContext, ns string, name string, node t.Fatalf("failed to register worker: %v", err) } // As the syncer does once the pod is Ready. - if _, err := tc.client.MarkWorkerAvailable(context.Background(), &ateapipb.MarkWorkerAvailableRequest{ - Worker: &ateapipb.ObjectRef{Name: string(createdPod.UID)}, + if _, err := tc.client.MarkWorkerAvailable(context.Background(), &ateapi.MarkWorkerAvailableRequest{ + Worker: &ateapi.ObjectRef{Name: string(createdPod.UID)}, }); err != nil { t.Fatalf("failed to mark worker available: %v", err) } @@ -740,7 +740,7 @@ func waitForWorkerAvailable(t *testing.T, tc *testContext, workerName string) { } // Hosting nothing is what "available" means, and the allocation total // is how a cached Worker reports it: it does not carry the records. - return worker.GetStatus().GetState() == ateapipb.WorkerState_WORKER_STATE_ACTIVE && + return worker.GetStatus().GetState() == ateapi.WorkerState_WORKER_STATE_ACTIVE && worker.GetStatus().GetAllocated().GetActors() == 0, nil }) if err != nil { @@ -825,7 +825,7 @@ func deleteWorkerPod(t *testing.T, tc *testContext, ns string, name string) { // Deregister the Worker, as the syncer would once it saw the pod go. The // Worker is named after the pod UID, but the caller only has the pod name, // so it is found by the pod fields it carries. - resp, err := tc.client.ListWorkers(context.Background(), &ateapipb.ListWorkersRequest{}) + resp, err := tc.client.ListWorkers(context.Background(), &ateapi.ListWorkersRequest{}) if err != nil { t.Fatalf("failed to list workers: %v", err) } @@ -833,8 +833,8 @@ func deleteWorkerPod(t *testing.T, tc *testContext, ns string, name string) { if w.GetWorkerNamespace() != ns || w.GetWorkerPod() != name { continue } - if _, err := tc.client.DeleteWorker(context.Background(), &ateapipb.DeleteWorkerRequest{ - Worker: &ateapipb.ObjectRef{Name: w.GetMetadata().GetName()}, + if _, err := tc.client.DeleteWorker(context.Background(), &ateapi.DeleteWorkerRequest{ + Worker: &ateapi.ObjectRef{Name: w.GetMetadata().GetName()}, }); err != nil { t.Fatalf("failed to deregister worker %s: %v", w.GetMetadata().GetName(), err) } diff --git a/cmd/ateapi/internal/controlapi/functionaltest/egress_policy_test.go b/cmd/ateapi/internal/controlapi/functionaltest/egress_policy_test.go index 1917594e52..231659aca3 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/egress_policy_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/egress_policy_test.go @@ -20,43 +20,43 @@ import ( "time" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/timestamppb" ) -func setupEgressPolicyActor(t *testing.T, testName string) (*testContext, *ateapipb.ObjectRef) { +func setupEgressPolicyActor(t *testing.T, testName string) (*testContext, *ateapi.ObjectRef) { t.Helper() ns := namespaceForTest(testName) tc := setupTest(t, ns) t.Cleanup(tc.cleanup) createTemplate(t, tc, ns) - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "egress-actor"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "egress-actor"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, } - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: actor}); err != nil { + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: actor}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - return tc, &ateapipb.ObjectRef{Atespace: testAtespace, Name: "egress-actor"} + return tc, &ateapi.ObjectRef{Atespace: testAtespace, Name: "egress-actor"} } -func functionalEgressPolicy() *ateapipb.EgressPolicy { - return &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "default"}, - Rules: []*ateapipb.EgressRule{{ - Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}}, +func functionalEgressPolicy() *ateapi.EgressPolicy { + return &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "default"}, + Rules: []*ateapi.EgressRule{{ + Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}}, }}, } } -func createEgressPolicy(t *testing.T, tc *testContext, actor *ateapipb.ObjectRef) *ateapipb.EgressPolicy { +func createEgressPolicy(t *testing.T, tc *testContext, actor *ateapi.ObjectRef) *ateapi.EgressPolicy { t.Helper() - created, err := tc.client.CreateActorEgressPolicy(context.Background(), &ateapipb.CreateActorEgressPolicyRequest{ + created, err := tc.client.CreateActorEgressPolicy(context.Background(), &ateapi.CreateActorEgressPolicyRequest{ Actor: actor, EgressPolicy: functionalEgressPolicy(), }) @@ -74,7 +74,7 @@ func TestCreateActorEgressPolicy_Success(t *testing.T) { policy.Metadata.CreateTime = timestamppb.New(time.Unix(1, 0)) policy.Metadata.UpdateTime = timestamppb.New(time.Unix(1, 0)) - created, err := tc.client.CreateActorEgressPolicy(context.Background(), &ateapipb.CreateActorEgressPolicyRequest{ + created, err := tc.client.CreateActorEgressPolicy(context.Background(), &ateapi.CreateActorEgressPolicyRequest{ Actor: actor, EgressPolicy: policy, }) @@ -95,7 +95,7 @@ func TestCreateActorEgressPolicy_Success(t *testing.T) { t.Errorf("timestamps = (%v, %v), want server-generated values", md.GetCreateTime(), md.GetUpdateTime()) } - got, err := tc.client.GetActorEgressPolicy(context.Background(), &ateapipb.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) + got, err := tc.client.GetActorEgressPolicy(context.Background(), &ateapi.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) if err != nil { t.Fatalf("GetActorEgressPolicy failed: %v", err) } @@ -108,14 +108,14 @@ func TestCreateActorEgressPolicy_Errors(t *testing.T) { tc, actor := setupEgressPolicyActor(t, "ns-create-egress-policy-errors") createEgressPolicy(t, tc, actor) - _, err := tc.client.CreateActorEgressPolicy(context.Background(), &ateapipb.CreateActorEgressPolicyRequest{ + _, err := tc.client.CreateActorEgressPolicy(context.Background(), &ateapi.CreateActorEgressPolicyRequest{ Actor: actor, EgressPolicy: functionalEgressPolicy(), }) assertGrpcError(t, err, codes.AlreadyExists, "EgressPolicy already exists") - _, err = tc.client.CreateActorEgressPolicy(context.Background(), &ateapipb.CreateActorEgressPolicyRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "missing-actor"}, + _, err = tc.client.CreateActorEgressPolicy(context.Background(), &ateapi.CreateActorEgressPolicyRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "missing-actor"}, EgressPolicy: functionalEgressPolicy(), }) assertGrpcError(t, err, codes.FailedPrecondition, "parent Actor does not exist") @@ -123,17 +123,17 @@ func TestCreateActorEgressPolicy_Errors(t *testing.T) { func TestGetActorEgressPolicy_NotFound(t *testing.T) { tc, actor := setupEgressPolicyActor(t, "ns-get-egress-policy-missing") - _, err := tc.client.GetActorEgressPolicy(context.Background(), &ateapipb.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) + _, err := tc.client.GetActorEgressPolicy(context.Background(), &ateapi.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) assertGrpcError(t, err, codes.NotFound, "EgressPolicy for actor "+actor.GetAtespace()+"/"+actor.GetName()+" not found") } func TestUpdateActorEgressPolicy(t *testing.T) { tc, actor := setupEgressPolicyActor(t, "ns-update-egress-policy") created := createEgressPolicy(t, tc, actor) - toUpdate := proto.Clone(created).(*ateapipb.EgressPolicy) - toUpdate.Rules = []*ateapipb.EgressRule{{TlsPassthrough: &ateapipb.TlsPassthroughRule{Hostnames: []string{"*"}, Ports: &ateapipb.Ports{Numbers: []int32{443}}}}} + toUpdate := proto.Clone(created).(*ateapi.EgressPolicy) + toUpdate.Rules = []*ateapi.EgressRule{{TlsPassthrough: &ateapi.TlsPassthroughRule{Hostnames: []string{"*"}, Ports: &ateapi.Ports{Numbers: []int32{443}}}}} - updated, err := tc.client.UpdateActorEgressPolicy(context.Background(), &ateapipb.UpdateActorEgressPolicyRequest{ + updated, err := tc.client.UpdateActorEgressPolicy(context.Background(), &ateapi.UpdateActorEgressPolicyRequest{ Actor: actor, EgressPolicy: toUpdate, }) @@ -153,7 +153,7 @@ func TestUpdateActorEgressPolicy(t *testing.T) { t.Errorf("updated rules = %v, want one tls_passthrough rule", updated.GetRules()) } - got, err := tc.client.GetActorEgressPolicy(context.Background(), &ateapipb.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) + got, err := tc.client.GetActorEgressPolicy(context.Background(), &ateapi.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) if err != nil { t.Fatalf("GetActorEgressPolicy failed: %v", err) } @@ -161,7 +161,7 @@ func TestUpdateActorEgressPolicy(t *testing.T) { t.Errorf("persisted policy mismatch (-updated +got):\n%s", diff) } - _, err = tc.client.UpdateActorEgressPolicy(context.Background(), &ateapipb.UpdateActorEgressPolicyRequest{ + _, err = tc.client.UpdateActorEgressPolicy(context.Background(), &ateapi.UpdateActorEgressPolicyRequest{ Actor: actor, EgressPolicy: toUpdate, }) @@ -172,18 +172,18 @@ func TestUpdateActorEgressPolicy_Preconditions(t *testing.T) { tc, actor := setupEgressPolicyActor(t, "ns-update-egress-policy-preconditions") created := createEgressPolicy(t, tc, actor) - unguarded := proto.Clone(created).(*ateapipb.EgressPolicy) + unguarded := proto.Clone(created).(*ateapi.EgressPolicy) unguarded.Metadata.Uid, unguarded.Metadata.Version = "", 0 - _, err := tc.client.UpdateActorEgressPolicy(context.Background(), &ateapipb.UpdateActorEgressPolicyRequest{Actor: actor, EgressPolicy: unguarded}) + _, err := tc.client.UpdateActorEgressPolicy(context.Background(), &ateapi.UpdateActorEgressPolicyRequest{Actor: actor, EgressPolicy: unguarded}) assertGrpcError(t, err, codes.InvalidArgument, "EgressPolicy UID and version are required") - wrongUID := proto.Clone(created).(*ateapipb.EgressPolicy) + wrongUID := proto.Clone(created).(*ateapi.EgressPolicy) wrongUID.Metadata.Uid = "9a2b1c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d" - _, err = tc.client.UpdateActorEgressPolicy(context.Background(), &ateapipb.UpdateActorEgressPolicyRequest{Actor: actor, EgressPolicy: wrongUID}) + _, err = tc.client.UpdateActorEgressPolicy(context.Background(), &ateapi.UpdateActorEgressPolicyRequest{Actor: actor, EgressPolicy: wrongUID}) assertGrpcError(t, err, codes.Aborted, "EgressPolicy UID conflict") - missingActor := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "missing-actor"} - _, err = tc.client.UpdateActorEgressPolicy(context.Background(), &ateapipb.UpdateActorEgressPolicyRequest{Actor: missingActor, EgressPolicy: created}) + missingActor := &ateapi.ObjectRef{Atespace: testAtespace, Name: "missing-actor"} + _, err = tc.client.UpdateActorEgressPolicy(context.Background(), &ateapi.UpdateActorEgressPolicyRequest{Actor: missingActor, EgressPolicy: created}) assertGrpcError(t, err, codes.NotFound, "EgressPolicy not found") } @@ -191,17 +191,17 @@ func TestDeleteActorEgressPolicy(t *testing.T) { tc, actor := setupEgressPolicyActor(t, "ns-delete-egress-policy") created := createEgressPolicy(t, tc, actor) - deleted, err := tc.client.DeleteActorEgressPolicy(context.Background(), &ateapipb.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) + deleted, err := tc.client.DeleteActorEgressPolicy(context.Background(), &ateapi.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) if err != nil { t.Fatalf("DeleteActorEgressPolicy failed: %v", err) } - if diff := cmp.Diff(created, deleted, protocmp.Transform(), protocmp.IgnoreFields(&ateapipb.ResourceMetadata{}, "delete_time")); diff != "" { + if diff := cmp.Diff(created, deleted, protocmp.Transform(), protocmp.IgnoreFields(&ateapi.ResourceMetadata{}, "delete_time")); diff != "" { t.Errorf("deleted policy mismatch (-created +deleted):\n%s", diff) } if deleted.GetMetadata().GetDeleteTime() == nil { t.Errorf("the deleted policy carries no delete_time") } - _, err = tc.client.DeleteActorEgressPolicy(context.Background(), &ateapipb.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) + _, err = tc.client.DeleteActorEgressPolicy(context.Background(), &ateapi.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) assertGrpcError(t, err, codes.NotFound, "EgressPolicy not found") } @@ -209,10 +209,10 @@ func TestDeleteActor_CascadesEgressPolicy(t *testing.T) { tc, actor := setupEgressPolicyActor(t, "ns-delete-actor-egress-policy") createEgressPolicy(t, tc, actor) - if _, err := tc.client.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{Actor: actor}); err != nil { + if _, err := tc.client.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{Actor: actor}); err != nil { t.Fatalf("DeleteActor failed: %v", err) } - _, err := tc.client.GetActorEgressPolicy(context.Background(), &ateapipb.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) + _, err := tc.client.GetActorEgressPolicy(context.Background(), &ateapi.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) assertGrpcError(t, err, codes.NotFound, "EgressPolicy for actor "+actor.GetAtespace()+"/"+actor.GetName()+" not found") } @@ -220,46 +220,46 @@ func TestValidation_ActorEgressPolicy(t *testing.T) { tc, _ := setupEgressPolicyActor(t, "ns-validation-egress-policy") ctx := context.Background() - _, err := tc.client.CreateActorEgressPolicy(ctx, &ateapipb.CreateActorEgressPolicyRequest{}) + _, err := tc.client.CreateActorEgressPolicy(ctx, &ateapi.CreateActorEgressPolicyRequest{}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "actor: Required value") - _, err = tc.client.GetActorEgressPolicy(ctx, &ateapipb.GetActorEgressPolicyRequest{}) + _, err = tc.client.GetActorEgressPolicy(ctx, &ateapi.GetActorEgressPolicyRequest{}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "actor: Required value") - _, err = tc.client.UpdateActorEgressPolicy(ctx, &ateapipb.UpdateActorEgressPolicyRequest{}) + _, err = tc.client.UpdateActorEgressPolicy(ctx, &ateapi.UpdateActorEgressPolicyRequest{}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "actor: Required value") - _, err = tc.client.DeleteActorEgressPolicy(ctx, &ateapipb.DeleteActorEgressPolicyRequest{}) + _, err = tc.client.DeleteActorEgressPolicy(ctx, &ateapi.DeleteActorEgressPolicyRequest{}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "actor: Required value") } func TestDeleteActorEgressPolicy_Preconditions(t *testing.T) { tc, actor := setupEgressPolicyActor(t, "ns-delete-egress-policy-preconditions") ctx := context.Background() - del := func(opts *ateapipb.DeleteOptions) error { - _, err := tc.client.DeleteActorEgressPolicy(ctx, &ateapipb.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName, Options: opts}) + del := func(opts *ateapi.DeleteOptions) error { + _, err := tc.client.DeleteActorEgressPolicy(ctx, &ateapi.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName, Options: opts}) return err } policy := createEgressPolicy(t, tc, actor) uid, version := policy.GetMetadata().GetUid(), policy.GetMetadata().GetVersion() - assertGrpcError(t, del(&ateapipb.DeleteOptions{Version: version + 1}), codes.Aborted, "EgressPolicy version conflict") - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: uid, Version: version + 1}), codes.Aborted, "EgressPolicy version conflict") - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: foreignUID}), codes.Aborted, "EgressPolicy UID conflict") - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: foreignUID, Version: version}), codes.Aborted, "EgressPolicy UID conflict") - if _, err := tc.client.GetActorEgressPolicy(ctx, &ateapipb.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}); err != nil { + assertGrpcError(t, del(&ateapi.DeleteOptions{Version: version + 1}), codes.Aborted, "EgressPolicy version conflict") + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: uid, Version: version + 1}), codes.Aborted, "EgressPolicy version conflict") + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: foreignUID}), codes.Aborted, "EgressPolicy UID conflict") + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: foreignUID, Version: version}), codes.Aborted, "EgressPolicy UID conflict") + if _, err := tc.client.GetActorEgressPolicy(ctx, &ateapi.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}); err != nil { t.Fatalf("a refused delete removed the policy: %v", err) } - if err := del(&ateapipb.DeleteOptions{Version: version}); err != nil { + if err := del(&ateapi.DeleteOptions{Version: version}); err != nil { t.Fatalf("DeleteActorEgressPolicy with the matching version: %v", err) } policy = createEgressPolicy(t, tc, actor) - if err := del(&ateapipb.DeleteOptions{Uid: policy.GetMetadata().GetUid()}); err != nil { + if err := del(&ateapi.DeleteOptions{Uid: policy.GetMetadata().GetUid()}); err != nil { t.Fatalf("DeleteActorEgressPolicy with the matching uid: %v", err) } policy = createEgressPolicy(t, tc, actor) - if err := del(&ateapipb.DeleteOptions{Uid: policy.GetMetadata().GetUid(), Version: policy.GetMetadata().GetVersion()}); err != nil { + if err := del(&ateapi.DeleteOptions{Uid: policy.GetMetadata().GetUid(), Version: policy.GetMetadata().GetVersion()}); err != nil { t.Fatalf("DeleteActorEgressPolicy with both guards: %v", err) } - _, err := tc.client.GetActorEgressPolicy(ctx, &ateapipb.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) + _, err := tc.client.GetActorEgressPolicy(ctx, &ateapi.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) assertGrpcError(t, err, codes.NotFound, "EgressPolicy for actor "+actor.GetAtespace()+"/"+actor.GetName()+" not found") } diff --git a/cmd/ateapi/internal/controlapi/functionaltest/tag_test.go b/cmd/ateapi/internal/controlapi/functionaltest/tag_test.go index 05f9736e4d..2091cf2535 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/tag_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/tag_test.go @@ -20,10 +20,10 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/testing/protocmp" ) @@ -32,13 +32,13 @@ import ( // a finished tag over a copy of it: the state CreateTag leaves // behind. actorName must be unique within the test, since a tag records the // actor it was taken from; opts adjust the tag before it is written. -func seedTag(t *testing.T, tc *testContext, actorName, tagName string, opts ...func(*ateapipb.Tag)) *ateapipb.Tag { +func seedTag(t *testing.T, tc *testContext, actorName, tagName string, opts ...func(*ateapi.Tag)) *ateapi.Tag { t.Helper() ctx := context.Background() - actor := storetest.MustCreateActor(t, ctx, tc.persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: actorName}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := storetest.MustCreateActor(t, ctx, tc.persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: actorName}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) // The actor's snapshot sits under its own prefix, keyed on the UID the store // assigns, so it can only be recorded once the row exists. @@ -46,10 +46,10 @@ func seedTag(t *testing.T, tc *testContext, actorName, tagName string, opts ...f if err != nil { t.Fatalf("NewActorSnapshotURI: %v", err) } - actor, err = tc.persistence.UpdateActor(ctx, resources.ActorRefFromActor(actor), store.PreconditionFrom(actor), func(toUpdate *ateapipb.Actor) error { + actor, err = tc.persistence.UpdateActor(ctx, resources.ActorRefFromActor(actor), store.PreconditionFrom(actor), func(toUpdate *ateapi.Actor) error { toUpdate.Status.LastAssignedGeneration = 1 - toUpdate.Status.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", actorSnapshotURI.Name(), actorSnapshotURI.String()), + toUpdate.Status.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", actorSnapshotURI.Name(), actorSnapshotURI.String()), } return nil }) @@ -60,12 +60,12 @@ func seedTag(t *testing.T, tc *testContext, actorName, tagName string, opts ...f if err != nil { t.Fatalf("NewTagSnapshotURI: %v", err) } - tag := &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: tagName}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, + tag := &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: tagName}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, SourceActor: resources.ActorRefFromActor(actor).ToObjectRef(), - Status: &ateapipb.TagStatus{ - Snapshot: newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, durableSnapshot(actor.GetStatus()).GetFidelity(), "", uri.Name(), uri.String()), + Status: &ateapi.TagStatus{ + Snapshot: newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, durableSnapshot(actor.GetStatus()).GetFidelity(), "", uri.Name(), uri.String()), }, } for _, opt := range opts { @@ -89,11 +89,11 @@ func TestCreateTag_ReusedTagName(t *testing.T) { // Actor A is suspended and tagged, the ordinary way. const tagName = "before-upgrade" actorFirstSnapshotURI := suspendActorForTest(t, tc, workerName, "actor-a") - first, err := tc.client.CreateTag(context.Background(), &ateapipb.CreateTagRequest{ - Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: tagName}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - SourceActor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-a"}, + first, err := tc.client.CreateTag(context.Background(), &ateapi.CreateTagRequest{ + Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: tagName}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + SourceActor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-a"}, }, }) if err != nil { @@ -112,19 +112,19 @@ func TestCreateTag_ReusedTagName(t *testing.T) { if secondSnapshotURI == actorFirstSnapshotURI { t.Fatalf("both actors suspended to %s, want distinct external snapshots", secondSnapshotURI) } - _, err = tc.client.CreateTag(context.Background(), &ateapipb.CreateTagRequest{ - Tag: &ateapipb.Tag{ + _, err = tc.client.CreateTag(context.Background(), &ateapi.CreateTagRequest{ + Tag: &ateapi.Tag{ // Same tagName that was written before. - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: tagName}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - SourceActor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-b"}, + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: tagName}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + SourceActor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-b"}, }, }) assertGrpcError(t, err, codes.AlreadyExists, fmt.Sprintf("Tag %s/%s already exists; delete it and create it again to retry", testAtespace, tagName)) // The row still contains actor A's tag - stored, err := tc.client.GetTag(context.Background(), &ateapipb.GetTagRequest{ - Tag: &ateapipb.ObjectRef{Atespace: testAtespace, Name: tagName}, + stored, err := tc.client.GetTag(context.Background(), &ateapi.GetTagRequest{ + Tag: &ateapi.ObjectRef{Atespace: testAtespace, Name: tagName}, }) if err != nil { t.Fatalf("GetTag failed: %v", err) @@ -140,11 +140,11 @@ func TestCreateTag_ReusedTagName(t *testing.T) { assertSnapshotPresent(t, tc, secondSnapshotURI) // The collision is not a dead end: a free name works. - if _, err := tc.client.CreateTag(context.Background(), &ateapipb.CreateTagRequest{ - Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "after-upgrade"}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - SourceActor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-b"}, + if _, err := tc.client.CreateTag(context.Background(), &ateapi.CreateTagRequest{ + Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "after-upgrade"}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + SourceActor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-b"}, }, }); err != nil { t.Fatalf("CreateTag under a free name failed: %v", err) @@ -164,23 +164,23 @@ func TestCreateTag_FromPausedActor(t *testing.T) { createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") ctx := context.Background() - ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-paused"} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + ref := &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-paused"} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor failed: %v", err) } - if _, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ + if _, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{ Actor: ref, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }); err != nil { t.Fatalf("pause failed: %v", err) } - paused, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: ref}) + paused, err := tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: ref}) if err != nil { t.Fatalf("GetActor failed: %v", err) } @@ -189,10 +189,10 @@ func TestCreateTag_FromPausedActor(t *testing.T) { t.Fatal("paused actor has no local snapshot") } - tag, err := tc.client.CreateTag(ctx, &ateapipb.CreateTagRequest{ - Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "from-paused"}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, + tag, err := tc.client.CreateTag(ctx, &ateapi.CreateTagRequest{ + Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "from-paused"}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, SourceActor: ref, }, }) @@ -206,7 +206,7 @@ func TestCreateTag_FromPausedActor(t *testing.T) { if len(snapshotObjectNames(t, tc, tagSnapshotURI(tag))) == 0 { t.Errorf("the tag's external snapshot %s is empty", tagSnapshotURI(tag)) } - stored, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: ref}) + stored, err := tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: ref}) if err != nil { t.Fatalf("GetActor failed: %v", err) } @@ -224,9 +224,9 @@ func TestCreateTag_FromPausedActor(t *testing.T) { func suspendActorForTest(t *testing.T, tc *testContext, workerName, name string) string { t.Helper() ctx := context.Background() - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor(%s) failed: %v", name, err) } @@ -234,14 +234,14 @@ func suspendActorForTest(t *testing.T, tc *testContext, workerName, name string) // cache: the preceding suspend released the worker in the store, but the // cache only learns of it on its next watch poll. waitForWorkerAvailable(t, tc, workerName) - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, }); err != nil { t.Fatalf("ResumeActor(%s) failed: %v", name, err) } - suspended, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + suspended, err := tc.client.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: name}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }) if err != nil { t.Fatalf("SuspendActor(%s) failed: %v", name, err) @@ -269,13 +269,13 @@ func TestUpdateTag_Preconditions(t *testing.T) { // observable write that bumps the version. // The tag under test is seeded from actor-2; source_actor is immutable, so // every update has to echo it back. - update := func(meta *ateapipb.ResourceMetadata, scope ateapipb.TagScope) (*ateapipb.Tag, error) { + update := func(meta *ateapi.ResourceMetadata, scope ateapi.TagScope) (*ateapi.Tag, error) { meta.Atespace, meta.Name = testAtespace, tagName - return tc.client.UpdateTag(context.Background(), &ateapipb.UpdateTagRequest{ - Tag: &ateapipb.Tag{ + return tc.client.UpdateTag(context.Background(), &ateapi.UpdateTagRequest{ + Tag: &ateapi.Tag{ Metadata: meta, Scope: scope, - SourceActor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-2"}, + SourceActor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-2"}, }, }) } @@ -283,8 +283,8 @@ func TestUpdateTag_Preconditions(t *testing.T) { // Delete and recreate the same atespace/name tag, so the first lifecycle's // uid becomes stale. staleUID := seedTag(t, tc, "actor-1", tagName).GetMetadata().GetUid() - if _, err := tc.client.DeleteTag(ctx, &ateapipb.DeleteTagRequest{ - Tag: &ateapipb.ObjectRef{Atespace: testAtespace, Name: tagName}, + if _, err := tc.client.DeleteTag(ctx, &ateapi.DeleteTagRequest{ + Tag: &ateapi.ObjectRef{Atespace: testAtespace, Name: tagName}, }); err != nil { t.Fatalf("DeleteTag failed: %v", err) } @@ -296,18 +296,18 @@ func TestUpdateTag_Preconditions(t *testing.T) { t.Fatalf("recreated tag reused uid %s, want a fresh one", uid) } // No preconditions - _, err := update(&ateapipb.ResourceMetadata{}, ateapipb.TagScope_TAG_SCOPE_PUBLISHED) + _, err := update(&ateapi.ResourceMetadata{}, ateapi.TagScope_TAG_SCOPE_PUBLISHED) assertGrpcError(t, err, codes.InvalidArgument, fmt.Sprintf("while updating tag %s/%s: persistence: precondition required: uid", testAtespace, tagName)) // The uid from the deleted lifecycle must be rejected, even though the // atespace/name it was observed under still resolves and the version it // guards on matches the recreated tag's. - _, err = update(&ateapipb.ResourceMetadata{Uid: staleUID, Version: staleVersion}, ateapipb.TagScope_TAG_SCOPE_PUBLISHED) + _, err = update(&ateapi.ResourceMetadata{Uid: staleUID, Version: staleVersion}, ateapi.TagScope_TAG_SCOPE_PUBLISHED) assertGrpcError(t, err, codes.Aborted, fmt.Sprintf("Tag %s/%s not found with uid %s", testAtespace, tagName, staleUID)) // Both guards matching the observed state: the update goes through, and // moves the tag past the version observed above. - first, err := update(&ateapipb.ResourceMetadata{Uid: uid, Version: staleVersion}, ateapipb.TagScope_TAG_SCOPE_PUBLISHED) + first, err := update(&ateapi.ResourceMetadata{Uid: uid, Version: staleVersion}, ateapi.TagScope_TAG_SCOPE_PUBLISHED) if err != nil { t.Fatalf("UpdateTag(matching guards) failed: %v", err) } @@ -315,21 +315,21 @@ func TestUpdateTag_Preconditions(t *testing.T) { if currentVersion <= staleVersion { t.Fatalf("version = %d, want greater than %d after an update", currentVersion, staleVersion) } - if got, want := first.GetScope(), ateapipb.TagScope_TAG_SCOPE_PUBLISHED; got != want { + if got, want := first.GetScope(), ateapi.TagScope_TAG_SCOPE_PUBLISHED; got != want { t.Errorf("scope = %v, want %v", got, want) } // The version observed before that write is now stale: rejected rather than // silently overwriting the concurrent change. - _, err = update(&ateapipb.ResourceMetadata{Uid: uid, Version: staleVersion}, ateapipb.TagScope_TAG_SCOPE_ATESPACE) + _, err = update(&ateapi.ResourceMetadata{Uid: uid, Version: staleVersion}, ateapi.TagScope_TAG_SCOPE_ATESPACE) assertGrpcError(t, err, codes.Aborted, "concurrent update conflict, please retry") // Guarding on the version the last write produced succeeds again. - updated, err := update(&ateapipb.ResourceMetadata{Uid: uid, Version: currentVersion}, ateapipb.TagScope_TAG_SCOPE_ATESPACE) + updated, err := update(&ateapi.ResourceMetadata{Uid: uid, Version: currentVersion}, ateapi.TagScope_TAG_SCOPE_ATESPACE) if err != nil { t.Fatalf("UpdateTag(matching guards) failed: %v", err) } - if got, want := updated.GetScope(), ateapipb.TagScope_TAG_SCOPE_ATESPACE; got != want { + if got, want := updated.GetScope(), ateapi.TagScope_TAG_SCOPE_ATESPACE; got != want { t.Errorf("scope = %v, want %v", got, want) } if updated.GetMetadata().GetVersion() <= currentVersion { @@ -337,7 +337,7 @@ func TestUpdateTag_Preconditions(t *testing.T) { } // The guard the client just satisfied is now stale in turn. - _, err = update(&ateapipb.ResourceMetadata{Uid: uid, Version: currentVersion}, ateapipb.TagScope_TAG_SCOPE_PUBLISHED) + _, err = update(&ateapi.ResourceMetadata{Uid: uid, Version: currentVersion}, ateapi.TagScope_TAG_SCOPE_PUBLISHED) assertGrpcError(t, err, codes.Aborted, "concurrent update conflict, please retry") } @@ -346,17 +346,17 @@ func TestUpdateTag_NotFound(t *testing.T) { tc := setupTest(t, ns) defer tc.cleanup() - _, err := tc.client.UpdateTag(context.Background(), &ateapipb.UpdateTagRequest{ - Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{ + _, err := tc.client.UpdateTag(context.Background(), &ateapi.UpdateTagRequest{ + Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{ Atespace: testAtespace, Name: "does-not-exist", // Well-formed guards to pass preconditions validation Uid: "9a2b1c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d", Version: 1, }, - Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED, - SourceActor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-1"}, + Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED, + SourceActor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-1"}, }, }) assertGrpcError(t, err, codes.NotFound, "Tag test-atespace/does-not-exist not found") @@ -377,7 +377,7 @@ func TestDeleteTag(t *testing.T) { } tc.objectStore.PutSnapshot(t, snapshotURI, "manifest.json") - deleted, err := tc.client.DeleteTag(ctx, &ateapipb.DeleteTagRequest{Tag: tagRef.ToObjectRef()}) + deleted, err := tc.client.DeleteTag(ctx, &ateapi.DeleteTagRequest{Tag: tagRef.ToObjectRef()}) if err != nil { t.Fatalf("DeleteTag failed: %v", err) } @@ -388,7 +388,7 @@ func TestDeleteTag(t *testing.T) { t.Errorf("the deleted tag carries no delete_time") } assertSnapshotCollected(t, tc, snapshotURI.String()) - _, err = tc.client.GetTag(ctx, &ateapipb.GetTagRequest{Tag: tagRef.ToObjectRef()}) + _, err = tc.client.GetTag(ctx, &ateapi.GetTagRequest{Tag: tagRef.ToObjectRef()}) assertGrpcError(t, err, codes.NotFound, "Tag "+tagRef.String()+" not found") } @@ -398,7 +398,7 @@ func TestDeleteTag_NotFound(t *testing.T) { defer tc.cleanup() tagRef := resources.TagRef{Atespace: testAtespace, Name: "missing"} - _, err := tc.client.DeleteTag(context.Background(), &ateapipb.DeleteTagRequest{Tag: tagRef.ToObjectRef()}) + _, err := tc.client.DeleteTag(context.Background(), &ateapi.DeleteTagRequest{Tag: tagRef.ToObjectRef()}) assertGrpcError(t, err, codes.NotFound, "Tag "+tagRef.String()+" not found") } @@ -410,33 +410,33 @@ func TestDeleteTag_Preconditions(t *testing.T) { createTemplate(t, tc, ns) tagRef := resources.TagRef{Atespace: testAtespace, Name: "v1"} ref := tagRef.ToObjectRef() - del := func(opts *ateapipb.DeleteOptions) error { - _, err := tc.client.DeleteTag(ctx, &ateapipb.DeleteTagRequest{Tag: ref, Options: opts}) + del := func(opts *ateapi.DeleteOptions) error { + _, err := tc.client.DeleteTag(ctx, &ateapi.DeleteTagRequest{Tag: ref, Options: opts}) return err } tag := seedTag(t, tc, "actor-1", tagRef.Name) uid, version := tag.GetMetadata().GetUid(), tag.GetMetadata().GetVersion() - assertGrpcError(t, del(&ateapipb.DeleteOptions{Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: uid, Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: foreignUID}), codes.Aborted, "Tag "+tagRef.String()+" does not have uid "+foreignUID) - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: foreignUID, Version: version}), codes.Aborted, "Tag "+tagRef.String()+" does not have uid "+foreignUID) - if _, err := tc.client.GetTag(ctx, &ateapipb.GetTagRequest{Tag: ref}); err != nil { + assertGrpcError(t, del(&ateapi.DeleteOptions{Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: uid, Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: foreignUID}), codes.Aborted, "Tag "+tagRef.String()+" does not have uid "+foreignUID) + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: foreignUID, Version: version}), codes.Aborted, "Tag "+tagRef.String()+" does not have uid "+foreignUID) + if _, err := tc.client.GetTag(ctx, &ateapi.GetTagRequest{Tag: ref}); err != nil { t.Fatalf("a refused delete removed the tag: %v", err) } - if err := del(&ateapipb.DeleteOptions{Version: version}); err != nil { + if err := del(&ateapi.DeleteOptions{Version: version}); err != nil { t.Fatalf("DeleteTag with the matching version: %v", err) } tag = seedTag(t, tc, "actor-2", tagRef.Name) - if err := del(&ateapipb.DeleteOptions{Uid: tag.GetMetadata().GetUid()}); err != nil { + if err := del(&ateapi.DeleteOptions{Uid: tag.GetMetadata().GetUid()}); err != nil { t.Fatalf("DeleteTag with the matching uid: %v", err) } tag = seedTag(t, tc, "actor-3", tagRef.Name) - if err := del(&ateapipb.DeleteOptions{Uid: tag.GetMetadata().GetUid(), Version: tag.GetMetadata().GetVersion()}); err != nil { + if err := del(&ateapi.DeleteOptions{Uid: tag.GetMetadata().GetUid(), Version: tag.GetMetadata().GetVersion()}); err != nil { t.Fatalf("DeleteTag with both guards: %v", err) } - _, err := tc.client.GetTag(ctx, &ateapipb.GetTagRequest{Tag: ref}) + _, err := tc.client.GetTag(ctx, &ateapi.GetTagRequest{Tag: ref}) assertGrpcError(t, err, codes.NotFound, "Tag "+tagRef.String()+" not found") } diff --git a/cmd/ateapi/internal/controlapi/functionaltest/worker_contention_test.go b/cmd/ateapi/internal/controlapi/functionaltest/worker_contention_test.go index e520268332..7c46150739 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/worker_contention_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/worker_contention_test.go @@ -23,9 +23,9 @@ import ( "k8s.io/apimachinery/pkg/util/wait" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/hardware" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" ) @@ -58,9 +58,9 @@ func TestResumeActor_ConcurrentOntoOneWorker(t *testing.T) { setWorkerActorCapacity(t, tc, "pool1", actors) for i := range actors { - if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: fmt.Sprintf("id%d", i)}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: fmt.Sprintf("id%d", i)}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor %d: %v", i, err) } @@ -76,8 +76,8 @@ func TestResumeActor_ConcurrentOntoOneWorker(t *testing.T) { for i := range actors { wg.Go(func() { start.Wait() - _, errs[i] = tc.client.ResumeActor(context.Background(), &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: fmt.Sprintf("id%d", i)}, + _, errs[i] = tc.client.ResumeActor(context.Background(), &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: fmt.Sprintf("id%d", i)}, }) }) } @@ -102,11 +102,11 @@ func TestResumeActor_ConcurrentOntoOneWorker(t *testing.T) { // reported as won would show up here rather than as an error above. Found by // pod rather than by taking the only worker in the list -- the list is // process-wide, so a -count>1 run sees the workers earlier iterations made. - listed, err := tc.client.ListWorkers(context.Background(), &ateapipb.ListWorkersRequest{}) + listed, err := tc.client.ListWorkers(context.Background(), &ateapi.ListWorkersRequest{}) if err != nil { t.Fatalf("ListWorkers: %v", err) } - var worker *ateapipb.Worker + var worker *ateapi.Worker for _, candidate := range listed.GetWorkers() { if candidate.GetWorkerNamespace() == ns && candidate.GetWorkerPod() == "worker-1" { worker = candidate @@ -160,15 +160,15 @@ const reportedEpoch = 1 // defaultWorkerRuntime returns the default ActorSandboxRuntime that // reportWorkerCapacity records on a test worker of the given sandbox class. -func defaultWorkerRuntime(class string) *ateapipb.ActorSandboxRuntime { +func defaultWorkerRuntime(class string) *ateapi.ActorSandboxRuntime { if class == "" { class = "gvisor" } - return &ateapipb.ActorSandboxRuntime{ + return &ateapi.ActorSandboxRuntime{ SandboxClass: class, - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: hardware.SchemaVersionV1, - Attributes: []*ateapipb.AttributeEntry{ + Attributes: []*ateapi.AttributeEntry{ {Key: hardware.AttrArchitecture, Value: "amd64"}, {Key: hardware.AttrSandboxBundleHash, Value: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}, }, @@ -181,12 +181,12 @@ func defaultWorkerRuntime(class string) *ateapipb.ActorSandboxRuntime { // The arguments are the ActorSandboxRuntimes a test also expects on snapshots and // assignments, so both sides of a match derive from one value; the compats // are copied so the stored row never aliases them. -func workerSandboxClasses(def *ateapipb.ActorSandboxRuntime, restorable ...*ateapipb.ActorSandboxRuntime) []*ateapipb.WorkerSandboxClass { - class := &ateapipb.WorkerSandboxClass{SandboxClass: def.GetSandboxClass(), DefaultRuntime: &ateapipb.WorkerSandboxRuntime{Version: proto.CloneOf(def.GetVersion())}} +func workerSandboxClasses(def *ateapi.ActorSandboxRuntime, restorable ...*ateapi.ActorSandboxRuntime) []*ateapi.WorkerSandboxClass { + class := &ateapi.WorkerSandboxClass{SandboxClass: def.GetSandboxClass(), DefaultRuntime: &ateapi.WorkerSandboxRuntime{Version: proto.CloneOf(def.GetVersion())}} for _, r := range restorable { - class.RestorableRuntimes = append(class.RestorableRuntimes, &ateapipb.WorkerSandboxRuntime{Version: proto.CloneOf(r.GetVersion())}) + class.RestorableRuntimes = append(class.RestorableRuntimes, &ateapi.WorkerSandboxRuntime{Version: proto.CloneOf(r.GetVersion())}) } - return []*ateapipb.WorkerSandboxClass{class} + return []*ateapi.WorkerSandboxClass{class} } // reportWorkerCapacity stands in for the worker process's registration and @@ -202,12 +202,12 @@ func reportWorkerCapacity(t *testing.T, tc *testContext, name string, actors int if err != nil { t.Fatalf("getting worker %s: %v", name, err) } - if _, err := tc.persistence.UpdateWorker(ctx, name, store.PreconditionFrom(worker), func(toUpdate *ateapipb.Worker) error { + if _, err := tc.persistence.UpdateWorker(ctx, name, store.PreconditionFrom(worker), func(toUpdate *ateapi.Worker) error { if toUpdate.Status.RegisteredEpoch == 0 { toUpdate.Status.RegisteredEpoch = reportedEpoch toUpdate.Status.Ips = []string{"127.0.0.1"} } - toUpdate.Status.Capacity = &ateapipb.WorkerResources{ + toUpdate.Status.Capacity = &ateapi.WorkerResources{ Actors: actors, CpuMillicores: int64(actors) * 1000, MemoryBytes: int64(actors) * 512 << 20, } diff --git a/cmd/ateapi/internal/controlapi/functionaltest/worker_restart_test.go b/cmd/ateapi/internal/controlapi/functionaltest/worker_restart_test.go index 60f5d0eb94..fcb74bcb21 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/worker_restart_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/worker_restart_test.go @@ -19,9 +19,9 @@ import ( "slices" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/controlapi" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -40,32 +40,32 @@ func TestResumeActor_RetriedAfterWorkerRestartDuringRestore(t *testing.T) { createTemplate(t, tc, ns) podUID := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") - ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"} - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + ref := &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } const newEpoch = reportedEpoch + 1 newIPs := []string{"127.0.0.2"} - updateWorker := func(mutate func(*ateapipb.WorkerStatus)) { + updateWorker := func(mutate func(*ateapi.WorkerStatus)) { t.Helper() worker, err := tc.persistence.GetWorker(ctx, podUID) if err != nil { t.Fatalf("GetWorker: %v", err) } - if _, err := tc.persistence.UpdateWorker(ctx, podUID, store.PreconditionFrom(worker), func(w *ateapipb.Worker) error { + if _, err := tc.persistence.UpdateWorker(ctx, podUID, store.PreconditionFrom(worker), func(w *ateapi.Worker) error { mutate(w.Status) return nil }); err != nil { t.Fatalf("UpdateWorker: %v", err) } } - getActor := func() *ateapipb.Actor { + getActor := func() *ateapi.Actor { t.Helper() - actor, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: ref}) + actor, err := tc.client.GetActor(ctx, &ateapi.GetActorRequest{Actor: ref}) if err != nil { t.Fatalf("GetActor failed: %v", err) } @@ -79,7 +79,7 @@ func TestResumeActor_RetriedAfterWorkerRestartDuringRestore(t *testing.T) { tc.fakeAtelet.RestoreWorkerEpoch = func() int64 { restores++ if restores == 1 { - updateWorker(func(s *ateapipb.WorkerStatus) { + updateWorker(func(s *ateapi.WorkerStatus) { s.RegisteredEpoch = newEpoch s.Ips = newIPs s.SandboxClasses = nil @@ -89,11 +89,11 @@ func TestResumeActor_RetriedAfterWorkerRestartDuringRestore(t *testing.T) { return newEpoch } - _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}) + _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}) if got := status.Code(err); got != codes.Unavailable { t.Fatalf("first ResumeActor = %v (err %v), want Unavailable", got, err) } - if got := getActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RESUMING { + if got := getActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RESUMING { t.Fatalf("actor state after the first resume = %v, want RESUMING", got) } @@ -102,13 +102,13 @@ func TestResumeActor_RetriedAfterWorkerRestartDuringRestore(t *testing.T) { if err := controlapi.NewWorkerWorkflow(tc.persistence, nil).ReconcileAssignments(ctx, podUID); err != nil { t.Fatalf("ReconcileAssignments: %v", err) } - if got := getActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RESUMING { + if got := getActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RESUMING { t.Fatalf("actor state after reconcile = %v, want RESUMING", got) } // Until the new process reports its runtimes the retry waits, without // restoring or crashing anything. - _, err = tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}) + _, err = tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}) if got := status.Code(err); got != codes.Unavailable { t.Fatalf("ResumeActor before runtimes are reported = %v (err %v), want Unavailable", got, err) } @@ -116,10 +116,10 @@ func TestResumeActor_RetriedAfterWorkerRestartDuringRestore(t *testing.T) { t.Fatalf("restores = %d before runtimes are reported, want 1", restores) } - updateWorker(func(s *ateapipb.WorkerStatus) { + updateWorker(func(s *ateapi.WorkerStatus) { s.SandboxClasses = workerSandboxClasses(defaultWorkerRuntime("gvisor")) }) - resp, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}) + resp, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}) if err != nil { t.Fatalf("ResumeActor after the restart: %v", err) } @@ -127,7 +127,7 @@ func TestResumeActor_RetriedAfterWorkerRestartDuringRestore(t *testing.T) { t.Errorf("restores = %d, want the retry to restore again", restores) } actor := resp.GetActor() - if got := actor.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := actor.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Fatalf("actor state = %v, want RUNNING", got) } assignment := actor.GetStatus().GetWorkerAssignment() @@ -143,7 +143,7 @@ func TestResumeActor_RetriedAfterWorkerRestartDuringRestore(t *testing.T) { if err := controlapi.NewWorkerWorkflow(tc.persistence, nil).ReconcileAssignments(ctx, podUID); err != nil { t.Fatalf("ReconcileAssignments: %v", err) } - if got := getActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := getActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("actor state after a later reconcile = %v, want RUNNING", got) } worker, err := tc.persistence.GetWorker(ctx, podUID) diff --git a/cmd/ateapi/internal/controlapi/functionaltest/worker_test.go b/cmd/ateapi/internal/controlapi/functionaltest/worker_test.go index 09164728c3..fbfad415fd 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/worker_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/worker_test.go @@ -21,7 +21,7 @@ import ( "time" "github.com/google/go-cmp/cmp" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/grpc/codes" "google.golang.org/protobuf/testing/protocmp" "k8s.io/apimachinery/pkg/util/wait" @@ -40,9 +40,9 @@ const testWorkerName = "5f2c1a90-7b34-4e6d-8a11-0c3e9d5b7f42" // CRUD API — only the atelet dialer resolves a Worker to a pod, and nothing in // ate-api reconciles the two now that the syncer runs in ate-controller. Tests // that need both use createWorkerPod. -func newTestWorker(ns string) *ateapipb.Worker { - return &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerName}, +func newTestWorker(ns string) *ateapi.Worker { + return &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerName}, WorkerNamespace: ns, WorkerPool: "pool1", WorkerPod: "worker-api-1", @@ -52,23 +52,23 @@ func newTestWorker(ns string) *ateapipb.Worker { } // registerWorker registers newTestWorker over the API and returns it as stored. -func registerWorker(t *testing.T, tc *testContext, ns string) *ateapipb.Worker { +func registerWorker(t *testing.T, tc *testContext, ns string) *ateapi.Worker { t.Helper() - created, err := tc.client.CreateWorker(context.Background(), &ateapipb.CreateWorkerRequest{Worker: newTestWorker(ns)}) + created, err := tc.client.CreateWorker(context.Background(), &ateapi.CreateWorkerRequest{Worker: newTestWorker(ns)}) if err != nil { t.Fatalf("CreateWorker failed: %v", err) } return created } -func workerRef(name string) *ateapipb.ObjectRef { - return &ateapipb.ObjectRef{Name: name} +func workerRef(name string) *ateapi.ObjectRef { + return &ateapi.ObjectRef{Name: name} } // waitForWorkerState waits for a state committed by an RPC to reach the worker // cache, which follows the store through a PostgreSQL watch and so lands // shortly after the call returns rather than with it. -func waitForWorkerState(t *testing.T, tc *testContext, name string, want ateapipb.WorkerState) { +func waitForWorkerState(t *testing.T, tc *testContext, name string, want ateapi.WorkerState) { t.Helper() err := wait.PollUntilContextTimeout(context.Background(), 10*time.Millisecond, 5*time.Second, true, func(context.Context) (bool, error) { worker, err := tc.workerCache.Worker(name) @@ -82,7 +82,7 @@ func waitForWorkerState(t *testing.T, tc *testContext, name string, want ateapip } } -func containsWorker(workers []*ateapipb.Worker, name string) bool { +func containsWorker(workers []*ateapi.Worker, name string) bool { for _, w := range workers { if w.GetMetadata().GetName() == name { return true @@ -103,7 +103,7 @@ func TestCreateAndGetWorker(t *testing.T) { want := newTestWorker(ns) want.Metadata.Version = 1 - want.Status = &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE} + want.Status = &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_UNAVAILABLE} if diff := cmp.Diff(want, created, protocmp.Transform(), ignoreServerMetadata); diff != "" { t.Errorf("CreateWorker response mismatch (-want +got):\n%s", diff) } @@ -111,7 +111,7 @@ func TestCreateAndGetWorker(t *testing.T) { t.Errorf("CreateWorker returned no uid, which every later guard needs") } - got, err := tc.client.GetWorker(context.Background(), &ateapipb.GetWorkerRequest{Worker: workerRef(testWorkerName)}) + got, err := tc.client.GetWorker(context.Background(), &ateapi.GetWorkerRequest{Worker: workerRef(testWorkerName)}) if err != nil { t.Fatalf("GetWorker failed: %v", err) } @@ -136,21 +136,21 @@ func TestListWorkers(t *testing.T) { createWorkerPool(t, tc, ns, "pool1", map[string]string{"foo": "bar"}) podUID := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") - listResp, err := tc.client.ListWorkers(context.Background(), &ateapipb.ListWorkersRequest{}) + listResp, err := tc.client.ListWorkers(context.Background(), &ateapi.ListWorkersRequest{}) if err != nil { t.Fatalf("ListWorkers failed: %v", err) } - var filteredWorkers []*ateapipb.Worker + var filteredWorkers []*ateapi.Worker for _, w := range listResp.GetWorkers() { if w.GetWorkerNamespace() == ns { filteredWorkers = append(filteredWorkers, w) } } - want := []*ateapipb.Worker{ + want := []*ateapi.Worker{ { - Metadata: &ateapipb.ResourceMetadata{ + Metadata: &ateapi.ResourceMetadata{ Name: podUID, // Three writes: the registration, marking it available, then // the capacity report. @@ -162,11 +162,11 @@ func TestListWorkers(t *testing.T) { WorkerPodUid: podUID, NodeName: "node1", Labels: map[string]string{"foo": "bar"}, - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, RegisteredEpoch: reportedEpoch, Ips: []string{"127.0.0.1"}, - Capacity: &ateapipb.WorkerResources{Actors: 1, CpuMillicores: 1000, MemoryBytes: 512 << 20}, + Capacity: &ateapi.WorkerResources{Actors: 1, CpuMillicores: 1000, MemoryBytes: 512 << 20}, SandboxClasses: workerSandboxClasses(defaultWorkerRuntime("gvisor")), }, }, @@ -192,7 +192,7 @@ func TestListWorkerActorAssignments(t *testing.T) { createTemplate(t, tc, ns) podUID := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") - empty, err := tc.client.ListWorkerActorAssignments(ctx, &ateapipb.ListWorkerActorAssignmentsRequest{Worker: workerRef(podUID)}) + empty, err := tc.client.ListWorkerActorAssignments(ctx, &ateapi.ListWorkerActorAssignmentsRequest{Worker: workerRef(podUID)}) if err != nil { t.Fatalf("ListWorkerActorAssignments on an empty worker failed: %v", err) } @@ -200,26 +200,26 @@ func TestListWorkerActorAssignments(t *testing.T) { t.Errorf("worker hosting nothing lists %d assignments, want 0", got) } - if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, }}); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"}, + if _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"}, }); err != nil { t.Fatalf("ResumeActor failed: %v", err) } - listed, err := tc.client.ListWorkerActorAssignments(ctx, &ateapipb.ListWorkerActorAssignmentsRequest{Worker: workerRef(podUID)}) + listed, err := tc.client.ListWorkerActorAssignments(ctx, &ateapi.ListWorkerActorAssignmentsRequest{Worker: workerRef(podUID)}) if err != nil { t.Fatalf("ListWorkerActorAssignments failed: %v", err) } if len(listed.GetActorAssignments()) != 1 { t.Fatalf("worker hosting one actor lists %d assignments, want 1", len(listed.GetActorAssignments())) } - want := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "id1"} + want := &ateapi.ObjectRef{Atespace: testAtespace, Name: "id1"} if diff := cmp.Diff(want, listed.GetActorAssignments()[0].GetActor(), protocmp.Transform()); diff != "" { t.Errorf("assignment names the wrong actor (-want +got):\n%s", diff) } @@ -237,7 +237,7 @@ func TestUpdateWorker(t *testing.T) { worker := registerWorker(t, tc, ns) worker.Labels = map[string]string{"tier": "batch"} - updated, err := tc.client.UpdateWorker(context.Background(), &ateapipb.UpdateWorkerRequest{Worker: worker}) + updated, err := tc.client.UpdateWorker(context.Background(), &ateapi.UpdateWorkerRequest{Worker: worker}) if err != nil { t.Fatalf("UpdateWorker failed: %v", err) } @@ -245,7 +245,7 @@ func TestUpdateWorker(t *testing.T) { want := newTestWorker(ns) want.Metadata.Version = 2 want.Labels = map[string]string{"tier": "batch"} - want.Status = &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE} + want.Status = &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_UNAVAILABLE} if diff := cmp.Diff(want, updated, protocmp.Transform(), ignoreServerMetadata); diff != "" { t.Errorf("UpdateWorker response mismatch (-want +got):\n%s", diff) } @@ -260,22 +260,22 @@ func TestDrainWorker(t *testing.T) { defer tc.cleanup() registerWorker(t, tc, ns) - waitForWorkerState(t, tc, testWorkerName, ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE) + waitForWorkerState(t, tc, testWorkerName, ateapi.WorkerState_WORKER_STATE_UNAVAILABLE) - drained, err := tc.client.DrainWorker(context.Background(), &ateapipb.DrainWorkerRequest{Worker: workerRef(testWorkerName)}) + drained, err := tc.client.DrainWorker(context.Background(), &ateapi.DrainWorkerRequest{Worker: workerRef(testWorkerName)}) if err != nil { t.Fatalf("DrainWorker failed: %v", err) } wantWorker := newTestWorker(ns) wantWorker.Metadata.Version = 2 - wantWorker.Status = &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_DRAINING} - want := &ateapipb.DrainWorkerResponse{Worker: wantWorker} + wantWorker.Status = &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_DRAINING} + want := &ateapi.DrainWorkerResponse{Worker: wantWorker} if diff := cmp.Diff(want, drained, protocmp.Transform(), ignoreServerMetadata); diff != "" { t.Errorf("DrainWorker response mismatch (-want +got):\n%s", diff) } - waitForWorkerState(t, tc, testWorkerName, ateapipb.WorkerState_WORKER_STATE_DRAINING) + waitForWorkerState(t, tc, testWorkerName, ateapi.WorkerState_WORKER_STATE_DRAINING) } // TestMarkWorkerAvailability moves a Worker between ACTIVE and UNAVAILABLE, and @@ -287,30 +287,30 @@ func TestMarkWorkerAvailability(t *testing.T) { ctx := context.Background() registerWorker(t, tc, ns) - waitForWorkerState(t, tc, testWorkerName, ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE) + waitForWorkerState(t, tc, testWorkerName, ateapi.WorkerState_WORKER_STATE_UNAVAILABLE) - available, err := tc.client.MarkWorkerAvailable(ctx, &ateapipb.MarkWorkerAvailableRequest{Worker: workerRef(testWorkerName)}) + available, err := tc.client.MarkWorkerAvailable(ctx, &ateapi.MarkWorkerAvailableRequest{Worker: workerRef(testWorkerName)}) if err != nil { t.Fatalf("MarkWorkerAvailable failed: %v", err) } want := newTestWorker(ns) want.Metadata.Version = 2 - want.Status = &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_ACTIVE} + want.Status = &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_ACTIVE} if diff := cmp.Diff(want, available.GetWorker(), protocmp.Transform(), ignoreServerMetadata); diff != "" { t.Errorf("MarkWorkerAvailable response mismatch (-want +got):\n%s", diff) } - waitForWorkerState(t, tc, testWorkerName, ateapipb.WorkerState_WORKER_STATE_ACTIVE) + waitForWorkerState(t, tc, testWorkerName, ateapi.WorkerState_WORKER_STATE_ACTIVE) - unavailable, err := tc.client.MarkWorkerUnavailable(ctx, &ateapipb.MarkWorkerUnavailableRequest{Worker: workerRef(testWorkerName)}) + unavailable, err := tc.client.MarkWorkerUnavailable(ctx, &ateapi.MarkWorkerUnavailableRequest{Worker: workerRef(testWorkerName)}) if err != nil { t.Fatalf("MarkWorkerUnavailable failed: %v", err) } want.Metadata.Version = 3 - want.Status = &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE} + want.Status = &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_UNAVAILABLE} if diff := cmp.Diff(want, unavailable.GetWorker(), protocmp.Transform(), ignoreServerMetadata); diff != "" { t.Errorf("MarkWorkerUnavailable response mismatch (-want +got):\n%s", diff) } - waitForWorkerState(t, tc, testWorkerName, ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE) + waitForWorkerState(t, tc, testWorkerName, ateapi.WorkerState_WORKER_STATE_UNAVAILABLE) } // TestDeleteWorker deregisters a Worker and checks it is gone. The delete @@ -325,13 +325,13 @@ func TestDeleteWorker(t *testing.T) { registerWorker(t, tc, ns) - deleted, err := tc.client.DeleteWorker(ctx, &ateapipb.DeleteWorkerRequest{Worker: workerRef(testWorkerName)}) + deleted, err := tc.client.DeleteWorker(ctx, &ateapi.DeleteWorkerRequest{Worker: workerRef(testWorkerName)}) if err != nil { t.Fatalf("DeleteWorker failed: %v", err) } want := newTestWorker(ns) want.Metadata.Version = 2 - want.Status = &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_DRAINING} + want.Status = &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_DRAINING} if diff := cmp.Diff(want, deleted, protocmp.Transform(), ignoreServerMetadata); diff != "" { t.Errorf("DeleteWorker response mismatch (-want +got):\n%s", diff) } @@ -339,7 +339,7 @@ func TestDeleteWorker(t *testing.T) { t.Error("DeleteWorker returned a worker without delete_time") } - listed, err := tc.client.ListWorkers(ctx, &ateapipb.ListWorkersRequest{}) + listed, err := tc.client.ListWorkers(ctx, &ateapi.ListWorkersRequest{}) if err != nil { t.Fatalf("ListWorkers failed: %v", err) } @@ -347,7 +347,7 @@ func TestDeleteWorker(t *testing.T) { t.Errorf("ListWorkers still returns worker %s after DeleteWorker", testWorkerName) } - _, err = tc.client.DeleteWorker(ctx, &ateapipb.DeleteWorkerRequest{Worker: workerRef(testWorkerName)}) + _, err = tc.client.DeleteWorker(ctx, &ateapi.DeleteWorkerRequest{Worker: workerRef(testWorkerName)}) assertGrpcError(t, err, codes.NotFound, fmt.Sprintf("Worker %s not found", testWorkerName)) } @@ -357,12 +357,12 @@ func TestValidation_Worker(t *testing.T) { defer tc.cleanup() t.Run("ListWorkers", func(t *testing.T) { - _, err := tc.client.ListWorkers(context.Background(), &ateapipb.ListWorkersRequest{Options: &ateapipb.ListOptions{PageSize: -1}}) + _, err := tc.client.ListWorkers(context.Background(), &ateapi.ListWorkersRequest{Options: &ateapi.ListOptions{PageSize: -1}}) assertGrpcErrorRegex(t, err, codes.InvalidArgument, "page_size: Invalid value") }) t.Run("ListWorkers invalid token", func(t *testing.T) { - _, err := tc.client.ListWorkers(context.Background(), &ateapipb.ListWorkersRequest{Options: &ateapipb.ListOptions{PageToken: "%%%"}}) + _, err := tc.client.ListWorkers(context.Background(), &ateapi.ListWorkersRequest{Options: &ateapi.ListOptions{PageToken: "%%%"}}) assertGrpcError(t, err, codes.InvalidArgument, "invalid page_token") }) } @@ -373,35 +373,35 @@ func TestDeleteWorker_Preconditions(t *testing.T) { defer tc.cleanup() ctx := context.Background() ref := workerRef(testWorkerName) - del := func(opts *ateapipb.DeleteOptions) error { - _, err := tc.client.DeleteWorker(ctx, &ateapipb.DeleteWorkerRequest{Worker: ref, Options: opts}) + del := func(opts *ateapi.DeleteOptions) error { + _, err := tc.client.DeleteWorker(ctx, &ateapi.DeleteWorkerRequest{Worker: ref, Options: opts}) return err } worker := registerWorker(t, tc, ns) uid, version := worker.GetMetadata().GetUid(), worker.GetMetadata().GetVersion() - assertGrpcError(t, del(&ateapipb.DeleteOptions{Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: uid, Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: foreignUID}), codes.Aborted, "Worker "+testWorkerName+" does not have uid "+foreignUID) - assertGrpcError(t, del(&ateapipb.DeleteOptions{Uid: foreignUID, Version: version}), codes.Aborted, "Worker "+testWorkerName+" does not have uid "+foreignUID) - if _, err := tc.client.GetWorker(ctx, &ateapipb.GetWorkerRequest{Worker: ref}); err != nil { + assertGrpcError(t, del(&ateapi.DeleteOptions{Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: uid, Version: version + 1}), codes.Aborted, "concurrent update conflict, please retry") + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: foreignUID}), codes.Aborted, "Worker "+testWorkerName+" does not have uid "+foreignUID) + assertGrpcError(t, del(&ateapi.DeleteOptions{Uid: foreignUID, Version: version}), codes.Aborted, "Worker "+testWorkerName+" does not have uid "+foreignUID) + if _, err := tc.client.GetWorker(ctx, &ateapi.GetWorkerRequest{Worker: ref}); err != nil { t.Fatalf("a refused delete removed the worker: %v", err) } // The delete drains the worker first, which moves the version; the guard // is checked against the record the caller read. - if err := del(&ateapipb.DeleteOptions{Version: version}); err != nil { + if err := del(&ateapi.DeleteOptions{Version: version}); err != nil { t.Fatalf("DeleteWorker with the matching version: %v", err) } worker = registerWorker(t, tc, ns) - if err := del(&ateapipb.DeleteOptions{Uid: worker.GetMetadata().GetUid()}); err != nil { + if err := del(&ateapi.DeleteOptions{Uid: worker.GetMetadata().GetUid()}); err != nil { t.Fatalf("DeleteWorker with the matching uid: %v", err) } worker = registerWorker(t, tc, ns) - if err := del(&ateapipb.DeleteOptions{Uid: worker.GetMetadata().GetUid(), Version: worker.GetMetadata().GetVersion()}); err != nil { + if err := del(&ateapi.DeleteOptions{Uid: worker.GetMetadata().GetUid(), Version: worker.GetMetadata().GetVersion()}); err != nil { t.Fatalf("DeleteWorker with both guards: %v", err) } - _, err := tc.client.GetWorker(ctx, &ateapipb.GetWorkerRequest{Worker: ref}) + _, err := tc.client.GetWorker(ctx, &ateapi.GetWorkerRequest{Worker: ref}) assertGrpcError(t, err, codes.NotFound, "Worker "+testWorkerName+" not found") } diff --git a/cmd/ateapi/internal/controlapi/hosting.go b/cmd/ateapi/internal/controlapi/hosting.go index d93afee96f..705ca7519d 100644 --- a/cmd/ateapi/internal/controlapi/hosting.go +++ b/cmd/ateapi/internal/controlapi/hosting.go @@ -20,9 +20,9 @@ import ( "fmt" "slices" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // HostingNode is the node that holds the actor, and "" when no node does. The @@ -42,7 +42,7 @@ import ( // // WorkerService uses it to refuse a node that asks for credentials for an // actor it does not hold. -func HostingNode(ctx context.Context, st store.Interface, actor *ateapipb.Actor) (string, error) { +func HostingNode(ctx context.Context, st store.Interface, actor *ateapi.Actor) (string, error) { status := actor.GetStatus() // The branches below pick the field to trust within the states a node // transfers in. @@ -51,14 +51,14 @@ func HostingNode(ctx context.Context, st store.Interface, actor *ateapipb.Actor) } assignment := status.GetWorkerAssignment() if assignment == nil { - if status.GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if status.GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { return "", nil } return status.GetAssignedNode(), nil } switch status.GetState() { - case ateapipb.ActorState_ACTOR_STATE_RESUMING, ateapipb.ActorState_ACTOR_STATE_RUNNING, - ateapipb.ActorState_ACTOR_STATE_SUSPENDING: + case ateapi.ActorState_ACTOR_STATE_RESUMING, ateapi.ActorState_ACTOR_STATE_RUNNING, + ateapi.ActorState_ACTOR_STATE_SUSPENDING: default: return "", nil } diff --git a/cmd/ateapi/internal/controlapi/hosting_test.go b/cmd/ateapi/internal/controlapi/hosting_test.go index e6f8c3f164..e32474d057 100644 --- a/cmd/ateapi/internal/controlapi/hosting_test.go +++ b/cmd/ateapi/internal/controlapi/hosting_test.go @@ -20,13 +20,13 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/scheduling" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/cmd/ateapi/internal/workercache" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" ) @@ -49,45 +49,45 @@ func TestHostingNodeAfterWorkerRelease(t *testing.T) { t.Run(tc.Name, func(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation}) + seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} workerName := wa.GetWorker().GetName() - if _, err := persistence.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: workerName}, + if _, err := persistence.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: workerName}, WorkerNamespace: wa.GetWorkerNamespace(), WorkerPool: wa.GetWorkerPool(), WorkerPod: wa.GetWorkerPod(), WorkerPodUid: wa.GetWorkerPodUid(), NodeName: node, - Status: registered(&ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, - SandboxClasses: []*ateapipb.WorkerSandboxClass{{SandboxClass: "gvisor"}}, + Status: registered(&ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, + SandboxClasses: []*ateapi.WorkerSandboxClass{{SandboxClass: "gvisor"}}, }), }); err != nil { t.Fatalf("CreateWorker: %v", err) } - status := &ateapipb.ActorStatus{ + status := &ateapi.ActorStatus{ State: tc.State, AssignedNode: node, WorkerAssignment: wireTestAssignment(), LastAssignedGeneration: 1, } if tc.Snapshot != nil { - status.Snapshots = []*ateapipb.Snapshot{tc.Snapshot(t)} + status.Snapshots = []*ateapi.Snapshot{tc.Snapshot(t)} } - created := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + created := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), Status: status, }) uid := created.GetMetadata().GetUid() - seedAssignment(t, persistence, workerName, &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: actorRef.Atespace, Name: actorRef.Name}, + seedAssignment(t, persistence, workerName, &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorUid: uid, }) - hostingNode := func(stage string) (string, *ateapipb.Actor) { + hostingNode := func(stage string) (string, *ateapi.Actor) { t.Helper() actor, err := persistence.GetActor(ctx, actorRef) if err != nil { @@ -123,8 +123,8 @@ func TestHostingNodeAfterWorkerRelease(t *testing.T) { } // The worker takes another actor. - seedAssignment(t, persistence, workerName, &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: actorRef.Atespace, Name: "actor-2"}, + seedAssignment(t, persistence, workerName, &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: actorRef.Atespace, Name: "actor-2"}, ActorUid: "5c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f", }) if got, _ := hostingNode("worker rebooked for another actor"); got != "" { @@ -155,46 +155,46 @@ func TestHostingNodeAfterResumeOntoNewWorker(t *testing.T) { persistence := newTestPersistence(t) actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) // stale-pod on node1 holds a claim from a failed attempt but is no longer // eligible; free-pod on node2 is eligible and free. - stale := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerUID("stale-pod")}, + stale := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerUID("stale-pod")}, WorkerNamespace: "worker-ns", WorkerPool: "pool-a", WorkerPod: "stale-pod", WorkerPodUid: testWorkerUID("stale-pod"), NodeName: "node1", - Status: registered(&ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, - SandboxClasses: []*ateapipb.WorkerSandboxClass{{SandboxClass: "microvm", DefaultRuntime: &ateapipb.WorkerSandboxRuntime{Version: testSandboxRuntime().GetVersion()}}}, + Status: registered(&ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, + SandboxClasses: []*ateapi.WorkerSandboxClass{{SandboxClass: "microvm", DefaultRuntime: &ateapi.WorkerSandboxRuntime{Version: testSandboxRuntime().GetVersion()}}}, }), } - free := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerUID("free-pod")}, + free := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerUID("free-pod")}, WorkerNamespace: "worker-ns", WorkerPool: "pool-b", WorkerPod: "free-pod", WorkerPodUid: testWorkerUID("free-pod"), NodeName: "node2", Labels: map[string]string{"pool": "b"}, - Status: registered(&ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Status: registered(&ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(testSandboxRuntime()), }), } - for _, w := range []*ateapipb.Worker{stale, free} { + for _, w := range []*ateapi.Worker{stale, free} { if _, err := persistence.CreateWorker(ctx, w); err != nil { t.Fatalf("CreateWorker(%s): %v", w.GetWorkerPod(), err) } } - seedAssignment(t, persistence, testWorkerUID("stale-pod"), &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: actorRef.Atespace, Name: actorRef.Name}, + seedAssignment(t, persistence, testWorkerUID("stale-pod"), &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorUid: actor.GetMetadata().GetUid(), }) @@ -205,14 +205,14 @@ func TestHostingNodeAfterResumeOntoNewWorker(t *testing.T) { t.Fatalf("workercache.Start: %v", err) } w := &ActorWorkflow{store: persistence, workerCache: wc, scheduler: scheduling.New(wc)} - tmpl := &ateapipb.ActorTemplate{ - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"pool": "b"}}, + tmpl := &ateapi.ActorTemplate{ + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"pool": "b"}}, } resuming, _, err := w.assignWorkerAttempt(ctx, actorRef, actor, tmpl) if err != nil { t.Fatalf("assignWorkerAttempt: %v", err) } - if got := resuming.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RESUMING { + if got := resuming.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RESUMING { t.Fatalf("actor state after assignment = %v, want RESUMING", got) } @@ -226,7 +226,7 @@ func TestHostingNodeAfterResumeOntoNewWorker(t *testing.T) { // A status naming the released stale worker is refused. onStale := proto.CloneOf(resuming) - onStale.Status.WorkerAssignment = &ateapipb.WorkerAssignment{Worker: &ateapipb.ObjectRef{Name: testWorkerUID("stale-pod")}} + onStale.Status.WorkerAssignment = &ateapi.WorkerAssignment{Worker: &ateapi.ObjectRef{Name: testWorkerUID("stale-pod")}} if got, err := HostingNode(ctx, persistence, onStale); err != nil || got != "" { t.Errorf("HostingNode naming the released stale worker = %q, %v; want \"\", nil", got, err) } @@ -235,37 +235,37 @@ func TestHostingNodeAfterResumeOntoNewWorker(t *testing.T) { // TestHostingNodeWithoutWorker pins which no-worker shapes count assigned_node // as hosting the actor. None of them reads the store. func TestHostingNodeWithoutWorker(t *testing.T) { - durable := func(st ateapipb.SnapshotStorageStatus) *ateapipb.SnapshotStorage { - return &ateapipb.SnapshotStorage{Status: st, Object: &ateapipb.ObjectSnapshot{SnapshotUri: "gs://snaps/root/atespaces/a/actors/uid/snap-1"}} + durable := func(st ateapi.SnapshotStorageStatus) *ateapi.SnapshotStorage { + return &ateapi.SnapshotStorage{Status: st, Object: &ateapi.ObjectSnapshot{SnapshotUri: "gs://snaps/root/atespaces/a/actors/uid/snap-1"}} } - status := func(state ateapipb.ActorState, locality string, d *ateapipb.SnapshotStorage) *ateapipb.ActorStatus { - return &ateapipb.ActorStatus{ + status := func(state ateapi.ActorState, locality string, d *ateapi.SnapshotStorage) *ateapi.ActorStatus { + return &ateapi.ActorStatus{ State: state, AssignedNode: "node-1", LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{{Uuid: "snap-1", Generation: 1, Owner: ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, Locality: locality, DurableSnapshot: d}}, + Snapshots: []*ateapi.Snapshot{{Uuid: "snap-1", Generation: 1, Owner: ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, Locality: locality, DurableSnapshot: d}}, } } - olderOnNode := status(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1", durable(ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)) + olderOnNode := status(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1", durable(ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)) olderOnNode.LastAssignedGeneration = 2 - olderOnNode.Snapshots = append(olderOnNode.Snapshots, &ateapipb.Snapshot{Uuid: "snap-2", Generation: 2, Owner: ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, DurableSnapshot: durable(ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)}) - noAssignedNode := status(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1", nil) + olderOnNode.Snapshots = append(olderOnNode.Snapshots, &ateapi.Snapshot{Uuid: "snap-2", Generation: 2, Owner: ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, DurableSnapshot: durable(ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)}) + noAssignedNode := status(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1", nil) noAssignedNode.AssignedNode = "" for _, tc := range []struct { name string - status *ateapipb.ActorStatus + status *ateapi.ActorStatus want string }{ - {"paused", status(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1", nil), "node-1"}, - {"paused, upload pending", status(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1", durable(ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING)), "node-1"}, - {"paused, uploaded, local copy kept", status(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1", durable(ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)), "node-1"}, + {"paused", status(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1", nil), "node-1"}, + {"paused, upload pending", status(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1", durable(ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING)), "node-1"}, + {"paused, uploaded, local copy kept", status(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1", durable(ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)), "node-1"}, {"older snapshot on the node, latest not", olderOnNode, "node-1"}, {"local copy but no assigned node", noAssignedNode, ""}, - {"suspending without a worker", status(ateapipb.ActorState_ACTOR_STATE_SUSPENDING, "node-1", durable(ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING)), ""}, - {"crashed with a local copy", status(ateapipb.ActorState_ACTOR_STATE_CRASHED, "node-1", nil), ""}, + {"suspending without a worker", status(ateapi.ActorState_ACTOR_STATE_SUSPENDING, "node-1", durable(ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING)), ""}, + {"crashed with a local copy", status(ateapi.ActorState_ACTOR_STATE_CRASHED, "node-1", nil), ""}, } { t.Run(tc.name, func(t *testing.T) { - actor := &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Atespace: "a", Name: "n", Uid: "uid"}, Status: tc.status} + actor := &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Atespace: "a", Name: "n", Uid: "uid"}, Status: tc.status} got, err := HostingNode(context.Background(), nil, actor) if err != nil || got != tc.want { t.Fatalf("HostingNode = %q, %v, want %q", got, err, tc.want) diff --git a/cmd/ateapi/internal/controlapi/metrics.go b/cmd/ateapi/internal/controlapi/metrics.go index 647045720d..f8d47c2869 100644 --- a/cmd/ateapi/internal/controlapi/metrics.go +++ b/cmd/ateapi/internal/controlapi/metrics.go @@ -19,11 +19,11 @@ import ( "fmt" "time" + "go.ate.dev/substrate/api/ateapi/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/hardware" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" "k8s.io/apimachinery/pkg/labels" @@ -65,7 +65,7 @@ func recordActorCrash(ctx context.Context, attrs []attribute.KeyValue) { // used to seed zero-valued series). Worker counts are spatially summable (over // states = pool size, over pools = fleet), which is the UpDownCounter contract; a // gauge would be wrong for a value meant to be summed. -func RegisterWorkerCount(meter metric.Meter, workers func() ([]*ateapipb.Worker, error), listPools func(labels.Selector) ([]*atev1alpha1.WorkerPool, error)) error { +func RegisterWorkerCount(meter metric.Meter, workers func() ([]*ateapi.Worker, error), listPools func(labels.Selector) ([]*atev1.WorkerPool, error)) error { counter, err := meter.Int64ObservableUpDownCounter( workerpoolWorkersMetric, metric.WithUnit("{worker}"), @@ -90,7 +90,7 @@ func RegisterWorkerCount(meter metric.Meter, workers func() ([]*ateapipb.Worker, for _, p := range pools { class := string(p.Spec.DefaultSandboxClass()) if class == "" { - class = string(atev1alpha1.SandboxClassGvisor) + class = string(atev1.SandboxClassGvisor) } for _, state := range workerStates { tally[key{p.Namespace, p.Name, state, class}] = 0 @@ -131,9 +131,9 @@ var workerStates = []string{ // workerState counts actor slots only. A capacity not yet reported is // unschedulable, not full. -func workerState(w *ateapipb.Worker) string { +func workerState(w *ateapi.Worker) string { capacity := w.GetStatus().GetCapacity().GetActors() - if w.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_ACTIVE || capacity <= 0 { + if w.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_ACTIVE || capacity <= 0 { return ateattr.WorkerStateUnschedulable } switch allocated := w.GetStatus().GetAllocated().GetActors(); { @@ -210,7 +210,7 @@ func (i *Instruments) recordLifecycleOp(ctx context.Context, op string, start ti // applies to resume and suspend and separates a full restore from a data-only // one of the same kind. // The pool keys are set together or not at all; see ateattr.WorkerPoolAttributes. -func lifecycleOpAttrs(actor *ateapipb.Actor, snapshotKind, snapshotScope string) []attribute.KeyValue { +func lifecycleOpAttrs(actor *ateapi.Actor, snapshotKind, snapshotScope string) []attribute.KeyValue { var attrs []attribute.KeyValue if actor != nil { attrs = append(attrs, diff --git a/cmd/ateapi/internal/controlapi/metrics_test.go b/cmd/ateapi/internal/controlapi/metrics_test.go index 3a68f8668e..eab5b8c7c1 100644 --- a/cmd/ateapi/internal/controlapi/metrics_test.go +++ b/cmd/ateapi/internal/controlapi/metrics_test.go @@ -21,10 +21,10 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel/attribute" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/metricdata" @@ -37,7 +37,7 @@ import ( // newWorkerCountReader registers ate.workerpool.workers against a local // ManualReader-backed provider so tests stay parallel-safe and never touch the // global meter provider. -func newWorkerCountReader(t *testing.T, workers func() ([]*ateapipb.Worker, error), listPools func(labels.Selector) ([]*atev1alpha1.WorkerPool, error)) *sdkmetric.ManualReader { +func newWorkerCountReader(t *testing.T, workers func() ([]*ateapi.Worker, error), listPools func(labels.Selector) ([]*atev1.WorkerPool, error)) *sdkmetric.ManualReader { t.Helper() reader := sdkmetric.NewManualReader() mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) @@ -47,7 +47,7 @@ func newWorkerCountReader(t *testing.T, workers func() ([]*ateapipb.Worker, erro return reader } -func noPools(labels.Selector) ([]*atev1alpha1.WorkerPool, error) { return nil, nil } +func noPools(labels.Selector) ([]*atev1.WorkerPool, error) { return nil, nil } func collectMetric(t *testing.T, reader *sdkmetric.ManualReader, name string) (metricdata.Metrics, bool) { t.Helper() @@ -75,18 +75,18 @@ func mustMetric(t *testing.T, reader *sdkmetric.ManualReader, name string) metri } // worker builds an ACTIVE worker holding allocated of capacity actor slots. -func worker(namespace, pool, class string, allocated, capacity int32) *ateapipb.Worker { - w := &ateapipb.Worker{ +func worker(namespace, pool, class string, allocated, capacity int32) *ateapi.Worker { + w := &ateapi.Worker{ WorkerNamespace: namespace, WorkerPool: pool, - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: capacity}, - Allocated: &ateapipb.WorkerResources{Actors: allocated}, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: capacity}, + Allocated: &ateapi.WorkerResources{Actors: allocated}, }, } if class != "" { - w.Status.SandboxClasses = []*ateapipb.WorkerSandboxClass{{SandboxClass: class}} + w.Status.SandboxClasses = []*ateapi.WorkerSandboxClass{{SandboxClass: class}} } return w } @@ -129,8 +129,8 @@ func seriesCounts(sum metricdata.Sum[int64]) map[series]int64 { // TestWorkerCountTally covers the tally, including two pools that share a name in // different namespaces: a WorkerPool is namespaced, so those must stay two series. func TestWorkerCountTally(t *testing.T) { - workers := func() ([]*ateapipb.Worker, error) { - return []*ateapipb.Worker{ + workers := func() ([]*ateapi.Worker, error) { + return []*ateapi.Worker{ worker("ns-1", "pool-a", "gvisor", 0, 1), worker("ns-1", "pool-a", "gvisor", 0, 1), worker("ns-1", "pool-a", "gvisor", 1, 1), @@ -174,7 +174,7 @@ func TestWorkerCountTally(t *testing.T) { // TestWorkerCountSkipsWhenCacheNotReady asserts the callback emits nothing while // the cache is warming up, so we never publish misleading zero-valued points. func TestWorkerCountSkipsWhenCacheNotReady(t *testing.T) { - notReady := func() ([]*ateapipb.Worker, error) { + notReady := func() ([]*ateapi.Worker, error) { return nil, context.DeadlineExceeded } reader := newWorkerCountReader(t, notReady, noPools) @@ -242,13 +242,13 @@ func attrString(dp metricdata.HistogramDataPoint[float64], k attribute.Key) (str func TestLifecycleOpDurationShape(t *testing.T) { inst, reader := newTestInstruments(t) - actor := &ateapipb.Actor{ - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ate-agents", Name: "support-agent"}, - Status: &ateapipb.ActorStatus{ - WorkerAssignment: &ateapipb.WorkerAssignment{ + actor := &ateapi.Actor{ + ActorTemplate: &ateapi.ObjectRef{Atespace: "ate-agents", Name: "support-agent"}, + Status: &ateapi.ActorStatus{ + WorkerAssignment: &ateapi.WorkerAssignment{ WorkerNamespace: "ate-workers", WorkerPool: "pool-a", - SandboxRuntime: &ateapipb.ActorSandboxRuntime{SandboxClass: "gvisor"}, + SandboxRuntime: &ateapi.ActorSandboxRuntime{SandboxClass: "gvisor"}, }, }, } @@ -289,7 +289,7 @@ func TestLifecycleOpDurationShape(t *testing.T) { // series would be indistinguishable from a real one. The unassigned actor also // pins the pool pair: a failure before the assign step emits neither key. func TestLifecycleOpAttrsOmitsUnknownScope(t *testing.T) { - actor := &ateapipb.Actor{ActorTemplate: &ateapipb.ObjectRef{Atespace: "ate-agents", Name: "support-agent"}} + actor := &ateapi.Actor{ActorTemplate: &ateapi.ObjectRef{Atespace: "ate-agents", Name: "support-agent"}} for _, kv := range lifecycleOpAttrs(actor, "", "") { switch kv.Key { case ateattr.SnapshotFidelityKey, ateattr.SnapshotKindKey, ateattr.WorkerPoolNamespaceKey, ateattr.WorkerPoolNameKey, ateattr.SandboxClassKey: @@ -411,10 +411,10 @@ func TestSchedulerAssignmentShapeAndOutcomes(t *testing.T) { } } -func workerPool(namespace, name string, class atev1alpha1.SandboxClass) *atev1alpha1.WorkerPool { - return &atev1alpha1.WorkerPool{ +func workerPool(namespace, name string, class atev1.SandboxClass) *atev1.WorkerPool { + return &atev1.WorkerPool{ ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: name}, - Spec: atev1alpha1.WorkerPoolSpec{SandboxClasses: []atev1alpha1.WorkerPoolSandboxClass{{Name: class}}}, + Spec: atev1.WorkerPoolSpec{SandboxClasses: []atev1.WorkerPoolSandboxClass{{Name: class}}}, } } @@ -422,14 +422,14 @@ func workerPool(namespace, name string, class atev1alpha1.SandboxClass) *atev1al // only state has no workers, and a pool with no workers at all, both report 0 // rather than an absent series. Empty pool class defaults to gvisor. func TestWorkerCountSeedsZeroForKnownPools(t *testing.T) { - pools := func(labels.Selector) ([]*atev1alpha1.WorkerPool, error) { - return []*atev1alpha1.WorkerPool{ + pools := func(labels.Selector) ([]*atev1.WorkerPool, error) { + return []*atev1.WorkerPool{ workerPool("ns-1", "pool-a", ""), - workerPool("ns-2", "pool-a", atev1alpha1.SandboxClassMicroVM), + workerPool("ns-2", "pool-a", atev1.SandboxClassMicroVM), }, nil } - workers := func() ([]*ateapipb.Worker, error) { - return []*ateapipb.Worker{worker("ns-1", "pool-a", "gvisor", 1, 1)}, nil + workers := func() ([]*ateapi.Worker, error) { + return []*ateapi.Worker{worker("ns-1", "pool-a", "gvisor", 1, 1)}, nil } reader := newWorkerCountReader(t, workers, pools) @@ -455,19 +455,19 @@ func TestWorkerCountSeedsZeroForKnownPools(t *testing.T) { // an idle==0 alert on it still fires. func TestWorkerCountEmptyClassWorker(t *testing.T) { const ( - gvisor = string(atev1alpha1.SandboxClassGvisor) - microvm = string(atev1alpha1.SandboxClassMicroVM) + gvisor = string(atev1.SandboxClassGvisor) + microvm = string(atev1.SandboxClassMicroVM) ) tests := []struct { name string - pools []*atev1alpha1.WorkerPool - workers []*ateapipb.Worker + pools []*atev1.WorkerPool + workers []*ateapi.Worker want map[series]int64 }{ { name: "gvisor pool", - pools: []*atev1alpha1.WorkerPool{workerPool("ns-1", "pool-empty", "")}, - workers: []*ateapipb.Worker{ + pools: []*atev1.WorkerPool{workerPool("ns-1", "pool-empty", "")}, + workers: []*ateapi.Worker{ worker("ns-1", "pool-empty", "", 0, 1), worker("ns-1", "pool-empty", "", 0, 1), worker("ns-1", "pool-empty", "", 0, 1), @@ -478,8 +478,8 @@ func TestWorkerCountEmptyClassWorker(t *testing.T) { { // No gvisor series shows for a pool that runs no gvisor. name: "microvm pool", - pools: []*atev1alpha1.WorkerPool{workerPool("ns-1", "pool-micro", atev1alpha1.SandboxClassMicroVM)}, - workers: []*ateapipb.Worker{worker("ns-1", "pool-micro", "", 0, 1)}, + pools: []*atev1.WorkerPool{workerPool("ns-1", "pool-micro", atev1.SandboxClassMicroVM)}, + workers: []*ateapi.Worker{worker("ns-1", "pool-micro", "", 0, 1)}, want: withCount(seeded(nil, "ns-1", "pool-micro", microvm), series{"ns-1", "pool-micro", ateattr.WorkerStateIdle, ateattr.SandboxClassUnknown}, 1), }, @@ -487,7 +487,7 @@ func TestWorkerCountEmptyClassWorker(t *testing.T) { // A worker that matches no pool has no class to fall back to. name: "orphan worker", pools: nil, - workers: []*ateapipb.Worker{worker("ns-1", "pool-orphan", "", 0, 1)}, + workers: []*ateapi.Worker{worker("ns-1", "pool-orphan", "", 0, 1)}, want: map[series]int64{ {"ns-1", "pool-orphan", ateattr.WorkerStateIdle, ateattr.SandboxClassUnknown}: 1, }, @@ -496,8 +496,8 @@ func TestWorkerCountEmptyClassWorker(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - pools := func(labels.Selector) ([]*atev1alpha1.WorkerPool, error) { return tt.pools, nil } - workers := func() ([]*ateapipb.Worker, error) { return tt.workers, nil } + pools := func(labels.Selector) ([]*atev1.WorkerPool, error) { return tt.pools, nil } + workers := func() ([]*ateapi.Worker, error) { return tt.workers, nil } reader := newWorkerCountReader(t, workers, pools) sum := mustMetric(t, reader, workerpoolWorkersMetric).Data.(metricdata.Sum[int64]) @@ -517,27 +517,27 @@ func TestWorkerCountEmptyClassWorker(t *testing.T) { func TestWorkerState(t *testing.T) { tests := []struct { name string - state ateapipb.WorkerState - capacity *ateapipb.WorkerResources - allocated *ateapipb.WorkerResources + state ateapi.WorkerState + capacity *ateapi.WorkerResources + allocated *ateapi.WorkerResources want string }{ - {"empty", ateapipb.WorkerState_WORKER_STATE_ACTIVE, &ateapipb.WorkerResources{Actors: 20}, nil, ateattr.WorkerStateIdle}, - {"some slots used", ateapipb.WorkerState_WORKER_STATE_ACTIVE, &ateapipb.WorkerResources{Actors: 20}, &ateapipb.WorkerResources{Actors: 3}, ateattr.WorkerStatePartial}, - {"one below capacity", ateapipb.WorkerState_WORKER_STATE_ACTIVE, &ateapipb.WorkerResources{Actors: 20}, &ateapipb.WorkerResources{Actors: 19}, ateattr.WorkerStatePartial}, - {"all slots used", ateapipb.WorkerState_WORKER_STATE_ACTIVE, &ateapipb.WorkerResources{Actors: 20}, &ateapipb.WorkerResources{Actors: 20}, ateattr.WorkerStateAtCapacity}, - {"single slot used", ateapipb.WorkerState_WORKER_STATE_ACTIVE, &ateapipb.WorkerResources{Actors: 1}, &ateapipb.WorkerResources{Actors: 1}, ateattr.WorkerStateAtCapacity}, + {"empty", ateapi.WorkerState_WORKER_STATE_ACTIVE, &ateapi.WorkerResources{Actors: 20}, nil, ateattr.WorkerStateIdle}, + {"some slots used", ateapi.WorkerState_WORKER_STATE_ACTIVE, &ateapi.WorkerResources{Actors: 20}, &ateapi.WorkerResources{Actors: 3}, ateattr.WorkerStatePartial}, + {"one below capacity", ateapi.WorkerState_WORKER_STATE_ACTIVE, &ateapi.WorkerResources{Actors: 20}, &ateapi.WorkerResources{Actors: 19}, ateattr.WorkerStatePartial}, + {"all slots used", ateapi.WorkerState_WORKER_STATE_ACTIVE, &ateapi.WorkerResources{Actors: 20}, &ateapi.WorkerResources{Actors: 20}, ateattr.WorkerStateAtCapacity}, + {"single slot used", ateapi.WorkerState_WORKER_STATE_ACTIVE, &ateapi.WorkerResources{Actors: 1}, &ateapi.WorkerResources{Actors: 1}, ateattr.WorkerStateAtCapacity}, // Capacity can shrink below the allocation on a later report. - {"over capacity", ateapipb.WorkerState_WORKER_STATE_ACTIVE, &ateapipb.WorkerResources{Actors: 2}, &ateapipb.WorkerResources{Actors: 5}, ateattr.WorkerStateAtCapacity}, - {"capacity not reported yet", ateapipb.WorkerState_WORKER_STATE_ACTIVE, nil, nil, ateattr.WorkerStateUnschedulable}, - {"zero capacity", ateapipb.WorkerState_WORKER_STATE_ACTIVE, &ateapipb.WorkerResources{Actors: 0}, nil, ateattr.WorkerStateUnschedulable}, - {"draining and empty", ateapipb.WorkerState_WORKER_STATE_DRAINING, &ateapipb.WorkerResources{Actors: 20}, nil, ateattr.WorkerStateUnschedulable}, - {"draining with actors", ateapipb.WorkerState_WORKER_STATE_DRAINING, &ateapipb.WorkerResources{Actors: 20}, &ateapipb.WorkerResources{Actors: 3}, ateattr.WorkerStateUnschedulable}, - {"state unspecified", ateapipb.WorkerState_WORKER_STATE_UNSPECIFIED, &ateapipb.WorkerResources{Actors: 20}, nil, ateattr.WorkerStateUnschedulable}, + {"over capacity", ateapi.WorkerState_WORKER_STATE_ACTIVE, &ateapi.WorkerResources{Actors: 2}, &ateapi.WorkerResources{Actors: 5}, ateattr.WorkerStateAtCapacity}, + {"capacity not reported yet", ateapi.WorkerState_WORKER_STATE_ACTIVE, nil, nil, ateattr.WorkerStateUnschedulable}, + {"zero capacity", ateapi.WorkerState_WORKER_STATE_ACTIVE, &ateapi.WorkerResources{Actors: 0}, nil, ateattr.WorkerStateUnschedulable}, + {"draining and empty", ateapi.WorkerState_WORKER_STATE_DRAINING, &ateapi.WorkerResources{Actors: 20}, nil, ateattr.WorkerStateUnschedulable}, + {"draining with actors", ateapi.WorkerState_WORKER_STATE_DRAINING, &ateapi.WorkerResources{Actors: 20}, &ateapi.WorkerResources{Actors: 3}, ateattr.WorkerStateUnschedulable}, + {"state unspecified", ateapi.WorkerState_WORKER_STATE_UNSPECIFIED, &ateapi.WorkerResources{Actors: 20}, nil, ateattr.WorkerStateUnschedulable}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - w := &ateapipb.Worker{Status: &ateapipb.WorkerStatus{State: tt.state, Capacity: tt.capacity, Allocated: tt.allocated}} + w := &ateapi.Worker{Status: &ateapi.WorkerStatus{State: tt.state, Capacity: tt.capacity, Allocated: tt.allocated}} if got := workerState(w); got != tt.want { t.Errorf("workerState = %q, want %q", got, tt.want) } @@ -549,20 +549,20 @@ func TestWorkerState(t *testing.T) { // state, so the sum over the states stays the size of the pool. func TestWorkerCountSumsToPool(t *testing.T) { draining := worker("ns-1", "pool-a", "gvisor", 2, 4) - draining.Status.State = ateapipb.WorkerState_WORKER_STATE_DRAINING + draining.Status.State = ateapi.WorkerState_WORKER_STATE_DRAINING unreported := worker("ns-1", "pool-a", "gvisor", 0, 0) unreported.Status.Capacity = nil - ws := []*ateapipb.Worker{ + ws := []*ateapi.Worker{ worker("ns-1", "pool-a", "gvisor", 0, 4), worker("ns-1", "pool-a", "gvisor", 2, 4), worker("ns-1", "pool-a", "gvisor", 4, 4), draining, unreported, } - pools := func(labels.Selector) ([]*atev1alpha1.WorkerPool, error) { - return []*atev1alpha1.WorkerPool{workerPool("ns-1", "pool-a", "")}, nil + pools := func(labels.Selector) ([]*atev1.WorkerPool, error) { + return []*atev1.WorkerPool{workerPool("ns-1", "pool-a", "")}, nil } - reader := newWorkerCountReader(t, func() ([]*ateapipb.Worker, error) { return ws, nil }, pools) + reader := newWorkerCountReader(t, func() ([]*ateapi.Worker, error) { return ws, nil }, pools) got := seriesCounts(mustMetric(t, reader, workerpoolWorkersMetric).Data.(metricdata.Sum[int64])) want := seeded(nil, "ns-1", "pool-a", "gvisor") diff --git a/cmd/ateapi/internal/controlapi/mint_after_release_test.go b/cmd/ateapi/internal/controlapi/mint_after_release_test.go index 7d0ecbff03..73af51d7ae 100644 --- a/cmd/ateapi/internal/controlapi/mint_after_release_test.go +++ b/cmd/ateapi/internal/controlapi/mint_after_release_test.go @@ -24,6 +24,7 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/ateletauth/ateletauthtest" "go.ate.dev/substrate/cmd/ateapi/internal/controlapi" "go.ate.dev/substrate/cmd/ateapi/internal/store" @@ -33,7 +34,6 @@ import ( "go.ate.dev/substrate/internal/installdefaults" "go.ate.dev/substrate/internal/localca" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" ) @@ -53,7 +53,7 @@ func TestMintWorkerActorCertificateAfterWorkerRelease(t *testing.T) { t.Run(wf.Name, func(t *testing.T) { ctx := context.Background() persistence := controlapi.NewTestPersistence(t) - controlapi.SeedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{StorageLocation: controlapi.TestStorageLocation}) + controlapi.SeedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{StorageLocation: controlapi.TestStorageLocation}) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} // wa's worker hosts the actor; the neighbor is another worker on // its node. @@ -63,41 +63,41 @@ func TestMintWorkerActorCertificateAfterWorkerRelease(t *testing.T) { {workerName, wa.GetWorkerPod(), wa.GetWorkerPodUid()}, {neighborName, "neighbor-pod", "neighbor-pod-uid"}, } { - if _, err := persistence.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: w.name}, + if _, err := persistence.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: w.name}, WorkerNamespace: wa.GetWorkerNamespace(), WorkerPool: wa.GetWorkerPool(), WorkerPod: w.pod, WorkerPodUid: w.podUID, NodeName: node, // Registered, with a sandbox class, so the scheduler takes it. - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, RegisteredEpoch: 1, - Capacity: &ateapipb.WorkerResources{Actors: 1}, - SandboxClasses: []*ateapipb.WorkerSandboxClass{{SandboxClass: "gvisor"}}, + Capacity: &ateapi.WorkerResources{Actors: 1}, + SandboxClasses: []*ateapi.WorkerSandboxClass{{SandboxClass: "gvisor"}}, }, }); err != nil { t.Fatalf("CreateWorker(%s): %v", w.name, err) } } - status := &ateapipb.ActorStatus{ + status := &ateapi.ActorStatus{ State: wf.State, AssignedNode: node, WorkerAssignment: controlapi.WireTestAssignment(), LastAssignedGeneration: 1, } if wf.Snapshot != nil { - status.Snapshots = []*ateapipb.Snapshot{wf.Snapshot(t)} + status.Snapshots = []*ateapi.Snapshot{wf.Snapshot(t)} } - created := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + created := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: controlapi.SuspendTestTemplateRef(), Status: status, }) uid := created.GetMetadata().GetUid() - controlapi.SeedAssignment(t, persistence, workerName, &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: actorRef.Atespace, Name: actorRef.Name}, + controlapi.SeedAssignment(t, persistence, workerName, &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorUid: uid, }) @@ -107,18 +107,18 @@ func TestMintWorkerActorCertificateAfterWorkerRelease(t *testing.T) { // atelet on node. mintAs := func(worker string) codes.Code { t.Helper() - _, err := minter.MintWorkerActorCertificate(ateletauthtest.ContextWith(ateletauthtest.CertOn(t, node)), &ateapipb.MintWorkerActorCertificateRequest{ - Actor: &ateapipb.ObjectRef{Atespace: actorRef.Atespace, Name: actorRef.Name}, + _, err := minter.MintWorkerActorCertificate(ateletauthtest.ContextWith(ateletauthtest.CertOn(t, node)), &ateapi.MintWorkerActorCertificateRequest{ + Actor: &ateapi.ObjectRef{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorUid: uid, CertificateSigningRequest: csr, - Worker: &ateapipb.ObjectRef{Name: worker}, + Worker: &ateapi.ObjectRef{Name: worker}, }) return apierror.Code(err) } // mint asks for the actor's certificate as the worker that the // actor is assigned to and returns the actor as the mint saw it // and the mint's code. - mint := func(stage string) (*ateapipb.Actor, codes.Code) { + mint := func(stage string) (*ateapi.Actor, codes.Code) { t.Helper() code := mintAs(workerName) actor, gerr := persistence.GetActor(ctx, actorRef) @@ -154,8 +154,8 @@ func TestMintWorkerActorCertificateAfterWorkerRelease(t *testing.T) { } // The worker takes another actor. - controlapi.SeedAssignment(t, persistence, workerName, &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: actorRef.Atespace, Name: "actor-2"}, + controlapi.SeedAssignment(t, persistence, workerName, &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: actorRef.Atespace, Name: "actor-2"}, ActorUid: "5c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f", }) if _, got := mint("worker rebooked for another actor"); got != codes.NotFound { diff --git a/cmd/ateapi/internal/controlapi/pagination.go b/cmd/ateapi/internal/controlapi/pagination.go index 61e24e74fc..0c6ce2b2b4 100644 --- a/cmd/ateapi/internal/controlapi/pagination.go +++ b/cmd/ateapi/internal/controlapi/pagination.go @@ -17,9 +17,9 @@ package controlapi import ( "errors" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const maxPageSize = 1000 @@ -33,7 +33,7 @@ func effectivePageSize(requested int32) int32 { return requested } -func toStoreListOptions(opts *ateapipb.ListOptions) store.ListOptions { +func toStoreListOptions(opts *ateapi.ListOptions) store.ListOptions { return store.ListOptions{PageSize: effectivePageSize(opts.GetPageSize()), PageToken: opts.GetPageToken()} } diff --git a/cmd/ateapi/internal/controlapi/pagination_test.go b/cmd/ateapi/internal/controlapi/pagination_test.go index 81325afe79..cb3d81499c 100644 --- a/cmd/ateapi/internal/controlapi/pagination_test.go +++ b/cmd/ateapi/internal/controlapi/pagination_test.go @@ -17,14 +17,14 @@ package controlapi import ( "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) func TestToStoreListOptions(t *testing.T) { tests := []struct { name string - opts *ateapipb.ListOptions + opts *ateapi.ListOptions want store.ListOptions }{{ name: "nil options default the page size", @@ -32,15 +32,15 @@ func TestToStoreListOptions(t *testing.T) { want: store.ListOptions{PageSize: 1000}, }, { name: "unset page size defaults", - opts: &ateapipb.ListOptions{PageToken: "tok"}, + opts: &ateapi.ListOptions{PageToken: "tok"}, want: store.ListOptions{PageSize: 1000, PageToken: "tok"}, }, { name: "page size within the cap is kept", - opts: &ateapipb.ListOptions{PageSize: 10, PageToken: "tok"}, + opts: &ateapi.ListOptions{PageSize: 10, PageToken: "tok"}, want: store.ListOptions{PageSize: 10, PageToken: "tok"}, }, { name: "page size above the cap is coerced", - opts: &ateapipb.ListOptions{PageSize: 5000}, + opts: &ateapi.ListOptions{PageSize: 5000}, want: store.ListOptions{PageSize: 1000}, }} for _, tt := range tests { diff --git a/cmd/ateapi/internal/controlapi/service.go b/cmd/ateapi/internal/controlapi/service.go index dc3fb6513b..65a2fc9d53 100644 --- a/cmd/ateapi/internal/controlapi/service.go +++ b/cmd/ateapi/internal/controlapi/service.go @@ -19,6 +19,8 @@ import ( "sync" "time" + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/workercache" "go.ate.dev/substrate/internal/localca" @@ -26,37 +28,35 @@ import ( "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/volume" "go.ate.dev/substrate/internal/volume/csi" - listersv1alpha1 "go.ate.dev/substrate/pkg/client/listers/api/v1alpha1" - "go.ate.dev/substrate/pkg/proto/ateapipb" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" + atelisters "go.ate.dev/substrate/pkg/client/listers/ate/v1" storagev1listers "k8s.io/client-go/listers/storage/v1" ) -// RPCService implements ateapipb.ControlServer and provides the implementation of +// RPCService implements ateapi.ControlServer and provides the implementation of // the RPC service. // // Methods on this service should be as light as possible, delegating to the // ServiceImpl for business logic and invariants. type RPCService struct { - ateapipb.UnimplementedControlServer + ateapi.UnimplementedControlServer impl serviceStore persistence serviceStore workerCache *workercache.Cache dialer *AteletDialer - csiDriverConfigLister listersv1alpha1.CSIDriverConfigLister + csiDriverConfigLister atelisters.CSIDriverConfigLister actorWorkflow *ActorWorkflow workerWorkflow *WorkerWorkflow instruments *Instruments mu sync.RWMutex volumePlugins map[string]volume.VolumePluginControlPlane - objectStorePlugin objectstorev1.ControlProviderClient + objectStorePlugin objectstore.ControlProviderClient actorJWTIssuer string actorIDJWTPool localjwtauthority.Pool actorIDCAPool localca.Pool } -var _ ateapipb.ControlServer = (*RPCService)(nil) +var _ ateapi.ControlServer = (*RPCService)(nil) // VolumePluginRegistry defines the interface for dynamic CSI plugin resolution. type VolumePluginRegistry interface { @@ -80,14 +80,14 @@ type VolumePluginRegistry interface { func NewRPCService( persistence store.Interface, workerCache *workercache.Cache, - csiDriverConfigLister listersv1alpha1.CSIDriverConfigLister, + csiDriverConfigLister atelisters.CSIDriverConfigLister, storageClassLister storagev1listers.StorageClassLister, dialer *AteletDialer, instruments *Instruments, egressGatewayAddress string, actorWorkflowDeadline time.Duration, volumePlugins map[string]volume.VolumePluginControlPlane, - objectStorePlugin objectstorev1.ControlProviderClient, + objectStorePlugin objectstore.ControlProviderClient, actorJWTIssuer string, actorIDJWTPool localjwtauthority.Pool, actorIDCAPool localca.Pool, @@ -117,38 +117,38 @@ func NewRPCService( // serviceStore enumerates the exact storage methods needed by // the control API and nothing more. type serviceStore interface { - CreateActor(ctx context.Context, actor *ateapipb.Actor) (*ateapipb.Actor, error) - GetActor(ctx context.Context, actorRef resources.ActorRef) (*ateapipb.Actor, error) - UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(toUpdate *ateapipb.Actor) error) (*ateapipb.Actor, error) - ListActors(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapipb.Actor], error) - CreateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, policy *ateapipb.EgressPolicy) (*ateapipb.EgressPolicy, error) - GetEgressPolicy(ctx context.Context, actorRef resources.ActorRef) (*ateapipb.EgressPolicy, error) - UpdateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(*ateapipb.EgressPolicy) error) (*ateapipb.EgressPolicy, error) - DeleteEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (*ateapipb.EgressPolicy, error) - GetTag(ctx context.Context, tagRef resources.TagRef) (*ateapipb.Tag, error) - ListTags(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapipb.Tag], error) - UpdateTag(ctx context.Context, tagRef resources.TagRef, precondition store.Precondition, mutate func(toUpdate *ateapipb.Tag) error) (*ateapipb.Tag, error) - DeleteTag(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions) (*ateapipb.Tag, error) - CreateAtespace(ctx context.Context, atespace *ateapipb.Atespace) (*ateapipb.Atespace, error) - GetAtespace(ctx context.Context, name string) (*ateapipb.Atespace, error) - ListAtespaces(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapipb.Atespace], error) - DeleteAtespace(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapipb.Atespace, error) - CreateGlobalAccessPolicy(ctx context.Context, policy *ateapipb.AccessPolicy) (*ateapipb.AccessPolicy, error) - GetGlobalAccessPolicy(ctx context.Context) (*ateapipb.AccessPolicy, error) - UpdateGlobalAccessPolicy(ctx context.Context, precondition store.Precondition, mutate func(*ateapipb.AccessPolicy) error) (*ateapipb.AccessPolicy, error) - CreateAtespaceAccessPolicy(ctx context.Context, name string, policy *ateapipb.AccessPolicy) (*ateapipb.AccessPolicy, error) - GetAtespaceAccessPolicy(ctx context.Context, name string) (*ateapipb.AccessPolicy, error) - UpdateAtespaceAccessPolicy(ctx context.Context, name string, precondition store.Precondition, mutate func(*ateapipb.AccessPolicy) error) (*ateapipb.AccessPolicy, error) - DeleteAtespaceAccessPolicy(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapipb.AccessPolicy, error) - CreateActorTemplate(ctx context.Context, template *ateapipb.ActorTemplate) (*ateapipb.ActorTemplate, error) - GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapipb.ActorTemplate, error) - ListActorTemplates(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapipb.ActorTemplate], error) - DeleteActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions) (*ateapipb.ActorTemplate, error) - ListWorkers(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapipb.Worker], error) - GetWorker(ctx context.Context, name string) (*ateapipb.Worker, error) - ListWorkerAssignments(ctx context.Context, workerName string, opts store.ListOptions) (store.ListResponse[*ateapipb.ActorAssignment], error) - CreateWorker(ctx context.Context, worker *ateapipb.Worker) (*ateapipb.Worker, error) - UpdateWorker(ctx context.Context, name string, precondition store.Precondition, mutate func(toUpdate *ateapipb.Worker) error) (*ateapipb.Worker, error) + CreateActor(ctx context.Context, actor *ateapi.Actor) (*ateapi.Actor, error) + GetActor(ctx context.Context, actorRef resources.ActorRef) (*ateapi.Actor, error) + UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(toUpdate *ateapi.Actor) error) (*ateapi.Actor, error) + ListActors(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapi.Actor], error) + CreateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, policy *ateapi.EgressPolicy) (*ateapi.EgressPolicy, error) + GetEgressPolicy(ctx context.Context, actorRef resources.ActorRef) (*ateapi.EgressPolicy, error) + UpdateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(*ateapi.EgressPolicy) error) (*ateapi.EgressPolicy, error) + DeleteEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (*ateapi.EgressPolicy, error) + GetTag(ctx context.Context, tagRef resources.TagRef) (*ateapi.Tag, error) + ListTags(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapi.Tag], error) + UpdateTag(ctx context.Context, tagRef resources.TagRef, precondition store.Precondition, mutate func(toUpdate *ateapi.Tag) error) (*ateapi.Tag, error) + DeleteTag(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions) (*ateapi.Tag, error) + CreateAtespace(ctx context.Context, atespace *ateapi.Atespace) (*ateapi.Atespace, error) + GetAtespace(ctx context.Context, name string) (*ateapi.Atespace, error) + ListAtespaces(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapi.Atespace], error) + DeleteAtespace(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.Atespace, error) + CreateGlobalAccessPolicy(ctx context.Context, policy *ateapi.AccessPolicy) (*ateapi.AccessPolicy, error) + GetGlobalAccessPolicy(ctx context.Context) (*ateapi.AccessPolicy, error) + UpdateGlobalAccessPolicy(ctx context.Context, precondition store.Precondition, mutate func(*ateapi.AccessPolicy) error) (*ateapi.AccessPolicy, error) + CreateAtespaceAccessPolicy(ctx context.Context, name string, policy *ateapi.AccessPolicy) (*ateapi.AccessPolicy, error) + GetAtespaceAccessPolicy(ctx context.Context, name string) (*ateapi.AccessPolicy, error) + UpdateAtespaceAccessPolicy(ctx context.Context, name string, precondition store.Precondition, mutate func(*ateapi.AccessPolicy) error) (*ateapi.AccessPolicy, error) + DeleteAtespaceAccessPolicy(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.AccessPolicy, error) + CreateActorTemplate(ctx context.Context, template *ateapi.ActorTemplate) (*ateapi.ActorTemplate, error) + GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapi.ActorTemplate, error) + ListActorTemplates(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapi.ActorTemplate], error) + DeleteActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions) (*ateapi.ActorTemplate, error) + ListWorkers(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapi.Worker], error) + GetWorker(ctx context.Context, name string) (*ateapi.Worker, error) + ListWorkerAssignments(ctx context.Context, workerName string, opts store.ListOptions) (store.ListResponse[*ateapi.ActorAssignment], error) + CreateWorker(ctx context.Context, worker *ateapi.Worker) (*ateapi.Worker, error) + UpdateWorker(ctx context.Context, name string, precondition store.Precondition, mutate func(toUpdate *ateapi.Worker) error) (*ateapi.Worker, error) AcquireLease(ctx context.Context, key string) (*store.Lease, error) } diff --git a/cmd/ateapi/internal/controlapi/snapshot_helpers.go b/cmd/ateapi/internal/controlapi/snapshot_helpers.go index 45c027d7ed..3e29b78312 100644 --- a/cmd/ateapi/internal/controlapi/snapshot_helpers.go +++ b/cmd/ateapi/internal/controlapi/snapshot_helpers.go @@ -15,14 +15,14 @@ package controlapi import ( + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/preview" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // findSnapshotByGeneration returns the Snapshot in snapshots with the given // generation, or nil if none exists. -func findSnapshotByGeneration(snapshots []*ateapipb.Snapshot, gen int32) *ateapipb.Snapshot { +func findSnapshotByGeneration(snapshots []*ateapi.Snapshot, gen int32) *ateapi.Snapshot { for _, snap := range snapshots { if snap.GetGeneration() == gen { return snap @@ -33,7 +33,7 @@ func findSnapshotByGeneration(snapshots []*ateapipb.Snapshot, gen int32) *ateapi // snapshotAtLatestGeneration returns the Snapshot at status.last_assigned_generation, or // nil if none exists. -func snapshotAtLatestGeneration(status *ateapipb.ActorStatus) *ateapipb.Snapshot { +func snapshotAtLatestGeneration(status *ateapi.ActorStatus) *ateapi.Snapshot { if status == nil { return nil } @@ -42,8 +42,8 @@ func snapshotAtLatestGeneration(status *ateapipb.ActorStatus) *ateapipb.Snapshot // latestSnapshot returns the highest-generation Snapshot on status that // matches, or nil if none does. -func latestSnapshot(status *ateapipb.ActorStatus, matches func(*ateapipb.Snapshot) bool) *ateapipb.Snapshot { - var latest *ateapipb.Snapshot +func latestSnapshot(status *ateapi.ActorStatus, matches func(*ateapi.Snapshot) bool) *ateapi.Snapshot { + var latest *ateapi.Snapshot for _, snap := range status.GetSnapshots() { if matches(snap) && (latest == nil || snap.GetGeneration() >= latest.GetGeneration()) { latest = snap @@ -54,28 +54,28 @@ func latestSnapshot(status *ateapipb.ActorStatus, matches func(*ateapipb.Snapsho // findLatestDurableSnapshot returns the highest-generation Snapshot on status // whose DurableSnapshot matches storageStatus, or nil if none exists. -func findLatestDurableSnapshot(status *ateapipb.ActorStatus, storageStatus ateapipb.SnapshotStorageStatus) *ateapipb.Snapshot { - return latestSnapshot(status, func(snap *ateapipb.Snapshot) bool { +func findLatestDurableSnapshot(status *ateapi.ActorStatus, storageStatus ateapi.SnapshotStorageStatus) *ateapi.Snapshot { + return latestSnapshot(status, func(snap *ateapi.Snapshot) bool { return snap.GetDurableSnapshot().GetStatus() == storageStatus }) } // findLatestLocalSnapshot returns the highest-generation snapshot with a local copy. -func findLatestLocalSnapshot(status *ateapipb.ActorStatus) *ateapipb.Snapshot { - return latestSnapshot(status, func(snap *ateapipb.Snapshot) bool { +func findLatestLocalSnapshot(status *ateapi.ActorStatus) *ateapi.Snapshot { + return latestSnapshot(status, func(snap *ateapi.Snapshot) bool { return snap.GetLocality() != "" }) } // latestSnapshotIsLocal reports whether the latest generation has a local copy. -func latestSnapshotIsLocal(status *ateapipb.ActorStatus) bool { +func latestSnapshotIsLocal(status *ateapi.ActorStatus) bool { return snapshotAtLatestGeneration(status).GetLocality() != "" } // clearLocalSnapshots clears Locality across all Snapshots in status.Snapshots // without dropping PENDING durable snapshots (so DeleteActor can still collect // an in-flight durable snapshot after releasing the worker). -func clearLocalSnapshots(status *ateapipb.ActorStatus) { +func clearLocalSnapshots(status *ateapi.ActorStatus) { for _, snap := range status.GetSnapshots() { snap.Locality = "" } @@ -103,11 +103,11 @@ func clearLocalSnapshots(status *ateapipb.ActorStatus) { // status.LastAssignedGeneration is not decreased so that we can keep track of // stale snapshots that need to be cleaned up and discarded generation numbers // are never reused. -func pruneSnapshots(status *ateapipb.ActorStatus, local *ateapipb.Snapshot) { +func pruneSnapshots(status *ateapi.ActorStatus, local *ateapi.Snapshot) { if status == nil { return } - latestDurable := findLatestDurableSnapshot(status, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + latestDurable := findLatestDurableSnapshot(status, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) kept := status.Snapshots[:0] for _, snap := range status.Snapshots { if snap != local { @@ -121,16 +121,16 @@ func pruneSnapshots(status *ateapipb.ActorStatus, local *ateapipb.Snapshot) { } // newDurableSnapshot constructs a Snapshot with DurableSnapshot populated. -func newDurableSnapshot(gen int32, owner ateapipb.SnapshotOwner, fidelity ateapipb.SnapshotFidelity, templateUID, uuid, uri string, storageStatus ateapipb.SnapshotStorageStatus) *ateapipb.Snapshot { - return &ateapipb.Snapshot{ +func newDurableSnapshot(gen int32, owner ateapi.SnapshotOwner, fidelity ateapi.SnapshotFidelity, templateUID, uuid, uri string, storageStatus ateapi.SnapshotStorageStatus) *ateapi.Snapshot { + return &ateapi.Snapshot{ Uuid: uuid, Generation: gen, Owner: owner, Fidelity: fidelity, ActorTemplateUid: templateUID, - DurableSnapshot: &ateapipb.SnapshotStorage{ + DurableSnapshot: &ateapi.SnapshotStorage{ Status: storageStatus, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: uri}, + Object: &ateapi.ObjectSnapshot{SnapshotUri: uri}, }, } } @@ -138,9 +138,9 @@ func newDurableSnapshot(gen int32, owner ateapipb.SnapshotOwner, fidelity ateapi // tagDurableSnapshotURI returns the durable snapshot URI on tag matching // storageStatus (or any status if storageStatus is UNSPECIFIED), or "" if none // exists. -func tagDurableSnapshotURI(tag *ateapipb.Tag, storageStatus ateapipb.SnapshotStorageStatus) string { +func tagDurableSnapshotURI(tag *ateapi.Tag, storageStatus ateapi.SnapshotStorageStatus) string { st := tag.GetStatus().GetSnapshot().GetDurableSnapshot() - if storageStatus != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_UNSPECIFIED && st.GetStatus() != storageStatus { + if storageStatus != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_UNSPECIFIED && st.GetStatus() != storageStatus { return "" } return st.GetObject().GetSnapshotUri() @@ -154,7 +154,7 @@ func tagDurableSnapshotURI(tag *ateapipb.Tag, storageStatus ateapipb.SnapshotSto // // It reads the process-wide gate rather than preview.IsEnabledFor, so a // request's preview opt-out cannot move where an actor's snapshots live. -func resolveSnapshotLocation(snapshotLocation string, actorTemplate *ateapipb.ActorTemplate) (string, error) { +func resolveSnapshotLocation(snapshotLocation string, actorTemplate *ateapi.ActorTemplate) (string, error) { if preview.IsEnabled(preview.GatePerTemplateSnapshotLocation) { if location := actorTemplate.GetSnapshotConfig().GetStorageLocation(); location != "" { return location, nil diff --git a/cmd/ateapi/internal/controlapi/snapshot_helpers_test.go b/cmd/ateapi/internal/controlapi/snapshot_helpers_test.go index 2f466f6329..760cb85a3f 100644 --- a/cmd/ateapi/internal/controlapi/snapshot_helpers_test.go +++ b/cmd/ateapi/internal/controlapi/snapshot_helpers_test.go @@ -18,9 +18,9 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/preview" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/testing/protocmp" ) @@ -33,11 +33,11 @@ func TestFindSnapshotByGenerationAndSnapshotAtLatestGeneration(t *testing.T) { t.Errorf("findSnapshotByGeneration(nil, 1) = %v, want nil", got) } - s1 := newPausedSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-1", "node-1") - s2 := newDurableSnapshot(2, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-2", "gs://b/snap-2", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) - status := &ateapipb.ActorStatus{ + s1 := newPausedSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-1", "node-1") + s2 := newDurableSnapshot(2, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-2", "gs://b/snap-2", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + status := &ateapi.ActorStatus{ LastAssignedGeneration: 2, - Snapshots: []*ateapipb.Snapshot{s1, s2}, + Snapshots: []*ateapi.Snapshot{s1, s2}, } if got := findSnapshotByGeneration(status.GetSnapshots(), 1); got != s1 { @@ -52,34 +52,34 @@ func TestFindSnapshotByGenerationAndSnapshotAtLatestGeneration(t *testing.T) { } func TestFindLatestDurableAndLocalSnapshots(t *testing.T) { - if snap := findLatestDurableSnapshot(nil, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED); snap != nil { + if snap := findLatestDurableSnapshot(nil, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED); snap != nil { t.Errorf("findLatestDurableSnapshot(nil) = %v, want nil", snap) } if snap := findLatestLocalSnapshot(nil); snap != nil { t.Errorf("findLatestLocalSnapshot(nil) = %v, want nil", snap) } - s1 := newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) - s2 := newDurableSnapshot(2, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-2", "gs://b/snap-2", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) - s3 := newDurableSnapshot(3, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-3", "gs://b/snap-3", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) - s4 := newPausedSnapshot(t, 4, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-4", "node-1") + s1 := newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + s2 := newDurableSnapshot(2, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-2", "gs://b/snap-2", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + s3 := newDurableSnapshot(3, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-3", "gs://b/snap-3", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) + s4 := newPausedSnapshot(t, 4, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-4", "node-1") // Place s2 before s1 to verify generation comparison rather than slice order. - status := &ateapipb.ActorStatus{ - Snapshots: []*ateapipb.Snapshot{s2, s1, s3, s4}, + status := &ateapi.ActorStatus{ + Snapshots: []*ateapi.Snapshot{s2, s1, s3, s4}, } - gotSnap := findLatestDurableSnapshot(status, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + gotSnap := findLatestDurableSnapshot(status, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) if gotSnap != s2 || gotSnap.GetDurableSnapshot().GetObject().GetSnapshotUri() != "gs://b/snap-2" { t.Errorf("findLatestDurableSnapshot(COMPLETED) = %v, want gen 2 (gs://b/snap-2)", gotSnap) } // An async suspend snapshot's durable copy is PENDING until atelet uploads it. - gotSnap = findLatestDurableSnapshot(status, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) + gotSnap = findLatestDurableSnapshot(status, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) if gotSnap != s4 { t.Errorf("findLatestDurableSnapshot(PENDING) = %v, want gen 4", gotSnap) } - gotSnap = findLatestDurableSnapshot(&ateapipb.ActorStatus{Snapshots: []*ateapipb.Snapshot{s2, s1, s3}}, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) + gotSnap = findLatestDurableSnapshot(&ateapi.ActorStatus{Snapshots: []*ateapi.Snapshot{s2, s1, s3}}, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) if gotSnap != s3 || gotSnap.GetDurableSnapshot().GetObject().GetSnapshotUri() != "gs://b/snap-3" { t.Errorf("findLatestDurableSnapshot(PENDING) without the paused snapshot = %v, want gen 3 (gs://b/snap-3)", gotSnap) } @@ -96,17 +96,17 @@ func TestSnapshotPruningHelpers(t *testing.T) { pruneSnapshots(nil, nil) t.Run("clearLocalSnapshots clears locality without dropping snapshots", func(t *testing.T) { - localGen1 := newPausedSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-1", "node-1") - localGen2 := newPausedSnapshot(t, 2, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-2", "node-2") - status := &ateapipb.ActorStatus{ - Snapshots: []*ateapipb.Snapshot{localGen1, localGen2}, + localGen1 := newPausedSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-1", "node-1") + localGen2 := newPausedSnapshot(t, 2, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-2", "node-2") + status := &ateapi.ActorStatus{ + Snapshots: []*ateapi.Snapshot{localGen1, localGen2}, } clearLocalSnapshots(status) - want := []*ateapipb.Snapshot{ - newPausedSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-1", ""), - newPausedSnapshot(t, 2, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-2", ""), + want := []*ateapi.Snapshot{ + newPausedSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-1", ""), + newPausedSnapshot(t, 2, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-2", ""), } if diff := cmp.Diff(want, status.GetSnapshots(), protocmp.Transform()); diff != "" { t.Errorf("status.Snapshots mismatch (-want +got):\n%s", diff) @@ -114,22 +114,22 @@ func TestSnapshotPruningHelpers(t *testing.T) { }) t.Run("pause flow: pruneSnapshots keeps the latest COMPLETED durable and the new local snapshot", func(t *testing.T) { - completedGen1 := newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + completedGen1 := newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) completedGen1.Locality = "node-1" - localGen2 := newPausedSnapshot(t, 2, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-2", "node-2") - localGen3 := newPausedSnapshot(t, 3, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-3", "") + localGen2 := newPausedSnapshot(t, 2, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-2", "node-2") + localGen3 := newPausedSnapshot(t, 3, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-3", "") - status := &ateapipb.ActorStatus{ + status := &ateapi.ActorStatus{ LastAssignedGeneration: 3, - Snapshots: []*ateapipb.Snapshot{completedGen1, localGen2, localGen3}, + Snapshots: []*ateapi.Snapshot{completedGen1, localGen2, localGen3}, } localGen3.Locality = "node-3" pruneSnapshots(status, localGen3) - want := []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), - newPausedSnapshot(t, 3, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-3", "node-3"), + want := []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + newPausedSnapshot(t, 3, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-3", "node-3"), } if diff := cmp.Diff(want, status.GetSnapshots(), protocmp.Transform()); diff != "" { t.Errorf("status.Snapshots mismatch (-want +got):\n%s", diff) @@ -140,12 +140,12 @@ func TestSnapshotPruningHelpers(t *testing.T) { }) t.Run("pruneSnapshots drops a PENDING snapshot that still names a node", func(t *testing.T) { - pendingWithLocality := newDurableSnapshot(2, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-2", "gs://b/snap-2", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) + pendingWithLocality := newDurableSnapshot(2, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-2", "gs://b/snap-2", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) pendingWithLocality.Locality = "node-1" - local := newPausedSnapshot(t, 3, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-3", "node-1") - status := &ateapipb.ActorStatus{ - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + local := newPausedSnapshot(t, 3, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-3", "node-1") + status := &ateapi.ActorStatus{ + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), pendingWithLocality, local, }, @@ -153,9 +153,9 @@ func TestSnapshotPruningHelpers(t *testing.T) { pruneSnapshots(status, local) - want := []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), - newPausedSnapshot(t, 3, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-3", "node-1"), + want := []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + newPausedSnapshot(t, 3, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-3", "node-1"), } if diff := cmp.Diff(want, status.GetSnapshots(), protocmp.Transform()); diff != "" { t.Errorf("status.Snapshots mismatch (-want +got):\n%s", diff) @@ -166,20 +166,20 @@ func TestSnapshotPruningHelpers(t *testing.T) { }) t.Run("revert flow: pruneSnapshots drops all PENDING snapshots and retains latest COMPLETED", func(t *testing.T) { - completedWithLocality := newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + completedWithLocality := newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) completedWithLocality.Locality = "node-1" - status := &ateapipb.ActorStatus{ - Snapshots: []*ateapipb.Snapshot{ + status := &ateapi.ActorStatus{ + Snapshots: []*ateapi.Snapshot{ completedWithLocality, - newPausedSnapshot(t, 2, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-2", "node-2"), - newDurableSnapshot(3, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-3", "gs://b/snap-3", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + newPausedSnapshot(t, 2, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-2", "node-2"), + newDurableSnapshot(3, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-3", "gs://b/snap-3", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), }, } pruneSnapshots(status, nil) - want := []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + want := []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), } if diff := cmp.Diff(want, status.GetSnapshots(), protocmp.Transform()); diff != "" { t.Errorf("status.Snapshots mismatch (-want +got):\n%s", diff) @@ -187,19 +187,19 @@ func TestSnapshotPruningHelpers(t *testing.T) { }) t.Run("suspend flow: pruneSnapshots drops older COMPLETED and PENDING snapshots", func(t *testing.T) { - status := &ateapipb.ActorStatus{ - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), - newPausedSnapshot(t, 2, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-2", "node-1"), - newDurableSnapshot(3, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-3", "gs://b/snap-3", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + status := &ateapi.ActorStatus{ + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/snap-1", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + newPausedSnapshot(t, 2, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "local-2", "node-1"), + newDurableSnapshot(3, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-3", "gs://b/snap-3", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), }, } status.Snapshots[2].Locality = "node-1" pruneSnapshots(status, nil) - want := []*ateapipb.Snapshot{ - newDurableSnapshot(3, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-3", "gs://b/snap-3", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + want := []*ateapi.Snapshot{ + newDurableSnapshot(3, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-3", "gs://b/snap-3", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), } if diff := cmp.Diff(want, status.GetSnapshots(), protocmp.Transform()); diff != "" { t.Errorf("status.Snapshots mismatch (-want +got):\n%s", diff) @@ -211,29 +211,29 @@ func TestSnapshotPruningHelpers(t *testing.T) { // node-local, whether or not atelet has uploaded it. A latest snapshot with // only a durable copy, or a local one not captured yet, does not count. func TestLatestSnapshotIsLocal(t *testing.T) { - local := func(gen int32) *ateapipb.Snapshot { - return newPausedSnapshot(t, gen, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "local", "node-1") + local := func(gen int32) *ateapi.Snapshot { + return newPausedSnapshot(t, gen, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "local", "node-1") } - withCopy := func(st ateapipb.SnapshotStorageStatus) *ateapipb.Snapshot { + withCopy := func(st ateapi.SnapshotStorageStatus) *ateapi.Snapshot { snap := local(1) - snap.DurableSnapshot = &ateapipb.SnapshotStorage{Status: st, Object: &ateapipb.ObjectSnapshot{SnapshotUri: "gs://b/up"}} + snap.DurableSnapshot = &ateapi.SnapshotStorage{Status: st, Object: &ateapi.ObjectSnapshot{SnapshotUri: "gs://b/up"}} return snap } - durable := newDurableSnapshot(2, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "durable", "gs://b/durable", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) - notCaptured := newPausedSnapshot(t, 2, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "local", "") + durable := newDurableSnapshot(2, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "durable", "gs://b/durable", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + notCaptured := newPausedSnapshot(t, 2, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "local", "") tests := []struct { name string - status *ateapipb.ActorStatus + status *ateapi.ActorStatus want bool }{ {"nil status", nil, false}, - {"no snapshots", &ateapipb.ActorStatus{}, false}, - {"local only", &ateapipb.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapipb.Snapshot{local(1)}}, true}, - {"local and uploaded", &ateapipb.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapipb.Snapshot{withCopy(ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)}}, true}, - {"local with an upload pending", &ateapipb.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapipb.Snapshot{withCopy(ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING)}}, true}, - {"durable only", &ateapipb.ActorStatus{LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{durable}}, false}, - {"older local under a pause in progress", &ateapipb.ActorStatus{LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{local(1), notCaptured}}, false}, + {"no snapshots", &ateapi.ActorStatus{}, false}, + {"local only", &ateapi.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapi.Snapshot{local(1)}}, true}, + {"local and uploaded", &ateapi.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapi.Snapshot{withCopy(ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)}}, true}, + {"local with an upload pending", &ateapi.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapi.Snapshot{withCopy(ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING)}}, true}, + {"durable only", &ateapi.ActorStatus{LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{durable}}, false}, + {"older local under a pause in progress", &ateapi.ActorStatus{LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{local(1), notCaptured}}, false}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { @@ -245,22 +245,22 @@ func TestLatestSnapshotIsLocal(t *testing.T) { } func TestTagDurableSnapshotURI(t *testing.T) { - if got := tagDurableSnapshotURI(nil, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_UNSPECIFIED); got != "" { + if got := tagDurableSnapshotURI(nil, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_UNSPECIFIED); got != "" { t.Errorf("tagDurableSnapshotURI(nil) = %q, want empty", got) } - pendingTag := &ateapipb.Tag{ - Status: &ateapipb.TagStatus{ - Snapshot: newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/tag-1", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + pendingTag := &ateapi.Tag{ + Status: &ateapi.TagStatus{ + Snapshot: newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-1", "uuid-1", "gs://b/tag-1", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), }, } - if got := tagDurableSnapshotURI(pendingTag, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED); got != "" { + if got := tagDurableSnapshotURI(pendingTag, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED); got != "" { t.Errorf("tagDurableSnapshotURI(pendingTag, COMPLETED) = %q, want empty", got) } - if got := tagDurableSnapshotURI(pendingTag, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING); got != "gs://b/tag-1" { + if got := tagDurableSnapshotURI(pendingTag, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING); got != "gs://b/tag-1" { t.Errorf("tagDurableSnapshotURI(pendingTag, PENDING) = %q, want gs://b/tag-1", got) } - if got := tagDurableSnapshotURI(pendingTag, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_UNSPECIFIED); got != "gs://b/tag-1" { + if got := tagDurableSnapshotURI(pendingTag, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_UNSPECIFIED); got != "gs://b/tag-1" { t.Errorf("tagDurableSnapshotURI(pendingTag, UNSPECIFIED) = %q, want gs://b/tag-1", got) } } @@ -326,9 +326,9 @@ func TestResolveSnapshotLocation(t *testing.T) { gates = []string{string(preview.GatePerTemplateSnapshotLocation)} } preview.InitForTest(t, gates...) - tmpl := &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "tmpl"}, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: tt.templateLocation}, + tmpl := &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "tmpl"}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: tt.templateLocation}, } got, err := resolveSnapshotLocation(tt.bucketPrefix, tmpl) if tt.wantErr { diff --git a/cmd/ateapi/internal/controlapi/snapshot_report.go b/cmd/ateapi/internal/controlapi/snapshot_report.go index 4b5ef70f28..286b425ef7 100644 --- a/cmd/ateapi/internal/controlapi/snapshot_report.go +++ b/cmd/ateapi/internal/controlapi/snapshot_report.go @@ -21,17 +21,17 @@ import ( "google.golang.org/protobuf/proto" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // ApplyActorSnapshotState records the snapshot state that the atelet on node // reports for the Actor. The caller has authenticated that atelet. -func (s *RPCService) ApplyActorSnapshotState(ctx context.Context, actorRef resources.ActorRef, actorUID, node string, state *ateapipb.ActorSnapshotState) error { +func (s *RPCService) ApplyActorSnapshotState(ctx context.Context, actorRef resources.ActorRef, actorUID, node string, state *ateapi.ActorSnapshotState) error { setSpanActorRefAttributes(ctx, actorRef) return s.actorWorkflow.ApplyReportedSnapshotState(ctx, actorRef, actorUID, node, state) } @@ -40,7 +40,7 @@ func (s *RPCService) ApplyActorSnapshotState(ctx context.Context, actorRef resou // Actor. It holds the Actor's lease and applies reports only to a SUSPENDED or // RUNNING Actor, so a report never interleaves with a workflow. A report that // changes nothing writes nothing. -func (w *ActorWorkflow) ApplyReportedSnapshotState(ctx context.Context, actorRef resources.ActorRef, actorUID, node string, state *ateapipb.ActorSnapshotState) error { +func (w *ActorWorkflow) ApplyReportedSnapshotState(ctx context.Context, actorRef resources.ActorRef, actorUID, node string, state *ateapi.ActorSnapshotState) error { ctx = preview.ContextWithOptIn(ctx) // Check before taking the lease, so an atelet can't hold the lease of an // Actor that isn't on its node. Check again under the lease. @@ -60,24 +60,24 @@ func (w *ActorWorkflow) ApplyReportedSnapshotState(ctx context.Context, actorRef // A workflow owns a transitioning Actor's snapshots, even after its lease // lapses. A crashed Actor's snapshots wait for a revert. switch st := before.GetStatus().GetState(); st { - case ateapipb.ActorState_ACTOR_STATE_SUSPENDED, ateapipb.ActorState_ACTOR_STATE_RUNNING: - case ateapipb.ActorState_ACTOR_STATE_CRASHED: + case ateapi.ActorState_ACTOR_STATE_SUSPENDED, ateapi.ActorState_ACTOR_STATE_RUNNING: + case ateapi.ActorState_ACTOR_STATE_CRASHED: return apierror.FailedPrecondition("actor %s is %s; revert it first", actorRef, st) - case ateapipb.ActorState_ACTOR_STATE_SUSPENDING, ateapipb.ActorState_ACTOR_STATE_RESUMING, - ateapipb.ActorState_ACTOR_STATE_DELETING, ateapipb.ActorState_ACTOR_STATE_REVERTING: + case ateapi.ActorState_ACTOR_STATE_SUSPENDING, ateapi.ActorState_ACTOR_STATE_RESUMING, + ateapi.ActorState_ACTOR_STATE_DELETING, ateapi.ActorState_ACTOR_STATE_REVERTING: return apierror.Aborted("actor %s is %s; retry once that finishes", actorRef, st) default: return apierror.Internal("actor %s has unexpected state %s", actorRef, st) } - applied := proto.Clone(before).(*ateapipb.Actor) + applied := proto.Clone(before).(*ateapi.Actor) if err := applyActorSnapshotState(leaseCtx, applied.GetStatus(), node, state); err != nil { return err } if proto.Equal(applied.GetStatus(), before.GetStatus()) { return nil } - if _, err := w.store.UpdateActor(leaseCtx, actorRef, store.PreconditionFrom(before), func(toUpdate *ateapipb.Actor) error { + if _, err := w.store.UpdateActor(leaseCtx, actorRef, store.PreconditionFrom(before), func(toUpdate *ateapi.Actor) error { toUpdate.Status = applied.GetStatus() return nil }); err != nil { @@ -92,7 +92,7 @@ func (w *ActorWorkflow) ApplyReportedSnapshotState(ctx context.Context, actorRef // loadReportedActor returns the Actor if it is the incarnation actorUID names // and is on node. Otherwise it returns NotFound, so an atelet learns nothing // about Actors on other nodes. -func (w *ActorWorkflow) loadReportedActor(ctx context.Context, actorRef resources.ActorRef, actorUID, node string) (*ateapipb.Actor, error) { +func (w *ActorWorkflow) loadReportedActor(ctx context.Context, actorRef resources.ActorRef, actorUID, node string) (*ateapi.Actor, error) { actor, err := w.store.GetActor(ctx, actorRef) if err != nil { if errors.Is(err, store.ErrNotFound) { @@ -122,7 +122,7 @@ func (w *ActorWorkflow) loadReportedActor(ctx context.Context, actorRef resource // snapshot there. Unlike HostingNode, it includes a node that holds only // older snapshots of an Actor placed elsewhere, since that node's atelet // reports them. -func actorOnNode(actor *ateapipb.Actor, node string) bool { +func actorOnNode(actor *ateapi.Actor, node string) bool { if actor.GetStatus().GetAssignedNode() == node { return true } @@ -143,7 +143,7 @@ const ( // applyActorSnapshotState applies the two facts a report carries: an upload // finished, and the atelet on node detached the Actor. A report with neither // latest_local nor uploading is a detach. -func applyActorSnapshotState(ctx context.Context, status *ateapipb.ActorStatus, node string, state *ateapipb.ActorSnapshotState) error { +func applyActorSnapshotState(ctx context.Context, status *ateapi.ActorStatus, node string, state *ateapi.ActorSnapshotState) error { if err := applyLatestDurable(ctx, status, state.GetLatestDurable()); err != nil { return err } @@ -158,7 +158,7 @@ func applyActorSnapshotState(ctx context.Context, status *ateapipb.ActorStatus, // report. It records the fidelity atelet reports, which for both RPCs is the // one requested. Unlike a report, a state with no local snapshot is not a // detach. The workflow that made the call records where its snapshot lives. -func applyAteletResponseState(ctx context.Context, status *ateapipb.ActorStatus, state *ateletpb.ActorSnapshotState) error { +func applyAteletResponseState(ctx context.Context, status *ateapi.ActorStatus, state *ateletpb.ActorSnapshotState) error { return applyLatestDurable(ctx, status, snapshotReportFromAtelet(state.GetLatestDurable())) } @@ -171,11 +171,11 @@ func applyAteletResponseState(ctx context.Context, status *ateapipb.ActorStatus, // its generation is older than the latest COMPLETED one, or is no longer in // status.snapshots, for example because a revert removed it. A repeat of the // latest COMPLETED generation also changes nothing, and isn't logged. -func applyLatestDurable(ctx context.Context, status *ateapipb.ActorStatus, reported *ateapipb.SnapshotReport) error { +func applyLatestDurable(ctx context.Context, status *ateapi.ActorStatus, reported *ateapi.SnapshotReport) error { if reported == nil { return nil } - if latest := findLatestDurableSnapshot(status, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED); latest.GetGeneration() >= reported.GetGeneration() { + if latest := findLatestDurableSnapshot(status, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED); latest.GetGeneration() >= reported.GetGeneration() { if latest.GetGeneration() > reported.GetGeneration() { slog.InfoContext(ctx, msgDurableOlder, slog.Int("generation", int(reported.GetGeneration())), @@ -204,11 +204,11 @@ func applyLatestDurable(ctx context.Context, status *ateapipb.ActorStatus, repor if got := reported.GetObject().GetSnapshotUri(); got != want { return apierror.InvalidArgument("snapshot generation %d was uploaded to %q, want %q", reported.GetGeneration(), got, want) } - if reported.GetFidelity() == ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED { + if reported.GetFidelity() == ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED { return apierror.InvalidArgument("snapshot generation %d reports no fidelity", reported.GetGeneration()) } snap.Fidelity = reported.GetFidelity() - snap.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + snap.DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED return nil } @@ -218,10 +218,10 @@ func applyLatestDurable(ctx context.Context, status *ateapipb.ActorStatus, repor // SUSPENDED Actor is released from node once none of its snapshots are there. // It refuses if the latest deleted snapshot isn't durable, so the Actor can't // resume from an older one. -func applyDetach(status *ateapipb.ActorStatus, node string, upTo int32) error { - deleted := func(s *ateapipb.Snapshot) bool { return s.GetLocality() == node && s.GetGeneration() <= upTo } +func applyDetach(status *ateapi.ActorStatus, node string, upTo int32) error { + deleted := func(s *ateapi.Snapshot) bool { return s.GetLocality() == node && s.GetGeneration() <= upTo } if latest := latestSnapshot(status, deleted); latest != nil && - latest.GetDurableSnapshot().GetStatus() != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { + latest.GetDurableSnapshot().GetStatus() != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { return apierror.FailedPrecondition("snapshot generation %d on node %s is not durable", latest.GetGeneration(), node) } for _, snap := range status.GetSnapshots() { @@ -229,8 +229,8 @@ func applyDetach(status *ateapipb.ActorStatus, node string, upTo int32) error { snap.Locality = "" } } - onNode := latestSnapshot(status, func(s *ateapipb.Snapshot) bool { return s.GetLocality() == node }) - if status.GetState() == ateapipb.ActorState_ACTOR_STATE_SUSPENDED && status.GetAssignedNode() == node && onNode == nil { + onNode := latestSnapshot(status, func(s *ateapi.Snapshot) bool { return s.GetLocality() == node }) + if status.GetState() == ateapi.ActorState_ACTOR_STATE_SUSPENDED && status.GetAssignedNode() == node && onNode == nil { status.AssignedNode = "" } return nil diff --git a/cmd/ateapi/internal/controlapi/snapshot_report_test.go b/cmd/ateapi/internal/controlapi/snapshot_report_test.go index e73398cf6c..bdb1049ba8 100644 --- a/cmd/ateapi/internal/controlapi/snapshot_report_test.go +++ b/cmd/ateapi/internal/controlapi/snapshot_report_test.go @@ -24,11 +24,11 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/protobuf/testing/protocmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const ( @@ -52,127 +52,127 @@ func ownedURI(t *testing.T, actorUID string, gen int32) string { // withDurable returns a Snapshot held on locality ("" for none) with a durable // copy in the given storage status. -func withDurable(t *testing.T, gen int32, locality string, storage ateapipb.SnapshotStorageStatus) *ateapipb.Snapshot { +func withDurable(t *testing.T, gen int32, locality string, storage ateapi.SnapshotStorageStatus) *ateapi.Snapshot { t.Helper() - snap := &ateapipb.Snapshot{Uuid: snapName(gen), Generation: gen, Locality: locality, Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY} - snap.DurableSnapshot = &ateapipb.SnapshotStorage{ + snap := &ateapi.Snapshot{Uuid: snapName(gen), Generation: gen, Locality: locality, Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY} + snap.DurableSnapshot = &ateapi.SnapshotStorage{ Status: storage, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: ownedURI(t, reportActorUID, gen)}, + Object: &ateapi.ObjectSnapshot{SnapshotUri: ownedURI(t, reportActorUID, gen)}, } return snap } -func reported(t *testing.T, gen int32) *ateapipb.SnapshotReport { +func reported(t *testing.T, gen int32) *ateapi.SnapshotReport { t.Helper() return reportedAt(t, gen, ownedURI(t, reportActorUID, gen)) } -func reportedAt(t *testing.T, gen int32, uri string) *ateapipb.SnapshotReport { +func reportedAt(t *testing.T, gen int32, uri string) *ateapi.SnapshotReport { t.Helper() - return &ateapipb.SnapshotReport{ + return &ateapi.SnapshotReport{ Uuid: snapName(gen), Generation: gen, - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: uri}, + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + Object: &ateapi.ObjectSnapshot{SnapshotUri: uri}, } } func TestApplyActorSnapshotState(t *testing.T) { const ( - pending = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING - completed = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED - suspended = ateapipb.ActorState_ACTOR_STATE_SUSPENDED - running = ateapipb.ActorState_ACTOR_STATE_RUNNING + pending = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + completed = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + suspended = ateapi.ActorState_ACTOR_STATE_SUSPENDED + running = ateapi.ActorState_ACTOR_STATE_RUNNING ) tests := []struct { name string - status *ateapipb.ActorStatus - state *ateapipb.ActorSnapshotState - want *ateapipb.ActorStatus + status *ateapi.ActorStatus + state *ateapi.ActorSnapshotState + want *ateapi.ActorStatus wantCode codes.Code }{{ name: "upload marks the pending snapshot COMPLETED and keeps it local", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, pending), }}, - state: &ateapipb.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: reported(t, 2)}, - want: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + state: &ateapi.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: reported(t, 2)}, + want: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, completed), }}, }, { name: "upload records the fidelity the manifest reports", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, pending), }}, - state: &ateapipb.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: func() *ateapipb.SnapshotReport { + state: &ateapi.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: func() *ateapi.SnapshotReport { r := reported(t, 2) - r.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS + r.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS return r }()}, - want: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ - func() *ateapipb.Snapshot { + want: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ + func() *ateapi.Snapshot { snap := withDurable(t, 2, reportNode, completed) - snap.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS + snap.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS return snap }(), }}, }, { name: "an unset fidelity is refused", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, pending), }}, - state: &ateapipb.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: func() *ateapipb.SnapshotReport { + state: &ateapi.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: func() *ateapi.SnapshotReport { r := reported(t, 2) - r.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED + r.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED return r }()}, wantCode: codes.InvalidArgument, }, { name: "a snapshot already COMPLETED changes nothing", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, completed), }}, - state: &ateapipb.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: reported(t, 2)}, - want: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + state: &ateapi.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: reported(t, 2)}, + want: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, completed), }}, }, { name: "a generation below the latest COMPLETED one changes nothing", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 1, reportNode, pending), withDurable(t, 2, reportNode, completed), }}, - state: &ateapipb.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: func() *ateapipb.SnapshotReport { + state: &ateapi.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: func() *ateapi.SnapshotReport { r := reported(t, 1) - r.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS + r.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS return r }()}, - want: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + want: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 1, reportNode, pending), withDurable(t, 2, reportNode, completed), }}, }, { name: "a generation status no longer has changes nothing", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 3, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 3, Snapshots: []*ateapi.Snapshot{ withDurable(t, 3, reportNode, pending), }}, - state: &ateapipb.ActorSnapshotState{LatestLocal: reported(t, 3), LatestDurable: reported(t, 2)}, - want: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 3, Snapshots: []*ateapipb.Snapshot{ + state: &ateapi.ActorSnapshotState{LatestLocal: reported(t, 3), LatestDurable: reported(t, 2)}, + want: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 3, Snapshots: []*ateapi.Snapshot{ withDurable(t, 3, reportNode, pending), }}, }, { name: "a generation newer than any assigned is refused", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, pending), }}, - state: &ateapipb.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: reported(t, 5)}, + state: &ateapi.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: reported(t, 5)}, wantCode: codes.FailedPrecondition, }, { name: "a uuid other than the recorded one is refused", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, pending), }}, - state: &ateapipb.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: func() *ateapipb.SnapshotReport { + state: &ateapi.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: func() *ateapi.SnapshotReport { r := reported(t, 2) r.Uuid = "other" return r @@ -180,122 +180,122 @@ func TestApplyActorSnapshotState(t *testing.T) { wantCode: codes.FailedPrecondition, }, { name: "an older snapshot's upload is recorded and the latest stays pending", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 1, reportNode, pending), withDurable(t, 2, reportNode, pending), }}, - state: &ateapipb.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: reported(t, 1)}, - want: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + state: &ateapi.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: reported(t, 1)}, + want: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 1, reportNode, completed), withDurable(t, 2, reportNode, pending), }}, }, { name: "a snapshot that records no upload is refused", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ - {Uuid: snapName(2), Generation: 2, Locality: reportNode, Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}, + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ + {Uuid: snapName(2), Generation: 2, Locality: reportNode, Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}, }}, - state: &ateapipb.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: reported(t, 2)}, + state: &ateapi.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: reported(t, 2)}, wantCode: codes.FailedPrecondition, }, { name: "an upload URI other than the recorded one is refused", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, pending), }}, - state: &ateapipb.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: reportedAt(t, 2, ownedURI(t, reportActorUID, 9))}, + state: &ateapi.ActorSnapshotState{LatestLocal: reported(t, 2), LatestDurable: reportedAt(t, 2, ownedURI(t, reportActorUID, 9))}, wantCode: codes.InvalidArgument, }, { name: "latest_local and uploading are not checked", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, pending), }}, - state: &ateapipb.ActorSnapshotState{LatestLocal: reported(t, 7), Uploading: reported(t, 8)}, - want: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + state: &ateapi.ActorSnapshotState{LatestLocal: reported(t, 7), Uploading: reported(t, 8)}, + want: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, pending), }}, }, { name: "an upload in flight with no local snapshot is not a detach", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, pending), }}, - state: &ateapipb.ActorSnapshotState{Uploading: reported(t, 2)}, - want: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + state: &ateapi.ActorSnapshotState{Uploading: reported(t, 2)}, + want: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, pending), }}, }, { name: "detach releases a suspended actor from the node", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 1, "", completed), withDurable(t, 2, reportNode, completed), }}, - state: &ateapipb.ActorSnapshotState{LatestDurable: reported(t, 2)}, - want: &ateapipb.ActorStatus{State: suspended, Snapshots: []*ateapipb.Snapshot{ + state: &ateapi.ActorSnapshotState{LatestDurable: reported(t, 2)}, + want: &ateapi.ActorStatus{State: suspended, Snapshots: []*ateapi.Snapshot{ withDurable(t, 1, "", completed), withDurable(t, 2, "", completed), }}, }, { name: "a detach can complete the upload it reports", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, pending), }}, - state: &ateapipb.ActorSnapshotState{LatestDurable: reported(t, 2)}, - want: &ateapipb.ActorStatus{State: suspended, Snapshots: []*ateapipb.Snapshot{ + state: &ateapi.ActorSnapshotState{LatestDurable: reported(t, 2)}, + want: &ateapi.ActorStatus{State: suspended, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, "", completed), }}, }, { name: "a late detach leaves a newer snapshot on the node and keeps the actor placed", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, completed), withDurable(t, 3, reportNode, completed), }}, - state: &ateapipb.ActorSnapshotState{LatestDurable: reported(t, 2)}, - want: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + state: &ateapi.ActorSnapshotState{LatestDurable: reported(t, 2)}, + want: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, "", completed), withDurable(t, 3, reportNode, completed), }}, }, { name: "a late detach leaves a newer snapshot whose upload is pending on the node", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 1, "", completed), withDurable(t, 2, reportNode, pending), }}, - state: &ateapipb.ActorSnapshotState{LatestDurable: reported(t, 1)}, - want: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + state: &ateapi.ActorSnapshotState{LatestDurable: reported(t, 1)}, + want: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 1, "", completed), withDurable(t, 2, reportNode, pending), }}, }, { name: "a detach of a snapshot that isn't durable is refused", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 1, reportNode, pending), }}, - state: &ateapipb.ActorSnapshotState{LatestDurable: reported(t, 2)}, + state: &ateapi.ActorSnapshotState{LatestDurable: reported(t, 2)}, wantCode: codes.FailedPrecondition, }, { name: "a detach from a node that holds no snapshot only releases the actor", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, "", completed), }}, - state: &ateapipb.ActorSnapshotState{LatestDurable: reported(t, 2)}, - want: &ateapipb.ActorStatus{State: suspended, Snapshots: []*ateapipb.Snapshot{ + state: &ateapi.ActorSnapshotState{LatestDurable: reported(t, 2)}, + want: &ateapi.ActorStatus{State: suspended, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, "", completed), }}, }, { name: "a running actor's detach keeps it placed on the node", - status: &ateapipb.ActorStatus{State: running, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: running, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, completed), }}, - state: &ateapipb.ActorSnapshotState{LatestDurable: reported(t, 2)}, - want: &ateapipb.ActorStatus{State: running, AssignedNode: reportNode, Snapshots: []*ateapipb.Snapshot{ + state: &ateapi.ActorSnapshotState{LatestDurable: reported(t, 2)}, + want: &ateapi.ActorStatus{State: running, AssignedNode: reportNode, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, "", completed), }}, }, { name: "a detach from one node leaves another node alone", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportOther, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportOther, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, completed), withDurable(t, 3, reportOther, pending), }}, - state: &ateapipb.ActorSnapshotState{LatestDurable: reported(t, 2)}, - want: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportOther, Snapshots: []*ateapipb.Snapshot{ + state: &ateapi.ActorSnapshotState{LatestDurable: reported(t, 2)}, + want: &ateapi.ActorStatus{State: suspended, AssignedNode: reportOther, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, "", completed), withDurable(t, 3, reportOther, pending), }}, @@ -325,18 +325,18 @@ func TestApplyActorSnapshotState(t *testing.T) { // logged. func TestApplyLatestDurableLogsStaleReports(t *testing.T) { const ( - pending = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING - completed = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + pending = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + completed = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED ) tests := []struct { name string - status *ateapipb.ActorStatus + status *ateapi.ActorStatus gen int32 wantMsg string wantAttrs map[string]string }{{ name: "below the latest COMPLETED generation", - status: &ateapipb.ActorStatus{LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 1, reportNode, pending), withDurable(t, 2, reportNode, completed), }}, @@ -345,7 +345,7 @@ func TestApplyLatestDurableLogsStaleReports(t *testing.T) { wantAttrs: map[string]string{"generation": "1", "uuid": snapName(1), "latest_completed_generation": "2"}, }, { name: "a generation status no longer has", - status: &ateapipb.ActorStatus{LastAssignedGeneration: 3, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{LastAssignedGeneration: 3, Snapshots: []*ateapi.Snapshot{ withDurable(t, 3, reportNode, pending), }}, gen: 2, @@ -353,13 +353,13 @@ func TestApplyLatestDurableLogsStaleReports(t *testing.T) { wantAttrs: map[string]string{"generation": "2", "uuid": snapName(2)}, }, { name: "the latest COMPLETED generation itself", - status: &ateapipb.ActorStatus{LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, completed), }}, gen: 2, }, { name: "applied", - status: &ateapipb.ActorStatus{LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, pending), }}, gen: 2, @@ -405,31 +405,31 @@ func TestApplyReportedSnapshotState(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) w := newMarkOnlyWorkflow(persistence) - tmpl, err := persistence.CreateActorTemplate(ctx, &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: reportAtespace, Name: "tmpl"}, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation}, + tmpl, err := persistence.CreateActorTemplate(ctx, &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: reportAtespace, Name: "tmpl"}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}, }) if err != nil { t.Fatalf("CreateActorTemplate() failed: %v", err) } actorRef := resources.ActorRef{Atespace: reportAtespace, Name: "actor-1"} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: reportAtespace, Name: "tmpl"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: reportAtespace, Name: "tmpl"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) uid := actor.GetMetadata().GetUid() pending := mustActorSnapshotURI(t, tmpl, actor, "snap-2") - actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.AssignedNode = reportNode s.LastAssignedGeneration = 2 - snap := newDurableSnapshot(2, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", pending.Name(), pending.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) + snap := newDurableSnapshot(2, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", pending.Name(), pending.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) snap.Locality = reportNode - s.Snapshots = []*ateapipb.Snapshot{snap} + s.Snapshots = []*ateapi.Snapshot{snap} }) uploaded := reportedAt(t, 2, pending.String()) - state := &ateapipb.ActorSnapshotState{LatestLocal: uploaded, LatestDurable: uploaded} + state := &ateapi.ActorSnapshotState{LatestLocal: uploaded, LatestDurable: uploaded} assertUnwritten := func(t *testing.T) { t.Helper() @@ -470,20 +470,20 @@ func TestApplyReportedSnapshotState(t *testing.T) { } // A transitioning actor gets Aborted, and a crashed one FailedPrecondition. for _, tc := range []struct { - state ateapipb.ActorState + state ateapi.ActorState want codes.Code }{ - {ateapipb.ActorState_ACTOR_STATE_SUSPENDING, codes.Aborted}, - {ateapipb.ActorState_ACTOR_STATE_RESUMING, codes.Aborted}, - {ateapipb.ActorState_ACTOR_STATE_DELETING, codes.Aborted}, - {ateapipb.ActorState_ACTOR_STATE_REVERTING, codes.Aborted}, - {ateapipb.ActorState_ACTOR_STATE_CRASHED, codes.FailedPrecondition}, + {ateapi.ActorState_ACTOR_STATE_SUSPENDING, codes.Aborted}, + {ateapi.ActorState_ACTOR_STATE_RESUMING, codes.Aborted}, + {ateapi.ActorState_ACTOR_STATE_DELETING, codes.Aborted}, + {ateapi.ActorState_ACTOR_STATE_REVERTING, codes.Aborted}, + {ateapi.ActorState_ACTOR_STATE_CRASHED, codes.FailedPrecondition}, } { t.Run("refused for a "+tc.state.String()+" actor", func(t *testing.T) { - actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { s.State = tc.state }) + actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.State = tc.state }) defer func() { - actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { - s.State = ateapipb.ActorState_ACTOR_STATE_SUSPENDED + actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { + s.State = ateapi.ActorState_ACTOR_STATE_SUSPENDED }) }() if err := w.ApplyReportedSnapshotState(ctx, actorRef, uid, reportNode, state); apierror.Code(err) != tc.want { @@ -493,7 +493,7 @@ func TestApplyReportedSnapshotState(t *testing.T) { }) } t.Run("refused for an upload to the wrong URI", func(t *testing.T) { - wrong := &ateapipb.ActorSnapshotState{LatestLocal: uploaded, LatestDurable: reportedAt(t, 2, ownedURI(t, uid, 9))} + wrong := &ateapi.ActorSnapshotState{LatestLocal: uploaded, LatestDurable: reportedAt(t, 2, ownedURI(t, uid, 9))} if err := w.ApplyReportedSnapshotState(ctx, actorRef, uid, reportNode, wrong); apierror.Code(err) != codes.InvalidArgument { t.Fatalf("ApplyReportedSnapshotState() = %v, want InvalidArgument", err) } @@ -507,7 +507,7 @@ func TestApplyReportedSnapshotState(t *testing.T) { if err != nil { t.Fatal(err) } - if st := got.GetStatus().GetSnapshots()[0].GetDurableSnapshot().GetStatus(); st != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { + if st := got.GetStatus().GetSnapshots()[0].GetDurableSnapshot().GetStatus(); st != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { t.Errorf("durable snapshot status = %v, want COMPLETED", st) } @@ -520,16 +520,16 @@ func TestApplyReportedSnapshotState(t *testing.T) { } func TestActorOnNode(t *testing.T) { - actor := func(assigned string, localities ...string) *ateapipb.Actor { - status := &ateapipb.ActorStatus{AssignedNode: assigned} + actor := func(assigned string, localities ...string) *ateapi.Actor { + status := &ateapi.ActorStatus{AssignedNode: assigned} for i, l := range localities { - status.Snapshots = append(status.Snapshots, withDurable(t, int32(i+1), l, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING)) + status.Snapshots = append(status.Snapshots, withDurable(t, int32(i+1), l, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING)) } - return &ateapipb.Actor{Status: status} + return &ateapi.Actor{Status: status} } for _, tc := range []struct { name string - actor *ateapipb.Actor + actor *ateapi.Actor want bool }{ {"placed on the node", actor(reportNode), true}, @@ -557,17 +557,17 @@ func ateletReported(t *testing.T, gen int32) *ateletpb.SnapshotReport { func TestApplyAteletResponseState(t *testing.T) { const ( - pending = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING - completed = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED - suspended = ateapipb.ActorState_ACTOR_STATE_SUSPENDED - suspending = ateapipb.ActorState_ACTOR_STATE_SUSPENDING + pending = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + completed = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + suspended = ateapi.ActorState_ACTOR_STATE_SUSPENDED + suspending = ateapi.ActorState_ACTOR_STATE_SUSPENDING otherActorUID = "1a7e4c83-6d20-4f95-b3c8-9e0a2f6d4b17" ) // previousPause is a suspending actor's status, holding the snapshot of the // async suspend before, whose upload is pending. - previousPause := func() *ateapipb.ActorStatus { - return &ateapipb.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + previousPause := func() *ateapi.ActorStatus { + return &ateapi.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 1, reportNode, pending), withDurable(t, 2, "", pending), }} @@ -578,22 +578,22 @@ func TestApplyAteletResponseState(t *testing.T) { } tests := []struct { name string - status *ateapipb.ActorStatus + status *ateapi.ActorStatus state *ateletpb.ActorSnapshotState - want *ateapipb.ActorStatus + want *ateapi.ActorStatus wantCode codes.Code }{{ name: "an immediate checkpoint marks its snapshot COMPLETED", - status: &ateapipb.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, "", pending), }}, state: &ateletpb.ActorSnapshotState{LatestDurable: ateletReported(t, 2)}, - want: &ateapipb.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + want: &ateapi.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, "", completed), }}, }, { name: "an immediate checkpoint records the fidelity it reports", - status: &ateapipb.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, "", pending), }}, state: &ateletpb.ActorSnapshotState{LatestDurable: func() *ateletpb.SnapshotReport { @@ -601,27 +601,27 @@ func TestApplyAteletResponseState(t *testing.T) { r.Snapshot.Fidelity = ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS return r }()}, - want: &ateapipb.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ - func() *ateapipb.Snapshot { + want: &ateapi.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ + func() *ateapi.Snapshot { snap := withDurable(t, 2, "", completed) - snap.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS + snap.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS return snap }(), }}, }, { name: "a deferred checkpoint changes nothing", - status: &ateapipb.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, "", pending), }}, state: &ateletpb.ActorSnapshotState{LatestLocal: ateletReported(t, 2)}, - want: &ateapipb.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + want: &ateapi.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, "", pending), }}, }, { name: "a deferred checkpoint records the upload of the previous pause's snapshot", status: previousPause(), state: &ateletpb.ActorSnapshotState{LatestLocal: ateletReported(t, 2), LatestDurable: ateletReported(t, 1)}, - want: &ateapipb.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + want: &ateapi.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 1, reportNode, completed), withDurable(t, 2, "", pending), }}, @@ -645,16 +645,16 @@ func TestApplyAteletResponseState(t *testing.T) { wantCode: codes.InvalidArgument, }, { name: "no local snapshot is not a detach", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, completed), }}, state: &ateletpb.ActorSnapshotState{LatestDurable: ateletReported(t, 2)}, - want: &ateapipb.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + want: &ateapi.ActorStatus{State: suspended, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, reportNode, completed), }}, }, { name: "an upload URI other than the recorded one is refused", - status: &ateapipb.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, "", pending), }}, state: &ateletpb.ActorSnapshotState{LatestDurable: func() *ateletpb.SnapshotReport { @@ -665,10 +665,10 @@ func TestApplyAteletResponseState(t *testing.T) { wantCode: codes.InvalidArgument, }, { name: "an unset state changes nothing", - status: &ateapipb.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + status: &ateapi.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, "", pending), }}, - want: &ateapipb.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapipb.Snapshot{ + want: &ateapi.ActorStatus{State: suspending, AssignedNode: reportNode, LastAssignedGeneration: 2, Snapshots: []*ateapi.Snapshot{ withDurable(t, 2, "", pending), }}, }} diff --git a/cmd/ateapi/internal/controlapi/span_identity.go b/cmd/ateapi/internal/controlapi/span_identity.go index 417be0f2be..e1f7d03265 100644 --- a/cmd/ateapi/internal/controlapi/span_identity.go +++ b/cmd/ateapi/internal/controlapi/span_identity.go @@ -19,14 +19,14 @@ import ( "go.opentelemetry.io/otel/trace" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // setSpanActorAttributes annotates the RPC's server span (from ctx) with the // actor's full identity. A no-op when ctx carries no recording span. -func setSpanActorAttributes(ctx context.Context, a *ateapipb.Actor) { +func setSpanActorAttributes(ctx context.Context, a *ateapi.Actor) { trace.SpanFromContext(ctx).SetAttributes(ateattr.ActorAttributes(a)...) } diff --git a/cmd/ateapi/internal/controlapi/span_identity_test.go b/cmd/ateapi/internal/controlapi/span_identity_test.go index 9bcf83d420..c664c6f5b8 100644 --- a/cmd/ateapi/internal/controlapi/span_identity_test.go +++ b/cmd/ateapi/internal/controlapi/span_identity_test.go @@ -22,9 +22,9 @@ import ( sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/sdk/trace/tracetest" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // recordRootSpanAttrs runs fn under a fresh recording root span from a local @@ -66,9 +66,9 @@ func assertSpanStr(t *testing.T, attrs map[attribute.Key]attribute.Value, key at func TestSetSpanActorAttributes(t *testing.T) { t.Parallel() - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "a1", Uid: "uid-a1", Version: 3}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "a1", Uid: "uid-a1", Version: 3}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, } attrs := recordRootSpanAttrs(t, func(ctx context.Context) { @@ -105,6 +105,6 @@ func TestSetSpanActorRefAttributes(t *testing.T) { // A context with no recording span must be a safe no-op, so call sites need no guard. func TestSetSpanActorAttributes_NoRecordingSpanIsNoop(t *testing.T) { t.Parallel() - setSpanActorAttributes(context.Background(), &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Name: "a1"}}) + setSpanActorAttributes(context.Background(), &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Name: "a1"}}) setSpanActorRefAttributes(context.Background(), resources.ActorRef{Atespace: "team-a", Name: "a1"}) } diff --git a/cmd/ateapi/internal/controlapi/tag.go b/cmd/ateapi/internal/controlapi/tag.go index 28d09dffe7..ec9362c707 100644 --- a/cmd/ateapi/internal/controlapi/tag.go +++ b/cmd/ateapi/internal/controlapi/tag.go @@ -19,12 +19,12 @@ import ( "errors" "fmt" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/defaults" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" "k8s.io/apimachinery/pkg/util/validation/field" ) @@ -33,7 +33,7 @@ import ( // tag its own copy of that snapshot so the Actor being suspended // again or deleted cannot collect it. The work is a workflow because it spans // two transactions around an object copy; see TagActorSnapshot. -func (s *RPCService) CreateTag(ctx context.Context, req *ateapipb.CreateTagRequest) (*ateapipb.Tag, error) { +func (s *RPCService) CreateTag(ctx context.Context, req *ateapi.CreateTagRequest) (*ateapi.Tag, error) { // First scrub any fields that users are not allowed to set, then fill the // defaults so validation sees the final resource state. inTag := req.Tag @@ -59,12 +59,12 @@ func (s *RPCService) CreateTag(ctx context.Context, req *ateapipb.CreateTagReque return tag, nil } -func (s *ServiceImpl) CreateTag(ctx context.Context, tag *ateapipb.Tag) (*ateapipb.Tag, error) { +func (s *ServiceImpl) CreateTag(ctx context.Context, tag *ateapi.Tag) (*ateapi.Tag, error) { // TODO: implement this return s.store.CreateTag(ctx, tag) } -func (s *RPCService) GetTag(ctx context.Context, req *ateapipb.GetTagRequest) (*ateapipb.Tag, error) { +func (s *RPCService) GetTag(ctx context.Context, req *ateapi.GetTagRequest) (*ateapi.Tag, error) { if errs := apivalidation.ValidateGetTagRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -79,12 +79,12 @@ func (s *RPCService) GetTag(ctx context.Context, req *ateapipb.GetTagRequest) (* return tag, nil } -func (s *ServiceImpl) GetTag(ctx context.Context, tagRef resources.TagRef) (*ateapipb.Tag, error) { +func (s *ServiceImpl) GetTag(ctx context.Context, tagRef resources.TagRef) (*ateapi.Tag, error) { // TODO: implement this return s.store.GetTag(ctx, tagRef) } -func (s *RPCService) ListTags(ctx context.Context, req *ateapipb.ListTagsRequest) (*ateapipb.ListTagsResponse, error) { +func (s *RPCService) ListTags(ctx context.Context, req *ateapi.ListTagsRequest) (*ateapi.ListTagsResponse, error) { if errs := apivalidation.ValidateListTagsRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -92,10 +92,10 @@ func (s *RPCService) ListTags(ctx context.Context, req *ateapipb.ListTagsRequest if err != nil { return nil, mapListError(fmt.Errorf("while listing tags: %w", err)) } - return &ateapipb.ListTagsResponse{Tags: page.Items, NextPageToken: page.NextPageToken}, nil + return &ateapi.ListTagsResponse{Tags: page.Items, NextPageToken: page.NextPageToken}, nil } -func (s *ServiceImpl) ListTags(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapipb.Tag], error) { +func (s *ServiceImpl) ListTags(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapi.Tag], error) { // TODO: implement this return s.store.ListTags(ctx, atespace, opts) } @@ -105,7 +105,7 @@ func (s *ServiceImpl) ListTags(ctx context.Context, atespace string, opts store. // failure and answer FAILED_PRECONDITION. var errTagPending = errors.New("tag is still being created") -func (s *RPCService) UpdateTag(ctx context.Context, req *ateapipb.UpdateTagRequest) (*ateapipb.Tag, error) { +func (s *RPCService) UpdateTag(ctx context.Context, req *ateapi.UpdateTagRequest) (*ateapi.Tag, error) { // First scrub any fields that users are not allowed to set. inTag := req.Tag if inTag != nil { // otherwise validation will flag it @@ -119,11 +119,11 @@ func (s *RPCService) UpdateTag(ctx context.Context, req *ateapipb.UpdateTagReque in := req.GetTag() tagRef := resources.TagRefFromTag(in) - storedTag, err := s.impl.UpdateTag(ctx, tagRef, store.PreconditionFrom(in), func(toUpdate *ateapipb.Tag) error { + storedTag, err := s.impl.UpdateTag(ctx, tagRef, store.PreconditionFrom(in), func(toUpdate *ateapi.Tag) error { // A tag whose create never finished names a partial copy. Publishing it // — or changing its scope at all — would hand out content that is still // being written, or may never be. - if tagDurableSnapshotURI(toUpdate, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) == "" { + if tagDurableSnapshotURI(toUpdate, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) == "" { return errTagPending } // Metadata and status are server-owned fields. @@ -166,8 +166,8 @@ func (s *RPCService) UpdateTag(ctx context.Context, req *ateapipb.UpdateTagReque return storedTag, nil } -func (s *ServiceImpl) UpdateTag(ctx context.Context, tagRef resources.TagRef, precondition store.Precondition, mutate func(toUpdate *ateapipb.Tag) error) (*ateapipb.Tag, error) { - return s.store.UpdateTag(ctx, tagRef, precondition, func(toUpdate *ateapipb.Tag) error { +func (s *ServiceImpl) UpdateTag(ctx context.Context, tagRef resources.TagRef, precondition store.Precondition, mutate func(toUpdate *ateapi.Tag) error) (*ateapi.Tag, error) { + return s.store.UpdateTag(ctx, tagRef, precondition, func(toUpdate *ateapi.Tag) error { // Apply the mutation function to the stored value. oldVal := proto.CloneOf(toUpdate) if err := mutate(toUpdate); err != nil { @@ -183,18 +183,18 @@ func (s *ServiceImpl) UpdateTag(ctx context.Context, tagRef resources.TagRef, pr } // DeleteTag removes the tag and collects the external snapshot it owns. -func (s *RPCService) DeleteTag(ctx context.Context, req *ateapipb.DeleteTagRequest) (*ateapipb.Tag, error) { +func (s *RPCService) DeleteTag(ctx context.Context, req *ateapi.DeleteTagRequest) (*ateapi.Tag, error) { if errs := apivalidation.ValidateDeleteTagRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } return s.actorWorkflow.DeleteTag(ctx, resources.TagRefFromObjectRef(req.GetTag()), toDeletePreconditions(req.GetOptions())) } -func (s *ServiceImpl) MarkTagForDeletion(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions, mutate func(*ateapipb.Tag) error) (*ateapipb.Tag, error) { +func (s *ServiceImpl) MarkTagForDeletion(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions, mutate func(*ateapi.Tag) error) (*ateapi.Tag, error) { return s.store.MarkTagForDeletion(ctx, tagRef, precondition, mutate) } -func (s *ServiceImpl) DeleteTag(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions) (*ateapipb.Tag, error) { +func (s *ServiceImpl) DeleteTag(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions) (*ateapi.Tag, error) { // TODO: implement this return s.store.DeleteTag(ctx, tagRef, precondition) } diff --git a/cmd/ateapi/internal/controlapi/tag_test.go b/cmd/ateapi/internal/controlapi/tag_test.go index 705842b836..a79c3cc000 100644 --- a/cmd/ateapi/internal/controlapi/tag_test.go +++ b/cmd/ateapi/internal/controlapi/tag_test.go @@ -22,11 +22,11 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/protobuf/testing/protocmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // TestListTags checks the atespace scoping and the paging of the @@ -49,7 +49,7 @@ func TestListTags(t *testing.T) { // list collects every page, so the assertions below cover the page token // round-trip as well as the contents. - list := func(req *ateapipb.ListTagsRequest) []string { + list := func(req *ateapi.ListTagsRequest) []string { t.Helper() var got []string for { @@ -63,33 +63,33 @@ func TestListTags(t *testing.T) { if resp.GetNextPageToken() == "" { return got } - req.Options = &ateapipb.ListOptions{PageSize: req.GetOptions().GetPageSize(), PageToken: resp.GetNextPageToken()} + req.Options = &ateapi.ListOptions{PageSize: req.GetOptions().GetPageSize(), PageToken: resp.GetNextPageToken()} } } tests := []struct { name string - req *ateapipb.ListTagsRequest + req *ateapi.ListTagsRequest want []string }{ { name: "atespace scoped", - req: &ateapipb.ListTagsRequest{Atespace: testAtespace}, + req: &ateapi.ListTagsRequest{Atespace: testAtespace}, want: []string{testAtespace + "/v1", testAtespace + "/v2"}, }, { name: "empty atespace lists all atespaces", - req: &ateapipb.ListTagsRequest{}, + req: &ateapi.ListTagsRequest{}, want: []string{otherAtespace + "/v1", testAtespace + "/v1", testAtespace + "/v2"}, }, { name: "one tag per page", - req: &ateapipb.ListTagsRequest{Options: &ateapipb.ListOptions{PageSize: 1}}, + req: &ateapi.ListTagsRequest{Options: &ateapi.ListOptions{PageSize: 1}}, want: []string{otherAtespace + "/v1", testAtespace + "/v1", testAtespace + "/v2"}, }, { name: "atespace with no tags", - req: &ateapipb.ListTagsRequest{Atespace: "empty-atespace"}, + req: &ateapi.ListTagsRequest{Atespace: "empty-atespace"}, want: nil, }, } @@ -101,7 +101,7 @@ func TestListTags(t *testing.T) { }) } - _, err := svc.ListTags(ctx, &ateapipb.ListTagsRequest{Options: &ateapipb.ListOptions{PageToken: "not-a-token"}}) + _, err := svc.ListTags(ctx, &ateapi.ListTagsRequest{Options: &ateapi.ListOptions{PageToken: "not-a-token"}}) if code := apierror.Code(err); code != codes.InvalidArgument { t.Errorf("ListTags(bad page_token) error = %v (code %v), want code InvalidArgument", err, code) } @@ -110,52 +110,52 @@ func TestListTags(t *testing.T) { func TestUpdateTag(t *testing.T) { tests := []struct { name string - stored *ateapipb.Tag - req *ateapipb.Tag - want *ateapipb.Tag + stored *ateapi.Tag + req *ateapi.Tag + want *ateapi.Tag wantCode codes.Code }{ { name: "publishes an atespace-scoped tag", - stored: &ateapipb.Tag{Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE}, - req: &ateapipb.Tag{Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED}, - want: &ateapipb.Tag{Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED}, + stored: &ateapi.Tag{Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE}, + req: &ateapi.Tag{Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED}, + want: &ateapi.Tag{Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED}, }, { name: "unpublishes a published tag", - stored: &ateapipb.Tag{Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED}, - req: &ateapipb.Tag{Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE}, - want: &ateapipb.Tag{Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE}, + stored: &ateapi.Tag{Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED}, + req: &ateapi.Tag{Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE}, + want: &ateapi.Tag{Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE}, }, { // scope is the only field a client owns: a request rewriting // server-owned fields is applied as a scope change alone. name: "server-owned fields in the request are ignored", - stored: &ateapipb.Tag{Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE}, - req: &ateapipb.Tag{ - Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED, - Status: &ateapipb.TagStatus{ - Snapshot: newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, "", "elsewhere", "gs://attacker/elsewhere", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + stored: &ateapi.Tag{Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE}, + req: &ateapi.Tag{ + Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED, + Status: &ateapi.TagStatus{ + Snapshot: newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, "", "elsewhere", "gs://attacker/elsewhere", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), ActorTemplateUid: "other-template-uid", }, }, - want: &ateapipb.Tag{Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED}, + want: &ateapi.Tag{Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED}, }, { // A tag never moves between snapshots, so it never moves between // sources either. name: "repointing source_actor is rejected", - stored: &ateapipb.Tag{Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE}, - req: &ateapipb.Tag{ - Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED, - SourceActor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "someone-elses-actor"}, + stored: &ateapi.Tag{Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE}, + req: &ateapi.Tag{ + Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED, + SourceActor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "someone-elses-actor"}, }, wantCode: codes.InvalidArgument, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tt.stored.Metadata = &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "tag1"} + tt.stored.Metadata = &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "tag1"} svc, stored := rpcServiceWithTag(t, tt.stored) tt.req.Metadata = stored.GetMetadata() @@ -165,7 +165,7 @@ func TestUpdateTag(t *testing.T) { tt.req.SourceActor = stored.GetSourceActor() } - updated, err := svc.UpdateTag(context.Background(), &ateapipb.UpdateTagRequest{Tag: tt.req}) + updated, err := svc.UpdateTag(context.Background(), &ateapi.UpdateTagRequest{Tag: tt.req}) if tt.wantCode != codes.OK { if code := apierror.Code(err); code != tt.wantCode { @@ -177,7 +177,7 @@ func TestUpdateTag(t *testing.T) { t.Fatalf("UpdateTag failed: %v", err) } - tt.want.Metadata = &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "tag1", Version: 2} + tt.want.Metadata = &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "tag1", Version: 2} tt.want.Status, tt.want.SourceActor = stored.GetStatus(), stored.GetSourceActor() if diff := cmp.Diff(tt.want, updated, protocmp.Transform(), ignoreUID, ignoreTimestamps); diff != "" { t.Errorf("UpdateTag response mismatch (-want +got):\n%s", diff) @@ -190,14 +190,14 @@ func TestUpdateTag(t *testing.T) { // uid nor a version is rejected. The schema does not require them — the store // does, because a caller that read nothing has nothing to lose a race with. func TestUpdateTag_BlindWrite(t *testing.T) { - svc, stored := rpcServiceWithTag(t, &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "tag1"}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, + svc, stored := rpcServiceWithTag(t, &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "tag1"}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, }) stored.Metadata.Uid, stored.Metadata.Version = "", 0 - stored.Scope = ateapipb.TagScope_TAG_SCOPE_PUBLISHED - _, err := svc.UpdateTag(context.Background(), &ateapipb.UpdateTagRequest{Tag: stored}) + stored.Scope = ateapi.TagScope_TAG_SCOPE_PUBLISHED + _, err := svc.UpdateTag(context.Background(), &ateapi.UpdateTagRequest{Tag: stored}) if code := apierror.Code(err); code != codes.InvalidArgument { t.Errorf("UpdateTag error = %v (code %v), want code InvalidArgument", err, code) } @@ -207,15 +207,15 @@ func TestUpdateTag_BlindWrite(t *testing.T) { // leaving scope unset is rejected. func TestUpdateTag_UnsetScopeDoesNotUnpublish(t *testing.T) { ctx := context.Background() - svc, stored := rpcServiceWithTag(t, &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "tag1"}, - Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED, + svc, stored := rpcServiceWithTag(t, &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "tag1"}, + Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED, }) // The guards are the ones the client read, so the rejection can only come // from the unset scope. - stored.Scope = ateapipb.TagScope_TAG_SCOPE_UNSPECIFIED - _, err := svc.UpdateTag(ctx, &ateapipb.UpdateTagRequest{ + stored.Scope = ateapi.TagScope_TAG_SCOPE_UNSPECIFIED + _, err := svc.UpdateTag(ctx, &ateapi.UpdateTagRequest{ Tag: stored, }) if code := apierror.Code(err); code != codes.InvalidArgument { @@ -226,7 +226,7 @@ func TestUpdateTag_UnsetScopeDoesNotUnpublish(t *testing.T) { if err != nil { t.Fatalf("GetTag: %v", err) } - if got, want := current.GetScope(), ateapipb.TagScope_TAG_SCOPE_PUBLISHED; got != want { + if got, want := current.GetScope(), ateapi.TagScope_TAG_SCOPE_PUBLISHED; got != want { t.Errorf("stored scope = %v, want %v: the rejected update must not have unpublished the tag", got, want) } if got, want := current.GetMetadata().GetVersion(), stored.GetMetadata().GetVersion(); got != want { @@ -235,12 +235,12 @@ func TestUpdateTag_UnsetScopeDoesNotUnpublish(t *testing.T) { } // newTestSuspendedActor creates a suspended actor holding an external snapshot. -func newTestSuspendedActor(t *testing.T, ctx context.Context, st store.Interface, atespace, name string) *ateapipb.Actor { +func newTestSuspendedActor(t *testing.T, ctx context.Context, st store.Interface, atespace, name string) *ateapi.Actor { t.Helper() - actor := storetest.MustCreateActor(t, ctx, st, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "default", Name: "template-1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := storetest.MustCreateActor(t, ctx, st, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "default", Name: "template-1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) // The snapshot sits under the actor's own prefix, which is keyed on the UID // the store assigns, so it can only be recorded once the row exists. @@ -248,10 +248,10 @@ func newTestSuspendedActor(t *testing.T, ctx context.Context, st store.Interface if err != nil { t.Fatalf("NewActorSnapshotURI: %v", err) } - return mustUpdateActorStatus(t, ctx, st, actor, func(status *ateapipb.ActorStatus) { + return mustUpdateActorStatus(t, ctx, st, actor, func(status *ateapi.ActorStatus) { status.LastAssignedGeneration = 1 - status.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", uri.Name(), uri.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + status.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", uri.Name(), uri.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), } }) } @@ -259,20 +259,20 @@ func newTestSuspendedActor(t *testing.T, ctx context.Context, st store.Interface // newTestTag builds a finished tag of actor: the shape // CreateTag leaves behind, pointing at the tag's own copy of the // actor's external snapshot rather than at the actor's. -func newTestTag(t *testing.T, name string, actor *ateapipb.Actor) *ateapipb.Tag { +func newTestTag(t *testing.T, name string, actor *ateapi.Actor) *ateapi.Tag { t.Helper() atespace := actor.GetMetadata().GetAtespace() uri, err := resources.NewTagSnapshotURI(testStorageLocation, atespace, name) if err != nil { t.Fatalf("NewTagSnapshotURI: %v", err) } - actorSnap := findLatestDurableSnapshot(actor.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) - return &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: name}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, + actorSnap := findLatestDurableSnapshot(actor.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + return &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: name}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, SourceActor: resources.ActorRefFromActor(actor).ToObjectRef(), - Status: &ateapipb.TagStatus{ - Snapshot: newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, actorSnap.GetFidelity(), actorSnap.GetActorTemplateUid(), uri.Name(), uri.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + Status: &ateapi.TagStatus{ + Snapshot: newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, actorSnap.GetFidelity(), actorSnap.GetActorTemplateUid(), uri.Name(), uri.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), }, } } @@ -280,17 +280,17 @@ func newTestTag(t *testing.T, name string, actor *ateapipb.Actor) *ateapipb.Tag // newPendingTestTag builds the tag a create leaves behind when it dies between // reserving the name and finishing the copy: the row names the prefix it was // writing into as PENDING. -func newPendingTestTag(t *testing.T, name string, actor *ateapipb.Actor) *ateapipb.Tag { +func newPendingTestTag(t *testing.T, name string, actor *ateapi.Actor) *ateapi.Tag { t.Helper() tag := newTestTag(t, name, actor) - tag.Status.Snapshot.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + tag.Status.Snapshot.DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING return tag } // rpcServiceWithTag seeds a suspended actor and a tag over its // external snapshot in a PostgreSQL-backed store, and returns an RPCService // over it. -func rpcServiceWithTag(t *testing.T, tag *ateapipb.Tag) (*RPCService, *ateapipb.Tag) { +func rpcServiceWithTag(t *testing.T, tag *ateapi.Tag) (*RPCService, *ateapi.Tag) { t.Helper() ctx := context.Background() persistence, cleanup := storetest.SetupTestStore(t) @@ -320,7 +320,7 @@ func TestUpdateTag_DeleteRecreateRace(t *testing.T) { // A concurrent client deletes A and re-tags the same atespace/name as a // brand new tag B, pointed at another snapshot. - var recreatedTag *ateapipb.Tag + var recreatedTag *ateapi.Tag racing := &conflictInjectingStore{ Interface: persistence, inject: func() { @@ -339,8 +339,8 @@ func TestUpdateTag_DeleteRecreateRace(t *testing.T) { // The client asserts "only update the tag with uid A". Its version guard is // satisfied by B as well, because re-tagging resets the version to 1: the // uid is the only thing that can tell the two lifecycles apart. - originalTag.Scope = ateapipb.TagScope_TAG_SCOPE_PUBLISHED - _, err := svc.UpdateTag(ctx, &ateapipb.UpdateTagRequest{ + originalTag.Scope = ateapi.TagScope_TAG_SCOPE_PUBLISHED + _, err := svc.UpdateTag(ctx, &ateapi.UpdateTagRequest{ Tag: originalTag, }) if code := apierror.Code(err); code != codes.Aborted { @@ -378,8 +378,8 @@ func TestUpdateTag_ConcurrentUpdate(t *testing.T) { racing := &conflictInjectingStore{ Interface: persistence, inject: func() { - if _, err := persistence.UpdateTag(ctx, resources.TagRef{Atespace: testAtespace, Name: tagName}, store.PreconditionFrom(originalTag), func(toUpdate *ateapipb.Tag) error { - toUpdate.Scope = ateapipb.TagScope_TAG_SCOPE_ATESPACE + if _, err := persistence.UpdateTag(ctx, resources.TagRef{Atespace: testAtespace, Name: tagName}, store.PreconditionFrom(originalTag), func(toUpdate *ateapi.Tag) error { + toUpdate.Scope = ateapi.TagScope_TAG_SCOPE_ATESPACE return nil }); err != nil { t.Fatalf("Racing writer: UpdateTag: %v", err) @@ -388,8 +388,8 @@ func TestUpdateTag_ConcurrentUpdate(t *testing.T) { } svc := &RPCService{impl: newServiceImpl(racing, nil)} - originalTag.Scope = ateapipb.TagScope_TAG_SCOPE_PUBLISHED - _, err := svc.UpdateTag(ctx, &ateapipb.UpdateTagRequest{ + originalTag.Scope = ateapi.TagScope_TAG_SCOPE_PUBLISHED + _, err := svc.UpdateTag(ctx, &ateapi.UpdateTagRequest{ Tag: originalTag, }) if code := apierror.Code(err); code != codes.Aborted { @@ -405,7 +405,7 @@ func TestUpdateTag_ConcurrentUpdate(t *testing.T) { if got, want := storedTag.GetMetadata().GetVersion(), originalTag.GetMetadata().GetVersion()+1; got != want { t.Errorf("stored version = %d, want %d", got, want) } - if got, want := storedTag.GetScope(), ateapipb.TagScope_TAG_SCOPE_ATESPACE; got != want { + if got, want := storedTag.GetScope(), ateapi.TagScope_TAG_SCOPE_ATESPACE; got != want { t.Errorf("Stored scope = %v, want %v: the rejected update was applied anyway", got, want) } } @@ -422,8 +422,8 @@ func TestUpdateTag_PendingTag(t *testing.T) { actor := newTestSuspendedActor(t, ctx, persistence, testAtespace, "actor-1") tag := storetest.MustCreateTag(t, ctx, persistence, newPendingTestTag(t, "v1", actor)) - tag.Scope = ateapipb.TagScope_TAG_SCOPE_PUBLISHED - _, err := svc.UpdateTag(ctx, &ateapipb.UpdateTagRequest{Tag: tag}) + tag.Scope = ateapi.TagScope_TAG_SCOPE_PUBLISHED + _, err := svc.UpdateTag(ctx, &ateapi.UpdateTagRequest{Tag: tag}) if code := apierror.Code(err); code != codes.FailedPrecondition { t.Fatalf("UpdateTag error = %v (code %v), want code FailedPrecondition", err, code) } @@ -432,7 +432,7 @@ func TestUpdateTag_PendingTag(t *testing.T) { if err != nil { t.Fatalf("GetTag: %v", err) } - if got, want := stored.GetScope(), ateapipb.TagScope_TAG_SCOPE_ATESPACE; got != want { + if got, want := stored.GetScope(), ateapi.TagScope_TAG_SCOPE_ATESPACE; got != want { t.Errorf("stored scope = %v, want %v: the rejected update published a pending tag", got, want) } } diff --git a/cmd/ateapi/internal/controlapi/template_reconciler.go b/cmd/ateapi/internal/controlapi/template_reconciler.go index 891128b0dd..285649afd2 100644 --- a/cmd/ateapi/internal/controlapi/template_reconciler.go +++ b/cmd/ateapi/internal/controlapi/template_reconciler.go @@ -22,10 +22,10 @@ import ( "time" "unicode/utf8" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" @@ -63,25 +63,25 @@ var errGoldenEgressPolicyConflict = errors.New("golden actor egress policy does // templateReconcilerStore enumerates the exact storage methods needed by // ActorTemplateReconciler and nothing more. type templateReconcilerStore interface { - GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapipb.ActorTemplate, error) - ListActorTemplates(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapipb.ActorTemplate], error) - UpdateActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.Precondition, mutate func(dbTemplate *ateapipb.ActorTemplate) error) (*ateapipb.ActorTemplate, error) + GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapi.ActorTemplate, error) + ListActorTemplates(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapi.ActorTemplate], error) + UpdateActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.Precondition, mutate func(dbTemplate *ateapi.ActorTemplate) error) (*ateapi.ActorTemplate, error) AcquireLease(ctx context.Context, key string) (*store.Lease, error) } // goldenActorControl is the in-process slice of the Control service the // reconciler drives golden actors through. *RPCService satisfies it. type goldenActorControl interface { - GetTag(ctx context.Context, req *ateapipb.GetTagRequest) (*ateapipb.Tag, error) - CreateTag(ctx context.Context, req *ateapipb.CreateTagRequest) (*ateapipb.Tag, error) - DeleteTag(ctx context.Context, req *ateapipb.DeleteTagRequest) (*ateapipb.Tag, error) - DeleteActor(ctx context.Context, req *ateapipb.DeleteActorRequest) (*ateapipb.Actor, error) - CreateActor(ctx context.Context, req *ateapipb.CreateActorRequest) (*ateapipb.Actor, error) - GetActor(ctx context.Context, req *ateapipb.GetActorRequest) (*ateapipb.Actor, error) - CreateActorEgressPolicy(ctx context.Context, req *ateapipb.CreateActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) - GetActorEgressPolicy(ctx context.Context, req *ateapipb.GetActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) - ResumeActor(ctx context.Context, req *ateapipb.ResumeActorRequest) (*ateapipb.ResumeActorResponse, error) - SuspendActor(ctx context.Context, req *ateapipb.SuspendActorRequest) (*ateapipb.SuspendActorResponse, error) + GetTag(ctx context.Context, req *ateapi.GetTagRequest) (*ateapi.Tag, error) + CreateTag(ctx context.Context, req *ateapi.CreateTagRequest) (*ateapi.Tag, error) + DeleteTag(ctx context.Context, req *ateapi.DeleteTagRequest) (*ateapi.Tag, error) + DeleteActor(ctx context.Context, req *ateapi.DeleteActorRequest) (*ateapi.Actor, error) + CreateActor(ctx context.Context, req *ateapi.CreateActorRequest) (*ateapi.Actor, error) + GetActor(ctx context.Context, req *ateapi.GetActorRequest) (*ateapi.Actor, error) + CreateActorEgressPolicy(ctx context.Context, req *ateapi.CreateActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) + GetActorEgressPolicy(ctx context.Context, req *ateapi.GetActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) + ResumeActor(ctx context.Context, req *ateapi.ResumeActorRequest) (*ateapi.ResumeActorResponse, error) + SuspendActor(ctx context.Context, req *ateapi.SuspendActorRequest) (*ateapi.SuspendActorResponse, error) } // ActorTemplateReconciler drives stored ActorTemplates through the golden @@ -126,7 +126,7 @@ func (r *ActorTemplateReconciler) resync(ctx context.Context) { return } for _, tmpl := range page.Items { - if tmpl.GetSnapshotConfig().GetGoldenSnapshotConfig().GetMode() == ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED { + if tmpl.GetSnapshotConfig().GetGoldenSnapshotConfig().GetMode() == ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED { continue } ref := resources.ActorTemplateRefFromActorTemplate(tmpl) @@ -200,11 +200,11 @@ func (r *ActorTemplateReconciler) reconcileOne(ctx context.Context, ref resource // TODO: Skip a template with delete_time set. DeleteActorTemplate may // already have deleted the golden actor and tag, and this pass rebuilds them. - if tmpl.GetSnapshotConfig().GetGoldenSnapshotConfig().GetMode() == ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED { + if tmpl.GetSnapshotConfig().GetGoldenSnapshotConfig().GetMode() == ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED { return 0, nil } - goldenActorRef := &ateapipb.ObjectRef{ + goldenActorRef := &ateapi.ObjectRef{ // Golden actors live in the template's atespace, under the same // policies and storage grants as ordinary actors. Atespace: tmpl.GetMetadata().GetAtespace(), @@ -228,7 +228,7 @@ func (r *ActorTemplateReconciler) reconcileOne(ctx context.Context, ref resource } // A completed tag survives a crash during actor deletion or checkpointing. - tag, err := r.control.GetTag(ctx, &ateapipb.GetTagRequest{Tag: goldenActorRef}) + tag, err := r.control.GetTag(ctx, &ateapi.GetTagRequest{Tag: goldenActorRef}) if err != nil && apierror.Code(err) != codes.NotFound { return 0, fmt.Errorf("while getting golden tag: %w", err) } @@ -236,11 +236,11 @@ func (r *ActorTemplateReconciler) reconcileOne(ctx context.Context, ref resource if tag.GetStatus().GetActorTemplateUid() != tmpl.GetMetadata().GetUid() || resources.ActorRefFromObjectRef(tag.GetSourceActor()) != resources.ActorRefFromObjectRef(goldenActorRef) { return 0, r.fail(ctx, tmpl, reasonGoldenTagConflict, "golden tag belongs to another actor or template") } - if tagDurableSnapshotURI(tag, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) != "" { + if tagDurableSnapshotURI(tag, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) != "" { return 0, r.saveGoldenTag(ctx, tmpl, goldenActorRef) } // CreateTag cannot resume an incomplete copy. Delete it before retrying. - if _, err := r.control.DeleteTag(ctx, &ateapipb.DeleteTagRequest{Tag: goldenActorRef}); err != nil && apierror.Code(err) != codes.NotFound { + if _, err := r.control.DeleteTag(ctx, &ateapi.DeleteTagRequest{Tag: goldenActorRef}); err != nil && apierror.Code(err) != codes.NotFound { return 0, fmt.Errorf("while deleting incomplete golden tag: %w", err) } } @@ -255,10 +255,10 @@ func (r *ActorTemplateReconciler) reconcileOne(ctx context.Context, ref resource } switch state := actor.GetStatus().GetState(); state { - case ateapipb.ActorState_ACTOR_STATE_CRASHED: + case ateapi.ActorState_ACTOR_STATE_CRASHED: return 0, r.fail(ctx, tmpl, reasonGoldenActorCrashed, "golden actor crashed before its snapshot was taken") - case ateapipb.ActorState_ACTOR_STATE_RUNNING: + case ateapi.ActorState_ACTOR_STATE_RUNNING: takeAt := goldenSnapshotStatus.GetSnapshotTime() if takeAt == nil { // Resumed, but the deadline write was lost (a replica died @@ -266,7 +266,7 @@ func (r *ActorTemplateReconciler) reconcileOne(ctx context.Context, ref resource // restart the clock. slog.WarnContext(ctx, "Golden actor running without a snapshot deadline; restarting warmup", slog.String("ActorTemplate", ref.String())) deadline := time.Now().Add(goldenSnapshotWarmupFor(tmpl.GetContainers())) - if tmpl, err = r.checkpoint(ctx, tmpl, func(snapshotStatus *ateapipb.GoldenSnapshotStatus) { + if tmpl, err = r.checkpoint(ctx, tmpl, func(snapshotStatus *ateapi.GoldenSnapshotStatus) { snapshotStatus.SnapshotTime = timestamppb.New(deadline) }); err != nil { return 0, err @@ -284,7 +284,7 @@ func (r *ActorTemplateReconciler) reconcileOne(ctx context.Context, ref resource } return 0, r.tagGoldenActor(ctx, tmpl, goldenActorRef) - case ateapipb.ActorState_ACTOR_STATE_SUSPENDING: + case ateapi.ActorState_ACTOR_STATE_SUSPENDING: // A previous pass died mid-suspend; retry suspend. err := r.suspendActor(ctx, goldenActorRef) if err != nil { @@ -292,11 +292,11 @@ func (r *ActorTemplateReconciler) reconcileOne(ctx context.Context, ref resource } return 0, r.tagGoldenActor(ctx, tmpl, goldenActorRef) - case ateapipb.ActorState_ACTOR_STATE_RESUMING, - ateapipb.ActorState_ACTOR_STATE_SUSPENDED: + case ateapi.ActorState_ACTOR_STATE_RESUMING, + ateapi.ActorState_ACTOR_STATE_SUSPENDED: // The golden actor was never resumed, or a previous resume didn't // finish; ResumeActor is reentrant from both. - if findLatestDurableSnapshot(actor.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) != nil { + if findLatestDurableSnapshot(actor.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) != nil { // Golden actors never start from a source snapshot, so an // existing snapshot means an earlier suspend completed // without being recorded. @@ -308,17 +308,17 @@ func (r *ActorTemplateReconciler) reconcileOne(ctx context.Context, ref resource } return 0, fmt.Errorf("while ensuring golden egress policy: %w", err) } - if _, err := r.control.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: goldenActorRef}); err != nil { + if _, err := r.control.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: goldenActorRef}); err != nil { // A crash during resume is observed as CRASHED on the retry. return 0, fmt.Errorf("while resuming golden actor: %w", err) } deadline := time.Now().Add(goldenSnapshotWarmupFor(tmpl.GetContainers())) - if tmpl, err = r.checkpoint(ctx, tmpl, func(snapshotStatus *ateapipb.GoldenSnapshotStatus) { + if tmpl, err = r.checkpoint(ctx, tmpl, func(snapshotStatus *ateapi.GoldenSnapshotStatus) { snapshotStatus.SnapshotTime = timestamppb.New(deadline) }); err != nil { return 0, err } - case ateapipb.ActorState_ACTOR_STATE_DELETING, ateapipb.ActorState_ACTOR_STATE_REVERTING: + case ateapi.ActorState_ACTOR_STATE_DELETING, ateapi.ActorState_ACTOR_STATE_REVERTING: // Nothing in the golden flow deletes or reverts the actor before // the snapshot is taken; someone else interfered. return 0, r.fail(ctx, tmpl, reasonUnexpectedState, fmt.Sprintf("golden actor in unexpected state %v", state)) @@ -331,27 +331,27 @@ func (r *ActorTemplateReconciler) reconcileOne(ctx context.Context, ref resource // suspendActor waits for the golden actor to produce an external snapshot. // SuspendActor completes an in-flight suspend and is a no-op if already suspended. -func (r *ActorTemplateReconciler) suspendActor(ctx context.Context, goldenRef *ateapipb.ObjectRef) error { - resp, err := r.control.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ +func (r *ActorTemplateReconciler) suspendActor(ctx context.Context, goldenRef *ateapi.ObjectRef) error { + resp, err := r.control.SuspendActor(ctx, &ateapi.SuspendActorRequest{ Actor: goldenRef, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }) if err != nil { // A crash during suspend is observed as CRASHED on the retry. return fmt.Errorf("while suspending golden actor: %w", err) } - if findLatestDurableSnapshot(resp.GetActor().GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) == nil { + if findLatestDurableSnapshot(resp.GetActor().GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) == nil { return fmt.Errorf("suspending golden actor produced no external snapshot") } return nil } // tagGoldenActor copies the snapshot into a tag before releasing the actor's copy. -func (r *ActorTemplateReconciler) tagGoldenActor(ctx context.Context, tmpl *ateapipb.ActorTemplate, ref *ateapipb.ObjectRef) error { - _, err := r.control.CreateTag(ctx, &ateapipb.CreateTagRequest{Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, +func (r *ActorTemplateReconciler) tagGoldenActor(ctx context.Context, tmpl *ateapi.ActorTemplate, ref *ateapi.ObjectRef) error { + _, err := r.control.CreateTag(ctx, &ateapi.CreateTagRequest{Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, SourceActor: ref, - Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED, + Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED, }}) if err != nil { return fmt.Errorf("while creating golden tag: %w", err) @@ -361,11 +361,11 @@ func (r *ActorTemplateReconciler) tagGoldenActor(ctx context.Context, tmpl *atea // saveGoldenTag finishes cleanup before recording terminal success, so retries // can rediscover the tag even if deletion or the status write fails. -func (r *ActorTemplateReconciler) saveGoldenTag(ctx context.Context, tmpl *ateapipb.ActorTemplate, ref *ateapipb.ObjectRef) error { - if _, err := r.control.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref}); err != nil && apierror.Code(err) != codes.NotFound { +func (r *ActorTemplateReconciler) saveGoldenTag(ctx context.Context, tmpl *ateapi.ActorTemplate, ref *ateapi.ObjectRef) error { + if _, err := r.control.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}); err != nil && apierror.Code(err) != codes.NotFound { return fmt.Errorf("while deleting golden actor: %w", err) } - _, err := r.checkpoint(ctx, tmpl, func(snapshotStatus *ateapipb.GoldenSnapshotStatus) { + _, err := r.checkpoint(ctx, tmpl, func(snapshotStatus *ateapi.GoldenSnapshotStatus) { snapshotStatus.GoldenTag = ref }) return err @@ -375,17 +375,17 @@ func (r *ActorTemplateReconciler) saveGoldenTag(ctx context.Context, tmpl *ateap // writer already drove the template to a terminal state. The write is guarded // by the observed template's uid and version, so a stale observation surfaces // as a conflict for the workqueue to retry. -func (r *ActorTemplateReconciler) checkpoint(ctx context.Context, observed *ateapipb.ActorTemplate, mutate func(*ateapipb.GoldenSnapshotStatus)) (*ateapipb.ActorTemplate, error) { +func (r *ActorTemplateReconciler) checkpoint(ctx context.Context, observed *ateapi.ActorTemplate, mutate func(*ateapi.GoldenSnapshotStatus)) (*ateapi.ActorTemplate, error) { ref := resources.ActorTemplateRefFromActorTemplate(observed) - updated, err := r.persistence.UpdateActorTemplate(ctx, ref, store.PreconditionFrom(observed), func(dbTemplate *ateapipb.ActorTemplate) error { + updated, err := r.persistence.UpdateActorTemplate(ctx, ref, store.PreconditionFrom(observed), func(dbTemplate *ateapi.ActorTemplate) error { if goldenSnapshotDone(dbTemplate.GetStatus().GetGoldenSnapshotStatus()) { return fmt.Errorf("actor template reached a terminal golden snapshot state concurrently") } if dbTemplate.Status == nil { - dbTemplate.Status = &ateapipb.ActorTemplateStatus{} + dbTemplate.Status = &ateapi.ActorTemplateStatus{} } if dbTemplate.Status.GoldenSnapshotStatus == nil { - dbTemplate.Status.GoldenSnapshotStatus = &ateapipb.GoldenSnapshotStatus{} + dbTemplate.Status.GoldenSnapshotStatus = &ateapi.GoldenSnapshotStatus{} } mutate(dbTemplate.Status.GoldenSnapshotStatus) return nil @@ -396,8 +396,8 @@ func (r *ActorTemplateReconciler) checkpoint(ctx context.Context, observed *atea // fail commits the terminal error message, prefixed with a machine-readable // reason and truncated to fit error_message's bound. -func (r *ActorTemplateReconciler) fail(ctx context.Context, observed *ateapipb.ActorTemplate, reason, msg string) error { - _, err := r.checkpoint(ctx, observed, func(snapshotStatus *ateapipb.GoldenSnapshotStatus) { +func (r *ActorTemplateReconciler) fail(ctx context.Context, observed *ateapi.ActorTemplate, reason, msg string) error { + _, err := r.checkpoint(ctx, observed, func(snapshotStatus *ateapi.GoldenSnapshotStatus) { snapshotStatus.ErrorMessage = truncateUTF8(reason+": "+msg, maxGoldenErrorMessageLen) }) return err @@ -417,14 +417,14 @@ func truncateUTF8(s string, n int) string { // goldenSnapshotDone reports whether the golden snapshot build reached a // terminal state: the snapshot was recorded, or the build failed. -func goldenSnapshotDone(snapshotStatus *ateapipb.GoldenSnapshotStatus) bool { +func goldenSnapshotDone(snapshotStatus *ateapi.GoldenSnapshotStatus) bool { return snapshotStatus.GetGoldenTag() != nil || snapshotStatus.GetErrorMessage() != "" } // goldenSnapshotWarmupFor returns 0 when every container has a wakeup probe // (ResumeActor already blocked until the workload reported 200), and the // default warmup otherwise. -func goldenSnapshotWarmupFor(containers []*ateapipb.Container) time.Duration { +func goldenSnapshotWarmupFor(containers []*ateapi.Container) time.Duration { if len(containers) == 0 { return goldenSnapshotWarmup } @@ -438,17 +438,17 @@ func goldenSnapshotWarmupFor(containers []*ateapipb.Container) time.Duration { // ensureActorExists returns the golden actor, creating it first if it does // not exist yet. -func (r *ActorTemplateReconciler) ensureActorExists(ctx context.Context, tmpl *ateapipb.ActorTemplate, goldenActorRef *ateapipb.ObjectRef) (*ateapipb.Actor, error) { - actor, err := r.control.GetActor(ctx, &ateapipb.GetActorRequest{Actor: goldenActorRef}) +func (r *ActorTemplateReconciler) ensureActorExists(ctx context.Context, tmpl *ateapi.ActorTemplate, goldenActorRef *ateapi.ObjectRef) (*ateapi.Actor, error) { + actor, err := r.control.GetActor(ctx, &ateapi.GetActorRequest{Actor: goldenActorRef}) if err == nil { return actor, nil } if apierror.Code(err) != codes.NotFound { return nil, fmt.Errorf("while getting golden actor: %w", err) } - actor, err = r.control.CreateActor(ctx, &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ + actor, err = r.control.CreateActor(ctx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: goldenActorRef.GetAtespace(), Name: goldenActorRef.GetName(), }, @@ -463,15 +463,15 @@ func (r *ActorTemplateReconciler) ensureActorExists(ctx context.Context, tmpl *a // ensureGoldenEgressPolicy also runs when an earlier pass created the actor but // failed before creating its policy or resuming it. -func (r *ActorTemplateReconciler) ensureGoldenEgressPolicy(ctx context.Context, tmpl *ateapipb.ActorTemplate, actorRef *ateapipb.ObjectRef) error { +func (r *ActorTemplateReconciler) ensureGoldenEgressPolicy(ctx context.Context, tmpl *ateapi.ActorTemplate, actorRef *ateapi.ObjectRef) error { want := tmpl.GetGoldenEgressPolicy() if want == nil { return nil } - _, err := r.control.CreateActorEgressPolicy(ctx, &ateapipb.CreateActorEgressPolicyRequest{ + _, err := r.control.CreateActorEgressPolicy(ctx, &ateapi.CreateActorEgressPolicyRequest{ Actor: actorRef, - EgressPolicy: &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.GetAtespace(), Name: resources.SingletonName}, + EgressPolicy: &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.GetAtespace(), Name: resources.SingletonName}, Rules: proto.CloneOf(want).GetRules(), }, }) @@ -481,11 +481,11 @@ func (r *ActorTemplateReconciler) ensureGoldenEgressPolicy(ctx context.Context, if apierror.Code(err) != codes.AlreadyExists { return err } - existing, err := r.control.GetActorEgressPolicy(ctx, &ateapipb.GetActorEgressPolicyRequest{Actor: actorRef, Name: resources.SingletonName}) + existing, err := r.control.GetActorEgressPolicy(ctx, &ateapi.GetActorEgressPolicyRequest{Actor: actorRef, Name: resources.SingletonName}) if err != nil { return err } - if !proto.Equal(&ateapipb.EgressPolicyTemplate{Rules: existing.GetRules()}, want) { + if !proto.Equal(&ateapi.EgressPolicyTemplate{Rules: existing.GetRules()}, want) { return errGoldenEgressPolicyConflict } return nil diff --git a/cmd/ateapi/internal/controlapi/template_reconciler_test.go b/cmd/ateapi/internal/controlapi/template_reconciler_test.go index 4786dab365..68c3ca2778 100644 --- a/cmd/ateapi/internal/controlapi/template_reconciler_test.go +++ b/cmd/ateapi/internal/controlapi/template_reconciler_test.go @@ -25,13 +25,13 @@ import ( "time" "unicode/utf8" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" @@ -40,7 +40,7 @@ import ( // fakeTemplateStore is an in-memory templateReconcilerStore. type fakeTemplateStore struct { mu sync.Mutex - templates map[resources.ActorTemplateRef]*ateapipb.ActorTemplate + templates map[resources.ActorTemplateRef]*ateapi.ActorTemplate // leaseErr, when set, is returned by AcquireLease. leaseErr error @@ -49,25 +49,25 @@ type fakeTemplateStore struct { forcePageSize int } -func newFakeTemplateStore(templates ...*ateapipb.ActorTemplate) *fakeTemplateStore { - s := &fakeTemplateStore{templates: map[resources.ActorTemplateRef]*ateapipb.ActorTemplate{}} +func newFakeTemplateStore(templates ...*ateapi.ActorTemplate) *fakeTemplateStore { + s := &fakeTemplateStore{templates: map[resources.ActorTemplateRef]*ateapi.ActorTemplate{}} for _, tmpl := range templates { - s.templates[resources.ActorTemplateRefFromActorTemplate(tmpl)] = proto.Clone(tmpl).(*ateapipb.ActorTemplate) + s.templates[resources.ActorTemplateRefFromActorTemplate(tmpl)] = proto.Clone(tmpl).(*ateapi.ActorTemplate) } return s } -func (s *fakeTemplateStore) GetActorTemplate(_ context.Context, ref resources.ActorTemplateRef) (*ateapipb.ActorTemplate, error) { +func (s *fakeTemplateStore) GetActorTemplate(_ context.Context, ref resources.ActorTemplateRef) (*ateapi.ActorTemplate, error) { s.mu.Lock() defer s.mu.Unlock() tmpl, ok := s.templates[ref] if !ok { return nil, store.ErrNotFound } - return proto.Clone(tmpl).(*ateapipb.ActorTemplate), nil + return proto.Clone(tmpl).(*ateapi.ActorTemplate), nil } -func (s *fakeTemplateStore) ListActorTemplates(_ context.Context, _ string, opts store.ListOptions) (store.ListResponse[*ateapipb.ActorTemplate], error) { +func (s *fakeTemplateStore) ListActorTemplates(_ context.Context, _ string, opts store.ListOptions) (store.ListResponse[*ateapi.ActorTemplate], error) { s.mu.Lock() defer s.mu.Unlock() refs := make([]resources.ActorTemplateRef, 0, len(s.templates)) @@ -84,13 +84,13 @@ func (s *fakeTemplateStore) ListActorTemplates(_ context.Context, _ string, opts if opts.PageToken != "" { var err error if start, err = strconv.Atoi(opts.PageToken); err != nil { - return store.ListResponse[*ateapipb.ActorTemplate]{}, err + return store.ListResponse[*ateapi.ActorTemplate]{}, err } } end := min(start+pageSize, len(refs)) - var resp store.ListResponse[*ateapipb.ActorTemplate] + var resp store.ListResponse[*ateapi.ActorTemplate] for _, ref := range refs[start:end] { - resp.Items = append(resp.Items, proto.Clone(s.templates[ref]).(*ateapipb.ActorTemplate)) + resp.Items = append(resp.Items, proto.Clone(s.templates[ref]).(*ateapi.ActorTemplate)) } if end < len(refs) { resp.NextPageToken = strconv.Itoa(end) @@ -98,7 +98,7 @@ func (s *fakeTemplateStore) ListActorTemplates(_ context.Context, _ string, opts return resp, nil } -func (s *fakeTemplateStore) UpdateActorTemplate(_ context.Context, ref resources.ActorTemplateRef, precondition store.Precondition, mutate func(*ateapipb.ActorTemplate) error) (*ateapipb.ActorTemplate, error) { +func (s *fakeTemplateStore) UpdateActorTemplate(_ context.Context, ref resources.ActorTemplateRef, precondition store.Precondition, mutate func(*ateapi.ActorTemplate) error) (*ateapi.ActorTemplate, error) { s.mu.Lock() defer s.mu.Unlock() if err := precondition.Validate(); err != nil { @@ -111,13 +111,13 @@ func (s *fakeTemplateStore) UpdateActorTemplate(_ context.Context, ref resources if err := precondition.Check(tmpl.GetMetadata()); err != nil { return nil, err } - updated := proto.Clone(tmpl).(*ateapipb.ActorTemplate) + updated := proto.Clone(tmpl).(*ateapi.ActorTemplate) if err := mutate(updated); err != nil { return nil, err } updated.Metadata.Version++ s.templates[ref] = updated - return proto.Clone(updated).(*ateapipb.ActorTemplate), nil + return proto.Clone(updated).(*ateapi.ActorTemplate), nil } func (s *fakeTemplateStore) AcquireLease(ctx context.Context, _ string) (*store.Lease, error) { @@ -129,7 +129,7 @@ func (s *fakeTemplateStore) AcquireLease(ctx context.Context, _ string) (*store. } // storedStatus returns the persisted status for ref, for assertions. -func (s *fakeTemplateStore) storedStatus(t *testing.T, ref resources.ActorTemplateRef) *ateapipb.ActorTemplateStatus { +func (s *fakeTemplateStore) storedStatus(t *testing.T, ref resources.ActorTemplateRef) *ateapi.ActorTemplateStatus { t.Helper() s.mu.Lock() defer s.mu.Unlock() @@ -137,7 +137,7 @@ func (s *fakeTemplateStore) storedStatus(t *testing.T, ref resources.ActorTempla if !ok { t.Fatalf("template %v not in store", ref) } - return proto.Clone(tmpl).(*ateapipb.ActorTemplate).GetStatus() + return proto.Clone(tmpl).(*ateapi.ActorTemplate).GetStatus() } // fakeGoldenControl is a stateful in-memory goldenActorControl: the golden @@ -148,12 +148,12 @@ func (s *fakeTemplateStore) storedStatus(t *testing.T, ref resources.ActorTempla // goldenState / goldenSnapshot. type fakeGoldenControl struct { mu sync.Mutex - tag *ateapipb.Tag + tag *ateapi.Tag tagErr error deleteErr error deleteTagErr error - tagReqs []*ateapipb.CreateTagRequest - deleteReqs []*ateapipb.DeleteActorRequest + tagReqs []*ateapi.CreateTagRequest + deleteReqs []*ateapi.DeleteActorRequest createErr error resumeErr error @@ -164,57 +164,57 @@ type fakeGoldenControl struct { // goldenSnapshot are its observed state and external snapshot while it // does. exists bool - goldenState ateapipb.ActorState + goldenState ateapi.ActorState goldenSnapshot string // snapshot is the external snapshot a completed suspend produces; empty // simulates a suspend that wrote none. snapshot string - createReqs []*ateapipb.CreateActorRequest - resumeReqs []*ateapipb.ResumeActorRequest - suspendReqs []*ateapipb.SuspendActorRequest - atespaceReqs []*ateapipb.CreateAtespaceRequest + createReqs []*ateapi.CreateActorRequest + resumeReqs []*ateapi.ResumeActorRequest + suspendReqs []*ateapi.SuspendActorRequest + atespaceReqs []*ateapi.CreateAtespaceRequest } -func (c *fakeGoldenControl) CreateAtespace(_ context.Context, req *ateapipb.CreateAtespaceRequest) (*ateapipb.Atespace, error) { +func (c *fakeGoldenControl) CreateAtespace(_ context.Context, req *ateapi.CreateAtespaceRequest) (*ateapi.Atespace, error) { c.mu.Lock() defer c.mu.Unlock() c.atespaceReqs = append(c.atespaceReqs, req) return req.GetAtespace(), nil } -func (c *fakeGoldenControl) goldenActorStatus() *ateapipb.ActorStatus { - st := &ateapipb.ActorStatus{State: c.goldenState} +func (c *fakeGoldenControl) goldenActorStatus() *ateapi.ActorStatus { + st := &ateapi.ActorStatus{State: c.goldenState} if c.goldenSnapshot != "" { st.LastAssignedGeneration = 1 - st.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, testTemplateUID, "golden-snapshot", c.goldenSnapshot, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + st.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, testTemplateUID, "golden-snapshot", c.goldenSnapshot, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), } } return st } -func (c *fakeGoldenControl) CreateActor(_ context.Context, req *ateapipb.CreateActorRequest) (*ateapipb.Actor, error) { +func (c *fakeGoldenControl) CreateActor(_ context.Context, req *ateapi.CreateActorRequest) (*ateapi.Actor, error) { c.mu.Lock() defer c.mu.Unlock() c.createReqs = append(c.createReqs, req) // AlreadyExists means the actor does exist (e.g. a racing creation). if c.createErr == nil || apierror.Code(c.createErr) == codes.AlreadyExists { c.exists = true - c.goldenState = ateapipb.ActorState_ACTOR_STATE_SUSPENDED + c.goldenState = ateapi.ActorState_ACTOR_STATE_SUSPENDED } if c.createErr != nil { return nil, c.createErr } // Like the real Control service, return the stored actor: metadata plus // a status observing the initial SUSPENDED state. - return &ateapipb.Actor{ + return &ateapi.Actor{ Metadata: req.GetActor().GetMetadata(), Status: c.goldenActorStatus(), }, nil } -func (c *fakeGoldenControl) GetActor(_ context.Context, req *ateapipb.GetActorRequest) (*ateapipb.Actor, error) { +func (c *fakeGoldenControl) GetActor(_ context.Context, req *ateapi.GetActorRequest) (*ateapi.Actor, error) { c.mu.Lock() defer c.mu.Unlock() if c.getErr != nil { @@ -223,48 +223,48 @@ func (c *fakeGoldenControl) GetActor(_ context.Context, req *ateapipb.GetActorRe if !c.exists { return nil, apierror.NotFound("no such actor") } - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: req.GetActor().GetAtespace(), Name: req.GetActor().GetName()}, + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: req.GetActor().GetAtespace(), Name: req.GetActor().GetName()}, Status: c.goldenActorStatus(), }, nil } -func (c *fakeGoldenControl) ResumeActor(_ context.Context, req *ateapipb.ResumeActorRequest) (*ateapipb.ResumeActorResponse, error) { +func (c *fakeGoldenControl) ResumeActor(_ context.Context, req *ateapi.ResumeActorRequest) (*ateapi.ResumeActorResponse, error) { c.mu.Lock() defer c.mu.Unlock() c.resumeReqs = append(c.resumeReqs, req) if c.resumeErr != nil { return nil, c.resumeErr } - c.goldenState = ateapipb.ActorState_ACTOR_STATE_RUNNING - return &ateapipb.ResumeActorResponse{}, nil + c.goldenState = ateapi.ActorState_ACTOR_STATE_RUNNING + return &ateapi.ResumeActorResponse{}, nil } -func (c *fakeGoldenControl) CreateActorEgressPolicy(context.Context, *ateapipb.CreateActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) { +func (c *fakeGoldenControl) CreateActorEgressPolicy(context.Context, *ateapi.CreateActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) { return nil, errors.New("unexpected golden egress policy creation") } -func (c *fakeGoldenControl) GetActorEgressPolicy(context.Context, *ateapipb.GetActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) { +func (c *fakeGoldenControl) GetActorEgressPolicy(context.Context, *ateapi.GetActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) { return nil, errors.New("unexpected golden egress policy lookup") } -func (c *fakeGoldenControl) SuspendActor(_ context.Context, req *ateapipb.SuspendActorRequest) (*ateapipb.SuspendActorResponse, error) { +func (c *fakeGoldenControl) SuspendActor(_ context.Context, req *ateapi.SuspendActorRequest) (*ateapi.SuspendActorResponse, error) { c.mu.Lock() defer c.mu.Unlock() c.suspendReqs = append(c.suspendReqs, req) if c.suspendErr != nil { return nil, c.suspendErr } - c.goldenState = ateapipb.ActorState_ACTOR_STATE_SUSPENDED + c.goldenState = ateapi.ActorState_ACTOR_STATE_SUSPENDED if c.goldenSnapshot == "" { c.goldenSnapshot = c.snapshot } - return &ateapipb.SuspendActorResponse{ - Actor: &ateapipb.Actor{Status: c.goldenActorStatus()}, + return &ateapi.SuspendActorResponse{ + Actor: &ateapi.Actor{Status: c.goldenActorStatus()}, }, nil } -func (c *fakeGoldenControl) GetTag(_ context.Context, _ *ateapipb.GetTagRequest) (*ateapipb.Tag, error) { +func (c *fakeGoldenControl) GetTag(_ context.Context, _ *ateapi.GetTagRequest) (*ateapi.Tag, error) { c.mu.Lock() defer c.mu.Unlock() if c.tag == nil { @@ -273,7 +273,7 @@ func (c *fakeGoldenControl) GetTag(_ context.Context, _ *ateapipb.GetTagRequest) return proto.CloneOf(c.tag), nil } -func (c *fakeGoldenControl) CreateTag(_ context.Context, req *ateapipb.CreateTagRequest) (*ateapipb.Tag, error) { +func (c *fakeGoldenControl) CreateTag(_ context.Context, req *ateapi.CreateTagRequest) (*ateapi.Tag, error) { c.mu.Lock() defer c.mu.Unlock() c.tagReqs = append(c.tagReqs, req) @@ -281,14 +281,14 @@ func (c *fakeGoldenControl) CreateTag(_ context.Context, req *ateapipb.CreateTag return nil, c.tagErr } c.tag = proto.CloneOf(req.GetTag()) - c.tag.Status = &ateapipb.TagStatus{ + c.tag.Status = &ateapi.TagStatus{ ActorTemplateUid: testTemplateUID, - Snapshot: newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, testTemplateUID, "golden-snapshot", c.goldenSnapshot, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + Snapshot: newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, testTemplateUID, "golden-snapshot", c.goldenSnapshot, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), } return proto.CloneOf(c.tag), nil } -func (c *fakeGoldenControl) DeleteTag(_ context.Context, _ *ateapipb.DeleteTagRequest) (*ateapipb.Tag, error) { +func (c *fakeGoldenControl) DeleteTag(_ context.Context, _ *ateapi.DeleteTagRequest) (*ateapi.Tag, error) { c.mu.Lock() defer c.mu.Unlock() if c.deleteTagErr != nil { @@ -299,7 +299,7 @@ func (c *fakeGoldenControl) DeleteTag(_ context.Context, _ *ateapipb.DeleteTagRe return tag, nil } -func (c *fakeGoldenControl) DeleteActor(_ context.Context, req *ateapipb.DeleteActorRequest) (*ateapipb.Actor, error) { +func (c *fakeGoldenControl) DeleteActor(_ context.Context, req *ateapi.DeleteActorRequest) (*ateapi.Actor, error) { c.mu.Lock() defer c.mu.Unlock() c.deleteReqs = append(c.deleteReqs, req) @@ -310,7 +310,7 @@ func (c *fakeGoldenControl) DeleteActor(_ context.Context, req *ateapipb.DeleteA return nil, apierror.NotFound("no actor") } c.exists = false - return &ateapipb.Actor{}, nil + return &ateapi.Actor{}, nil } func (c *fakeGoldenControl) callCounts() (creates, resumes, suspends int) { @@ -329,16 +329,16 @@ var testTemplateRef = resources.ActorTemplateRef{Atespace: testAtespace, Name: t // testTemplate builds a template with an empty status whose single container // has a wakeup probe, so goldenSnapshotWarmupFor returns 0 and reconcileOne // drives the golden actor to a snapshot without waiting for a warmup window. -func testTemplate(opts ...func(*ateapipb.ActorTemplate)) *ateapipb.ActorTemplate { - tmpl := &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: testTemplateName, Uid: testTemplateUID, Version: 1}, - Containers: []*ateapipb.Container{ - {Name: "main", Image: "img", WakeupProbe: &ateapipb.WakeupProbe{}}, +func testTemplate(opts ...func(*ateapi.ActorTemplate)) *ateapi.ActorTemplate { + tmpl := &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: testTemplateName, Uid: testTemplateUID, Version: 1}, + Containers: []*ateapi.Container{ + {Name: "main", Image: "img", WakeupProbe: &ateapi.WakeupProbe{}}, }, - SnapshotConfig: &ateapipb.SnapshotConfig{ - GoldenSnapshotConfig: &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, + SnapshotConfig: &ateapi.SnapshotConfig{ + GoldenSnapshotConfig: &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, }, - Status: &ateapipb.ActorTemplateStatus{}, + Status: &ateapi.ActorTemplateStatus{}, } for _, opt := range opts { opt(tmpl) @@ -346,39 +346,39 @@ func testTemplate(opts ...func(*ateapipb.ActorTemplate)) *ateapipb.ActorTemplate return tmpl } -func withoutWakeupProbe(tmpl *ateapipb.ActorTemplate) { +func withoutWakeupProbe(tmpl *ateapi.ActorTemplate) { for _, container := range tmpl.Containers { container.WakeupProbe = nil } } -func withoutGoldenSnapshot(tmpl *ateapipb.ActorTemplate) { - tmpl.SnapshotConfig.GoldenSnapshotConfig.Mode = ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED +func withoutGoldenSnapshot(tmpl *ateapi.ActorTemplate) { + tmpl.SnapshotConfig.GoldenSnapshotConfig.Mode = ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED } // seededGoldenStatus returns the template's golden snapshot status, allocating // it so the with* options below can mutate it. -func seededGoldenStatus(tmpl *ateapipb.ActorTemplate) *ateapipb.GoldenSnapshotStatus { +func seededGoldenStatus(tmpl *ateapi.ActorTemplate) *ateapi.GoldenSnapshotStatus { if tmpl.Status.GoldenSnapshotStatus == nil { - tmpl.Status.GoldenSnapshotStatus = &ateapipb.GoldenSnapshotStatus{} + tmpl.Status.GoldenSnapshotStatus = &ateapi.GoldenSnapshotStatus{} } return tmpl.Status.GoldenSnapshotStatus } -func withSnapshotDeadline(at time.Time) func(*ateapipb.ActorTemplate) { - return func(tmpl *ateapipb.ActorTemplate) { +func withSnapshotDeadline(at time.Time) func(*ateapi.ActorTemplate) { + return func(tmpl *ateapi.ActorTemplate) { seededGoldenStatus(tmpl).SnapshotTime = timestamppb.New(at) } } -func withGoldenTag() func(*ateapipb.ActorTemplate) { - return func(tmpl *ateapipb.ActorTemplate) { - seededGoldenStatus(tmpl).GoldenTag = &ateapipb.ObjectRef{Atespace: testTemplateRef.Atespace, Name: testTemplateUID} +func withGoldenTag() func(*ateapi.ActorTemplate) { + return func(tmpl *ateapi.ActorTemplate) { + seededGoldenStatus(tmpl).GoldenTag = &ateapi.ObjectRef{Atespace: testTemplateRef.Atespace, Name: testTemplateUID} } } -func withFailed(reason string) func(*ateapipb.ActorTemplate) { - return func(tmpl *ateapipb.ActorTemplate) { +func withFailed(reason string) func(*ateapi.ActorTemplate) { + return func(tmpl *ateapi.ActorTemplate) { seededGoldenStatus(tmpl).ErrorMessage = reason + ": seeded failure" } } @@ -388,15 +388,15 @@ func newTestTemplateReconciler(persistence templateReconcilerStore, control gold } func TestGoldenSnapshotWarmupFor(t *testing.T) { - probe := &ateapipb.WakeupProbe{} + probe := &ateapi.WakeupProbe{} tests := []struct { name string - containers []*ateapipb.Container + containers []*ateapi.Container want time.Duration }{ {"no containers", nil, goldenSnapshotWarmup}, - {"all containers have wakeup probe", []*ateapipb.Container{{WakeupProbe: probe}, {WakeupProbe: probe}}, 0}, - {"one container missing wakeup probe", []*ateapipb.Container{{WakeupProbe: probe}, {}}, goldenSnapshotWarmup}, + {"all containers have wakeup probe", []*ateapi.Container{{WakeupProbe: probe}, {WakeupProbe: probe}}, 0}, + {"one container missing wakeup probe", []*ateapi.Container{{WakeupProbe: probe}, {}}, goldenSnapshotWarmup}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -411,7 +411,7 @@ func TestReconcileOne(t *testing.T) { goldenSnapshot := "gs://bucket/root/atespaces/ns/actors/" + someActorUID + "/snapshots/snap-1" tests := []struct { name string - template *ateapipb.ActorTemplate // nil: template absent from the store + template *ateapi.ActorTemplate // nil: template absent from the store leaseErr error control *fakeGoldenControl @@ -464,7 +464,7 @@ func TestReconcileOne(t *testing.T) { name: "running golden actor waits for a future deadline", template: testTemplate(withoutWakeupProbe, withSnapshotDeadline(time.Now().Add(time.Hour))), - control: &fakeGoldenControl{exists: true, goldenState: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + control: &fakeGoldenControl{exists: true, goldenState: ateapi.ActorState_ACTOR_STATE_RUNNING}, wantRequeueMin: 59 * time.Minute, wantRequeueMax: time.Hour, }, @@ -472,14 +472,14 @@ func TestReconcileOne(t *testing.T) { name: "running golden actor is snapshotted once the deadline passed", template: testTemplate( withSnapshotDeadline(time.Now().Add(-time.Minute))), - control: &fakeGoldenControl{exists: true, goldenState: ateapipb.ActorState_ACTOR_STATE_RUNNING, snapshot: goldenSnapshot}, + control: &fakeGoldenControl{exists: true, goldenState: ateapi.ActorState_ACTOR_STATE_RUNNING, snapshot: goldenSnapshot}, wantTag: true, wantSuspends: 1, }, { name: "running golden actor with a lost deadline restarts the warmup", template: testTemplate(withoutWakeupProbe), - control: &fakeGoldenControl{exists: true, goldenState: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + control: &fakeGoldenControl{exists: true, goldenState: ateapi.ActorState_ACTOR_STATE_RUNNING}, wantRequeueMin: goldenSnapshotWarmup - time.Second, wantRequeueMax: goldenSnapshotWarmup, wantDeadline: true, @@ -488,21 +488,21 @@ func TestReconcileOne(t *testing.T) { name: "suspend returning no snapshot errors", template: testTemplate( withSnapshotDeadline(time.Now().Add(-time.Minute))), - control: &fakeGoldenControl{exists: true, goldenState: ateapipb.ActorState_ACTOR_STATE_RUNNING, snapshot: ""}, + control: &fakeGoldenControl{exists: true, goldenState: ateapi.ActorState_ACTOR_STATE_RUNNING, snapshot: ""}, wantErr: true, wantSuspends: 1, }, { name: "suspending golden actor is completed and recorded", template: testTemplate(), - control: &fakeGoldenControl{exists: true, goldenState: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, snapshot: goldenSnapshot}, + control: &fakeGoldenControl{exists: true, goldenState: ateapi.ActorState_ACTOR_STATE_SUSPENDING, snapshot: goldenSnapshot}, wantTag: true, wantSuspends: 1, }, { name: "suspended golden actor with a snapshot is recorded without more control calls", template: testTemplate(), - control: &fakeGoldenControl{exists: true, goldenState: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, goldenSnapshot: goldenSnapshot}, + control: &fakeGoldenControl{exists: true, goldenState: ateapi.ActorState_ACTOR_STATE_SUSPENDED, goldenSnapshot: goldenSnapshot}, wantTag: true, }, { @@ -530,14 +530,14 @@ func TestReconcileOne(t *testing.T) { { name: "crashed golden actor fails the template", template: testTemplate(), - control: &fakeGoldenControl{exists: true, goldenState: ateapipb.ActorState_ACTOR_STATE_CRASHED}, + control: &fakeGoldenControl{exists: true, goldenState: ateapi.ActorState_ACTOR_STATE_CRASHED}, wantFailedReason: reasonGoldenActorCrashed, wantMessage: "crashed", }, { name: "resume failure requeues without failing", template: testTemplate(), - control: &fakeGoldenControl{exists: true, goldenState: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, resumeErr: apierror.Unavailable("no workers")}, + control: &fakeGoldenControl{exists: true, goldenState: ateapi.ActorState_ACTOR_STATE_SUSPENDED, resumeErr: apierror.Unavailable("no workers")}, wantErr: true, wantResumes: 1, }, @@ -550,14 +550,14 @@ func TestReconcileOne(t *testing.T) { { name: "deleting golden actor fails the template", template: testTemplate(), - control: &fakeGoldenControl{exists: true, goldenState: ateapipb.ActorState_ACTOR_STATE_DELETING}, + control: &fakeGoldenControl{exists: true, goldenState: ateapi.ActorState_ACTOR_STATE_DELETING}, wantFailedReason: reasonUnexpectedState, wantMessage: "unexpected state", }, { name: "unspecified actor state checks back later", template: testTemplate(), - control: &fakeGoldenControl{exists: true, goldenState: ateapipb.ActorState_ACTOR_STATE_UNSPECIFIED}, + control: &fakeGoldenControl{exists: true, goldenState: ateapi.ActorState_ACTOR_STATE_UNSPECIFIED}, wantRequeueMin: 7 * time.Second, wantRequeueMax: 7 * time.Second, }, @@ -650,23 +650,23 @@ func TestReconcileOne(t *testing.T) { type goldenEgressControl struct { *RPCService - resume func(context.Context, *ateapipb.ResumeActorRequest) (*ateapipb.ResumeActorResponse, error) - createPolicy func(context.Context, *ateapipb.CreateActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) - getPolicy func(context.Context, *ateapipb.GetActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) + resume func(context.Context, *ateapi.ResumeActorRequest) (*ateapi.ResumeActorResponse, error) + createPolicy func(context.Context, *ateapi.CreateActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) + getPolicy func(context.Context, *ateapi.GetActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) } -func (c *goldenEgressControl) ResumeActor(ctx context.Context, req *ateapipb.ResumeActorRequest) (*ateapipb.ResumeActorResponse, error) { +func (c *goldenEgressControl) ResumeActor(ctx context.Context, req *ateapi.ResumeActorRequest) (*ateapi.ResumeActorResponse, error) { return c.resume(ctx, req) } -func (c *goldenEgressControl) CreateActorEgressPolicy(ctx context.Context, req *ateapipb.CreateActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) { +func (c *goldenEgressControl) CreateActorEgressPolicy(ctx context.Context, req *ateapi.CreateActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) { if c.createPolicy != nil { return c.createPolicy(ctx, req) } return c.RPCService.CreateActorEgressPolicy(ctx, req) } -func (c *goldenEgressControl) GetActorEgressPolicy(ctx context.Context, req *ateapipb.GetActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) { +func (c *goldenEgressControl) GetActorEgressPolicy(ctx context.Context, req *ateapi.GetActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) { if c.getPolicy != nil { return c.getPolicy(ctx, req) } @@ -677,10 +677,10 @@ func TestReconcileOne_GoldenEgressPolicyBeforeResume(t *testing.T) { preview.InitForTest(t, "GoldenEgressPolicy") for _, tt := range []struct { name string - policy *ateapipb.EgressPolicyTemplate + policy *ateapi.EgressPolicyTemplate }{ {name: "absent"}, - {name: "configured", policy: &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{{Https: &ateapipb.HttpsRule{Hostnames: []string{"api.example.com"}}}}}}, + {name: "configured", policy: &ateapi.EgressPolicyTemplate{Rules: []*ateapi.EgressRule{{Https: &ateapi.HttpsRule{Hostnames: []string{"api.example.com"}}}}}}, } { t.Run(tt.name, func(t *testing.T) { ctx := t.Context() @@ -689,20 +689,20 @@ func TestReconcileOne_GoldenEgressPolicyBeforeResume(t *testing.T) { impl.clusterSnapshotLocation = "gs://cluster-bucket/" svc := &RPCService{impl: impl} storetest.MustCreateAtespace(t, ctx, persistence, "templates") - tmpl, err := svc.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.Metadata = &ateapipb.ResourceMetadata{Atespace: "templates", Name: "tmpl"} + tmpl, err := svc.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.Metadata = &ateapi.ResourceMetadata{Atespace: "templates", Name: "tmpl"} tmpl.GoldenEgressPolicy = tt.policy })}) if err != nil { t.Fatal(err) } stop := errors.New("stop before running workload") - control := &goldenEgressControl{RPCService: svc, resume: func(ctx context.Context, req *ateapipb.ResumeActorRequest) (*ateapipb.ResumeActorResponse, error) { + control := &goldenEgressControl{RPCService: svc, resume: func(ctx context.Context, req *ateapi.ResumeActorRequest) (*ateapi.ResumeActorResponse, error) { ref := req.GetActor() if ref.GetAtespace() != tmpl.GetMetadata().GetAtespace() || ref.GetName() != tmpl.GetMetadata().GetUid() { t.Fatalf("unexpected golden actor: %v", ref) } - policy, err := svc.GetActorEgressPolicy(ctx, &ateapipb.GetActorEgressPolicyRequest{Actor: ref, Name: resources.SingletonName}) + policy, err := svc.GetActorEgressPolicy(ctx, &ateapi.GetActorEgressPolicyRequest{Actor: ref, Name: resources.SingletonName}) if tt.policy == nil { if apierror.Code(err) != codes.NotFound { t.Fatalf("golden without configured policy: %v, want NotFound", err) @@ -712,7 +712,7 @@ func TestReconcileOne_GoldenEgressPolicyBeforeResume(t *testing.T) { if err != nil { t.Fatalf("golden policy must exist before resume: %v", err) } - want := &ateapipb.EgressPolicy{Metadata: policy.Metadata, Rules: tmpl.GetGoldenEgressPolicy().GetRules()} + want := &ateapi.EgressPolicy{Metadata: policy.Metadata, Rules: tmpl.GetGoldenEgressPolicy().GetRules()} if policy.GetMetadata().GetAtespace() != ref.GetAtespace() || policy.GetMetadata().GetName() != "default" || !proto.Equal(policy, want) { t.Fatalf("golden policy = %v, want rules %v in %s", policy, want.Rules, ref.GetAtespace()) } @@ -744,24 +744,24 @@ func TestReconcileOne_GoldenEgressPolicyRecovery(t *testing.T) { impl.clusterSnapshotLocation = "gs://cluster-bucket/" svc := &RPCService{impl: impl} storetest.MustCreateAtespace(t, ctx, persistence, "templates") - tmpl, err := svc.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) { - tmpl.Metadata = &ateapipb.ResourceMetadata{Atespace: "templates", Name: "tmpl"} - tmpl.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{ - {Https: &ateapipb.HttpsRule{Hostnames: []string{"api.example.com"}}}, + tmpl, err := svc.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { + tmpl.Metadata = &ateapi.ResourceMetadata{Atespace: "templates", Name: "tmpl"} + tmpl.GoldenEgressPolicy = &ateapi.EgressPolicyTemplate{Rules: []*ateapi.EgressRule{ + {Https: &ateapi.HttpsRule{Hostnames: []string{"api.example.com"}}}, }} })}) if err != nil { t.Fatal(err) } - ref := &ateapipb.ObjectRef{Atespace: tmpl.GetMetadata().GetAtespace(), Name: tmpl.GetMetadata().GetUid()} + ref := &ateapi.ObjectRef{Atespace: tmpl.GetMetadata().GetAtespace(), Name: tmpl.GetMetadata().GetUid()} transient := errors.New("policy service unavailable") stop := errors.New("stop before running workload") resumeCalls := 0 - control := &goldenEgressControl{RPCService: svc, resume: func(context.Context, *ateapipb.ResumeActorRequest) (*ateapipb.ResumeActorResponse, error) { + control := &goldenEgressControl{RPCService: svc, resume: func(context.Context, *ateapi.ResumeActorRequest) (*ateapi.ResumeActorResponse, error) { resumeCalls++ return nil, stop }} - control.createPolicy = func(ctx context.Context, req *ateapipb.CreateActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) { + control.createPolicy = func(ctx context.Context, req *ateapi.CreateActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) { if scenario == "create fails" { return nil, transient } @@ -777,12 +777,12 @@ func TestReconcileOne_GoldenEgressPolicyRecovery(t *testing.T) { return nil, apierror.AlreadyExists("policy exists") } if scenario == "lookup fails" { - control.getPolicy = func(context.Context, *ateapipb.GetActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) { + control.getPolicy = func(context.Context, *ateapi.GetActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) { return nil, transient } } var actorUID string - var previousPolicy *ateapipb.EgressPolicy + var previousPolicy *ateapi.EgressPolicy for pass := range 2 { // A fresh reconciler must recover from persisted state alone. r := newTestTemplateReconciler(persistence, control) @@ -821,7 +821,7 @@ func TestReconcileOne_GoldenEgressPolicyRecovery(t *testing.T) { if resumeCalls != wantResumes { t.Fatalf("resume calls = %d, want %d", resumeCalls, wantResumes) } - actor, err := svc.GetActor(ctx, &ateapipb.GetActorRequest{Actor: ref}) + actor, err := svc.GetActor(ctx, &ateapi.GetActorRequest{Actor: ref}) if err != nil { t.Fatal(err) } @@ -829,10 +829,10 @@ func TestReconcileOne_GoldenEgressPolicyRecovery(t *testing.T) { t.Fatal("retry recreated the golden actor") } actorUID = actor.GetMetadata().GetUid() - if actor.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if actor.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("actor state = %v, want SUSPENDED", actor.GetStatus().GetState()) } - policy, err := svc.GetActorEgressPolicy(ctx, &ateapipb.GetActorEgressPolicyRequest{Actor: ref, Name: resources.SingletonName}) + policy, err := svc.GetActorEgressPolicy(ctx, &ateapi.GetActorEgressPolicyRequest{Actor: ref, Name: resources.SingletonName}) if pass == 0 && scenario == "create fails" { if apierror.Code(err) != codes.NotFound { t.Fatalf("policy lookup = %v, want NotFound", err) @@ -856,11 +856,11 @@ func TestReconcileOne_GoldenEgressPolicyRecovery(t *testing.T) { control.createPolicy = nil control.getPolicy = nil if scenario == "conflicting policy" { - control.createPolicy = func(context.Context, *ateapipb.CreateActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) { + control.createPolicy = func(context.Context, *ateapi.CreateActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) { t.Fatal("retried policy creation after terminal failure") return nil, nil } - control.getPolicy = func(context.Context, *ateapipb.GetActorEgressPolicyRequest) (*ateapipb.EgressPolicy, error) { + control.getPolicy = func(context.Context, *ateapi.GetActorEgressPolicyRequest) (*ateapi.EgressPolicy, error) { t.Fatal("retried policy lookup after terminal failure") return nil, nil } @@ -905,8 +905,8 @@ func TestReconcileOne_GoldenActorRequests(t *testing.T) { if got := control.suspendReqs[0].GetActor().GetName(); got != testTemplateUID { t.Errorf("suspended actor = %q, want %q", got, testTemplateUID) } - if got := control.suspendReqs[0].GetOptions().GetMode(); got != ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS { - t.Errorf("golden suspend mode = %v, want %v", got, ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS) + if got := control.suspendReqs[0].GetOptions().GetMode(); got != ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS { + t.Errorf("golden suspend mode = %v, want %v", got, ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS) } if st.storedStatus(t, testTemplateRef).GetGoldenSnapshotStatus().GetSnapshotTime() == nil { t.Error("stored snapshot_time is nil, want set") @@ -918,7 +918,7 @@ func TestCheckpoint_TerminalStateErrors(t *testing.T) { for _, seed := range []struct { name string - opt func(*ateapipb.ActorTemplate) + opt func(*ateapi.ActorTemplate) }{ {"golden snapshot taken", withGoldenTag()}, {"failed", withFailed(reasonGoldenActorCrashed)}, @@ -929,7 +929,7 @@ func TestCheckpoint_TerminalStateErrors(t *testing.T) { // Checkpoint against a template a concurrent writer already // drove to a terminal state. - _, err := r.checkpoint(ctx, testTemplate(seed.opt), func(snapshotStatus *ateapipb.GoldenSnapshotStatus) { + _, err := r.checkpoint(ctx, testTemplate(seed.opt), func(snapshotStatus *ateapi.GoldenSnapshotStatus) { snapshotStatus.SnapshotTime = timestamppb.New(time.Now()) }) if err == nil { @@ -1020,7 +1020,7 @@ func TestFail_TruncatesErrorMessage(t *testing.T) { t.Error("error_message is not valid UTF-8") } op := apivalidation.MakeUpdateOp(ctx) - if errs := apivalidation.Validate_GoldenSnapshotStatus(ctx, op, nil, golden, &ateapipb.GoldenSnapshotStatus{}); len(errs) != 0 { + if errs := apivalidation.Validate_GoldenSnapshotStatus(ctx, op, nil, golden, &ateapi.GoldenSnapshotStatus{}); len(errs) != 0 { t.Errorf("stored status fails validation: %v", errs) } } @@ -1034,11 +1034,11 @@ func TestCheckpoint_StaleObservationConflicts(t *testing.T) { r := newTestTemplateReconciler(st, &fakeGoldenControl{}) // A concurrent writer advances the stored version past the observation. - if _, err := st.UpdateActorTemplate(ctx, testTemplateRef, store.PreconditionFrom(testTemplate()), func(*ateapipb.ActorTemplate) error { return nil }); err != nil { + if _, err := st.UpdateActorTemplate(ctx, testTemplateRef, store.PreconditionFrom(testTemplate()), func(*ateapi.ActorTemplate) error { return nil }); err != nil { t.Fatalf("seeding concurrent update failed: %v", err) } - _, err := r.checkpoint(ctx, testTemplate(), func(snapshotStatus *ateapipb.GoldenSnapshotStatus) { + _, err := r.checkpoint(ctx, testTemplate(), func(snapshotStatus *ateapi.GoldenSnapshotStatus) { snapshotStatus.SnapshotTime = timestamppb.New(time.Now()) }) if !errors.Is(err, store.ErrVersionConflict) { @@ -1067,21 +1067,21 @@ func TestResync_QueuesOnlyActionableTemplates(t *testing.T) { tests := []struct { name string - opts []func(*ateapipb.ActorTemplate) + opts []func(*ateapi.ActorTemplate) wantQueued bool }{ {"empty status", nil, true}, - {"golden snapshot disabled", []func(*ateapipb.ActorTemplate){withoutGoldenSnapshot}, false}, - {"mid warmup", []func(*ateapipb.ActorTemplate){withSnapshotDeadline(time.Now().Add(time.Hour))}, true}, - {"golden snapshot taken", []func(*ateapipb.ActorTemplate){withGoldenTag()}, false}, - {"failed", []func(*ateapipb.ActorTemplate){withFailed(reasonGoldenActorCrashed)}, false}, + {"golden snapshot disabled", []func(*ateapi.ActorTemplate){withoutGoldenSnapshot}, false}, + {"mid warmup", []func(*ateapi.ActorTemplate){withSnapshotDeadline(time.Now().Add(time.Hour))}, true}, + {"golden snapshot taken", []func(*ateapi.ActorTemplate){withGoldenTag()}, false}, + {"failed", []func(*ateapi.ActorTemplate){withFailed(reasonGoldenActorCrashed)}, false}, } // Seed one template per row, resync once, and check membership per row. templateName := func(name string) string { return "tmpl-" + strings.ReplaceAll(name, " ", "-") } - templates := make([]*ateapipb.ActorTemplate, 0, len(tests)) + templates := make([]*ateapi.ActorTemplate, 0, len(tests)) for _, tt := range tests { tmpl := testTemplate(tt.opts...) tmpl.Metadata.Name = templateName(tt.name) @@ -1107,9 +1107,9 @@ func TestResync_QueuesOnlyActionableTemplates(t *testing.T) { func TestResync_FollowsPagination(t *testing.T) { st := newFakeTemplateStore( - testTemplate(func(tmpl *ateapipb.ActorTemplate) { tmpl.Metadata.Name = "tmpl-a" }), - testTemplate(func(tmpl *ateapipb.ActorTemplate) { tmpl.Metadata.Name = "tmpl-b" }), - testTemplate(func(tmpl *ateapipb.ActorTemplate) { tmpl.Metadata.Name = "tmpl-c" }), + testTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.Metadata.Name = "tmpl-a" }), + testTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.Metadata.Name = "tmpl-b" }), + testTemplate(func(tmpl *ateapi.ActorTemplate) { tmpl.Metadata.Name = "tmpl-c" }), ) st.forcePageSize = 1 r := newTestTemplateReconciler(st, &fakeGoldenControl{}) @@ -1122,14 +1122,14 @@ func TestResync_FollowsPagination(t *testing.T) { } func TestReconcileOne_GoldenTagRecovery(t *testing.T) { - ref := &ateapipb.ObjectRef{Atespace: testTemplateRef.Atespace, Name: testTemplateUID} - completed := &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: ref.Atespace, Name: ref.Name}, + ref := &ateapi.ObjectRef{Atespace: testTemplateRef.Atespace, Name: testTemplateUID} + completed := &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: ref.Atespace, Name: ref.Name}, SourceActor: ref, - Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED, - Status: &ateapipb.TagStatus{ + Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED, + Status: &ateapi.TagStatus{ ActorTemplateUid: testTemplateUID, - Snapshot: newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, testTemplateUID, "tag-snapshot", "gs://bucket/tag-snapshot", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + Snapshot: newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, testTemplateUID, "tag-snapshot", "gs://bucket/tag-snapshot", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), }, } incomplete := proto.CloneOf(completed) @@ -1137,7 +1137,7 @@ func TestReconcileOne_GoldenTagRecovery(t *testing.T) { tests := []struct { name string // tag is the golden tag an earlier pass left behind, if any. - tag *ateapipb.Tag + tag *ateapi.Tag // actorDeleted seeds a pass that died after deleting the golden actor. actorDeleted bool // These errors fail one step of the first pass; the retry succeeds. @@ -1158,7 +1158,7 @@ func TestReconcileOne_GoldenTagRecovery(t *testing.T) { t.Run(tt.name, func(t *testing.T) { control := &fakeGoldenControl{ tag: proto.CloneOf(tt.tag), exists: !tt.actorDeleted, - goldenState: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, goldenSnapshot: "gs://bucket/actor-snapshot", + goldenState: ateapi.ActorState_ACTOR_STATE_SUSPENDED, goldenSnapshot: "gs://bucket/actor-snapshot", tagErr: tt.createTagErr, deleteErr: tt.deleteActorErr, deleteTagErr: tt.deleteTagErr, } st := newFakeTemplateStore(testTemplate()) @@ -1187,7 +1187,7 @@ func TestReconcileOne_GoldenTagRecovery(t *testing.T) { if !proto.Equal(st.storedStatus(t, testTemplateRef).GetGoldenSnapshotStatus().GetGoldenTag(), ref) { t.Fatal("golden tag not recorded") } - if tagDurableSnapshotURI(control.tag, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) == "" { + if tagDurableSnapshotURI(control.tag, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) == "" { t.Fatal("golden tag has no snapshot") } if len(control.createReqs) != 0 || len(control.resumeReqs) != 0 || len(control.suspendReqs) != 0 { @@ -1197,7 +1197,7 @@ func TestReconcileOne_GoldenTagRecovery(t *testing.T) { t.Fatalf("CreateTag calls = %d, want %d", got, tt.wantCreateTags) } for _, req := range control.tagReqs { - if !proto.Equal(req.Tag.SourceActor, ref) || req.Tag.Scope != ateapipb.TagScope_TAG_SCOPE_PUBLISHED || req.Tag.Metadata.Name != ref.Name { + if !proto.Equal(req.Tag.SourceActor, ref) || req.Tag.Scope != ateapi.TagScope_TAG_SCOPE_PUBLISHED || req.Tag.Metadata.Name != ref.Name { t.Fatalf("incorrect golden tag request: %v", req) } } @@ -1209,17 +1209,17 @@ func TestReconcileOne_GoldenTagConflict(t *testing.T) { tests := []struct { name string templateUID string - sourceActor *ateapipb.ObjectRef + sourceActor *ateapi.ObjectRef }{ - {name: "template", templateUID: "another-template", sourceActor: &ateapipb.ObjectRef{Atespace: testTemplateRef.Atespace, Name: testTemplateUID}}, - {name: "actor name", templateUID: testTemplateUID, sourceActor: &ateapipb.ObjectRef{Atespace: testTemplateRef.Atespace, Name: "another-actor"}}, - {name: "actor atespace", templateUID: testTemplateUID, sourceActor: &ateapipb.ObjectRef{Atespace: "another-atespace", Name: testTemplateUID}}, + {name: "template", templateUID: "another-template", sourceActor: &ateapi.ObjectRef{Atespace: testTemplateRef.Atespace, Name: testTemplateUID}}, + {name: "actor name", templateUID: testTemplateUID, sourceActor: &ateapi.ObjectRef{Atespace: testTemplateRef.Atespace, Name: "another-actor"}}, + {name: "actor atespace", templateUID: testTemplateUID, sourceActor: &ateapi.ObjectRef{Atespace: "another-atespace", Name: testTemplateUID}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tag := &ateapipb.Tag{ + tag := &ateapi.Tag{ SourceActor: tt.sourceActor, - Status: &ateapipb.TagStatus{ActorTemplateUid: tt.templateUID}, + Status: &ateapi.TagStatus{ActorTemplateUid: tt.templateUID}, } control := &fakeGoldenControl{tag: proto.CloneOf(tag), exists: true} st := newFakeTemplateStore(testTemplate()) diff --git a/cmd/ateapi/internal/controlapi/validate.go b/cmd/ateapi/internal/controlapi/validate.go index 50959b934a..9d7ac8759f 100644 --- a/cmd/ateapi/internal/controlapi/validate.go +++ b/cmd/ateapi/internal/controlapi/validate.go @@ -14,11 +14,11 @@ package controlapi -import "go.ate.dev/substrate/pkg/proto/ateapipb" +import "go.ate.dev/substrate/api/ateapi/v1" // scrubResourceMetadataForCreate removes fields that should not be set by the // user when creating a resource. -func scrubResourceMetadataForCreate(in *ateapipb.ResourceMetadata) { +func scrubResourceMetadataForCreate(in *ateapi.ResourceMetadata) { if in == nil { return // validation will flag it } @@ -31,7 +31,7 @@ func scrubResourceMetadataForCreate(in *ateapipb.ResourceMetadata) { // scrubResourceMetadataForUpdate removes fields that should not be set by the // user when updating a resource. -func scrubResourceMetadataForUpdate(in *ateapipb.ResourceMetadata) { +func scrubResourceMetadataForUpdate(in *ateapi.ResourceMetadata) { if in == nil { return // validation will flag it } diff --git a/cmd/ateapi/internal/controlapi/volumes.go b/cmd/ateapi/internal/controlapi/volumes.go index 218958cfc9..cba6f37f82 100644 --- a/cmd/ateapi/internal/controlapi/volumes.go +++ b/cmd/ateapi/internal/controlapi/volumes.go @@ -20,9 +20,9 @@ import ( "fmt" "log/slog" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/volume" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -31,20 +31,20 @@ import ( // externalVolumesStatus wraps vols for ActorStatus, leaving the field unset // when the actor has no external volumes. -func externalVolumesStatus(vols []*ateapipb.ExternalVolumeStatus) *ateapipb.ExternalVolumes { +func externalVolumesStatus(vols []*ateapi.ExternalVolumeStatus) *ateapi.ExternalVolumes { if len(vols) == 0 { return nil } - return &ateapipb.ExternalVolumes{Volumes: vols} + return &ateapi.ExternalVolumes{Volumes: vols} } // initialExternalVolumes constructs the actor's volume objects before volume // creation. A volume has no storage volume ID until it is provisioned. -func initialExternalVolumes(ctx context.Context, scLister storagev1listers.StorageClassLister, template *ateapipb.ActorTemplate) ([]*ateapipb.ExternalVolumeStatus, error) { +func initialExternalVolumes(ctx context.Context, scLister storagev1listers.StorageClassLister, template *ateapi.ActorTemplate) ([]*ateapi.ExternalVolumeStatus, error) { if template == nil { return nil, apierror.InvalidArgument("template is required") } - var volumes []*ateapipb.ExternalVolumeStatus + var volumes []*ateapi.ExternalVolumeStatus for _, vol := range template.GetVolumes() { if vol.GetExternal().GetTemplate() != nil { scName := vol.GetExternal().GetTemplate().GetStorageClassName() @@ -56,7 +56,7 @@ func initialExternalVolumes(ctx context.Context, scLister storagev1listers.Stora return nil, apierror.Internal("failed to get StorageClass %q: %v", scName, err) } - volumes = append(volumes, &ateapipb.ExternalVolumeStatus{ + volumes = append(volumes, &ateapi.ExternalVolumeStatus{ Name: vol.GetName(), VolumeType: sc.Provisioner, }) @@ -68,8 +68,8 @@ func initialExternalVolumes(ctx context.Context, scLister storagev1listers.Stora // createActorVolumes provisions the external volumes in volumesToCreate that have no storage volume ID, using the provided volume plugin. // It returns the list of external volumes (with storage IDs), or an error if any creation fails. // Any volumes processed before or during a failure are returned alongside the error so they can be persisted on the actor. -func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, scLister storagev1listers.StorageClassLister, actorUID string, template *ateapipb.ActorTemplate, volumesToCreate []*ateapipb.ExternalVolumeStatus) (resultVolumes []*ateapipb.ExternalVolumeStatus, err error) { - resultVolumes = make([]*ateapipb.ExternalVolumeStatus, 0, len(volumesToCreate)) +func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, scLister storagev1listers.StorageClassLister, actorUID string, template *ateapi.ActorTemplate, volumesToCreate []*ateapi.ExternalVolumeStatus) (resultVolumes []*ateapi.ExternalVolumeStatus, err error) { + resultVolumes = make([]*ateapi.ExternalVolumeStatus, 0, len(volumesToCreate)) var currentIdx int defer func() { @@ -83,7 +83,7 @@ func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, scLi for idx, vol := range volumesToCreate { currentIdx = idx - var specVol *ateapipb.Volume + var specVol *ateapi.Volume volName := vol.GetName() for _, tVol := range template.GetVolumes() { if tVol.GetName() == volName { @@ -134,7 +134,7 @@ func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, scLi return resultVolumes, apierror.Internal("volume plugin returned no ID for volume %q", specVol.GetName()) } - resultVolumes = append(resultVolumes, &ateapipb.ExternalVolumeStatus{ + resultVolumes = append(resultVolumes, &ateapi.ExternalVolumeStatus{ Name: volName, StorageVolumeId: resp.VolumeID, VolumeType: sc.Provisioner, @@ -145,7 +145,7 @@ func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, scLi } // deleteActorVolumes deletes all external volumes in the list. -func deleteActorVolumes(ctx context.Context, registry VolumePluginRegistry, actorUID string, volumes []*ateapipb.ExternalVolumeStatus) error { +func deleteActorVolumes(ctx context.Context, registry VolumePluginRegistry, actorUID string, volumes []*ateapi.ExternalVolumeStatus) error { if actorUID == "" { return errors.New("actorUID is required") } @@ -177,11 +177,11 @@ func deleteActorVolumes(ctx context.Context, registry VolumePluginRegistry, acto } // getMountedActorVolumes filters the actor's volumes and returns only those that are declared and mounted in the ActorTemplate. -func getMountedActorVolumes(ctx context.Context, ref *ateapipb.ObjectRef, volumes []*ateapipb.ExternalVolumeStatus, template *ateapipb.ActorTemplate) []*ateapipb.ExternalVolumeStatus { - var mounted []*ateapipb.ExternalVolumeStatus +func getMountedActorVolumes(ctx context.Context, ref *ateapi.ObjectRef, volumes []*ateapi.ExternalVolumeStatus, template *ateapi.ActorTemplate) []*ateapi.ExternalVolumeStatus { + var mounted []*ateapi.ExternalVolumeStatus for _, vol := range volumes { // Find the corresponding volume in the ActorTemplate to check if it's mounted - var matchedTemplateVol *ateapipb.Volume + var matchedTemplateVol *ateapi.Volume for _, tVol := range template.GetVolumes() { if vol.GetName() == tVol.GetName() { matchedTemplateVol = tVol @@ -208,14 +208,14 @@ func actorVolumeID(actorUID string, volumeName string) string { } // detachActorVolumes detaches all mounted external volumes for an actor from its assigned node. -func detachActorVolumes(ctx context.Context, registry VolumePluginRegistry, actor *ateapipb.Actor, template *ateapipb.ActorTemplate, action string) error { +func detachActorVolumes(ctx context.Context, registry VolumePluginRegistry, actor *ateapi.Actor, template *ateapi.ActorTemplate, action string) error { node := actor.GetStatus().GetAssignedNode() if node == "" { slog.WarnContext(ctx, fmt.Sprintf("Actor has no assigned node during %s, skipping detach volumes", action), slog.String("actor_id", actor.GetMetadata().GetName())) return nil } - ref := &ateapipb.ObjectRef{Atespace: actor.GetMetadata().GetAtespace(), Name: actor.GetMetadata().GetName()} + ref := &ateapi.ObjectRef{Atespace: actor.GetMetadata().GetAtespace(), Name: actor.GetMetadata().GetName()} // If the template is available, only detach volumes that are actively mounted // in the template's containers. If the template is missing/deleted, fall back to // attempting detachment for all external volumes recorded on the actor so we do diff --git a/cmd/ateapi/internal/controlapi/volumes_test.go b/cmd/ateapi/internal/controlapi/volumes_test.go index 496ba31ca2..6fc05a620a 100644 --- a/cmd/ateapi/internal/controlapi/volumes_test.go +++ b/cmd/ateapi/internal/controlapi/volumes_test.go @@ -26,9 +26,9 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/testing/protocmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/volume" - "go.ate.dev/substrate/pkg/proto/ateapipb" storagev1 "k8s.io/api/storage/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -60,15 +60,15 @@ var _ storagev1listers.StorageClassLister = (*fakeStorageClassLister)(nil) func TestActorVolumesStorageClassErrors(t *testing.T) { ctx := context.Background() - tmpl := &ateapipb.ActorTemplate{ - Volumes: []*ateapipb.Volume{{ + tmpl := &ateapi.ActorTemplate{ + Volumes: []*ateapi.Volume{{ Name: "data-vol", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", }}, }}, } - volumes := []*ateapipb.ExternalVolumeStatus{{ + volumes := []*ateapi.ExternalVolumeStatus{{ Name: "data-vol", VolumeType: "mock-standard", }} @@ -116,11 +116,11 @@ func TestActorVolumesStorageClassErrors(t *testing.T) { } func TestInitialActorVolumes(t *testing.T) { - tmpl := &ateapipb.ActorTemplate{ - Volumes: []*ateapipb.Volume{ + tmpl := &ateapi.ActorTemplate{ + Volumes: []*ateapi.Volume{ { Name: "data-vol-1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", }}, }, @@ -129,18 +129,18 @@ func TestInitialActorVolumes(t *testing.T) { }, { Name: "durable-vol", - DurableDir: &ateapipb.DurableDirVolumeSource{}, + DurableDir: &ateapi.DurableDirVolumeSource{}, }, { Name: "data-vol-2", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "fast", }}, }, }, } - want := []*ateapipb.ExternalVolumeStatus{ + want := []*ateapi.ExternalVolumeStatus{ { Name: "data-vol-1", VolumeType: "mock-standard", @@ -175,34 +175,34 @@ func TestInitialActorVolumes(t *testing.T) { func TestCreateActorVolumes(t *testing.T) { ctx := context.Background() - standardTmpl := &ateapipb.ActorTemplate{ - Volumes: []*ateapipb.Volume{ + standardTmpl := &ateapi.ActorTemplate{ + Volumes: []*ateapi.Volume{ { Name: "data-vol", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", }}, }, }, } - multiVolTmpl := &ateapipb.ActorTemplate{ - Volumes: []*ateapipb.Volume{ + multiVolTmpl := &ateapi.ActorTemplate{ + Volumes: []*ateapi.Volume{ { Name: "vol1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", }}, }, { Name: "vol2", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", }}, }, { Name: "vol3", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "standard", }}, }, @@ -211,23 +211,23 @@ func TestCreateActorVolumes(t *testing.T) { tests := []struct { name string - tmpl *ateapipb.ActorTemplate - inputVolumes []*ateapipb.ExternalVolumeStatus + tmpl *ateapi.ActorTemplate + inputVolumes []*ateapi.ExternalVolumeStatus storageClasses map[string]*storagev1.StorageClass wantErr bool - wantRes []*ateapipb.ExternalVolumeStatus + wantRes []*ateapi.ExternalVolumeStatus }{ { name: "partial failure returns error and preserves succeeded, failed, and remaining volumes", tmpl: multiVolTmpl, - inputVolumes: []*ateapipb.ExternalVolumeStatus{ + inputVolumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol1", VolumeType: "mock-standard"}, // Its type differs from its StorageClass's provisioner, so creating it fails. {Name: "vol2", VolumeType: "mock-fast"}, {Name: "vol3", VolumeType: "mock-standard"}, }, wantErr: true, - wantRes: []*ateapipb.ExternalVolumeStatus{ + wantRes: []*ateapi.ExternalVolumeStatus{ { Name: "vol1", StorageVolumeId: "mock-vol-substrate-actor-uid-123-vol1", @@ -240,14 +240,14 @@ func TestCreateActorVolumes(t *testing.T) { { name: "volume with a storage volume id is not created again", tmpl: standardTmpl, - inputVolumes: []*ateapipb.ExternalVolumeStatus{ + inputVolumes: []*ateapi.ExternalVolumeStatus{ { Name: "data-vol", StorageVolumeId: "existing-vol-id", }, }, wantErr: false, - wantRes: []*ateapipb.ExternalVolumeStatus{ + wantRes: []*ateapi.ExternalVolumeStatus{ { Name: "data-vol", StorageVolumeId: "existing-vol-id", @@ -256,19 +256,19 @@ func TestCreateActorVolumes(t *testing.T) { }, { name: "volume not found in template returns error", - tmpl: &ateapipb.ActorTemplate{}, - inputVolumes: []*ateapipb.ExternalVolumeStatus{ + tmpl: &ateapi.ActorTemplate{}, + inputVolumes: []*ateapi.ExternalVolumeStatus{ {Name: "missing-vol"}, }, wantErr: true, - wantRes: []*ateapipb.ExternalVolumeStatus{ + wantRes: []*ateapi.ExternalVolumeStatus{ {Name: "missing-vol"}, }, }, { name: "storage class parameters are propagated to volume context", tmpl: standardTmpl, - inputVolumes: []*ateapipb.ExternalVolumeStatus{ + inputVolumes: []*ateapi.ExternalVolumeStatus{ { Name: "data-vol", VolumeType: "mock-standard", @@ -285,7 +285,7 @@ func TestCreateActorVolumes(t *testing.T) { }, }, wantErr: false, - wantRes: []*ateapipb.ExternalVolumeStatus{ + wantRes: []*ateapi.ExternalVolumeStatus{ { Name: "data-vol", StorageVolumeId: "mock-vol-substrate-actor-uid-123-data-vol", @@ -343,10 +343,10 @@ func (emptyIDVolumePlugin) CreateVolume(context.Context, volume.CreateVolumeRequ } func TestCreateActorVolumesRejectsEmptyPluginID(t *testing.T) { - tmpl := &ateapipb.ActorTemplate{ - Volumes: []*ateapipb.Volume{{ + tmpl := &ateapi.ActorTemplate{ + Volumes: []*ateapi.Volume{{ Name: "data-vol", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{StorageClassName: "standard"}}, + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "standard"}}, }}, } registry := &mockPluginRegistry{ @@ -355,7 +355,7 @@ func TestCreateActorVolumesRejectsEmptyPluginID(t *testing.T) { scLister := &fakeStorageClassLister{storageClasses: map[string]*storagev1.StorageClass{ "standard": {ObjectMeta: metav1.ObjectMeta{Name: "standard"}, Provisioner: "mock-standard"}, }} - input := []*ateapipb.ExternalVolumeStatus{{Name: "data-vol", VolumeType: "mock-standard"}} + input := []*ateapi.ExternalVolumeStatus{{Name: "data-vol", VolumeType: "mock-standard"}} res, err := createActorVolumes(context.Background(), registry, scLister, "actor-uid-123", tmpl, input) if got := apierror.Code(err); got != codes.Internal { @@ -383,14 +383,14 @@ func TestDeleteActorVolumes(t *testing.T) { tests := []struct { name string actorUID string - volumes []*ateapipb.ExternalVolumeStatus + volumes []*ateapi.ExternalVolumeStatus wantDeleted []string wantErr bool }{ { name: "uses storage volume ID when present", actorUID: "uid-abc", - volumes: []*ateapipb.ExternalVolumeStatus{ + volumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol1", StorageVolumeId: "storage-vol-123", VolumeType: "mock"}, }, wantDeleted: []string{"storage-vol-123"}, @@ -399,7 +399,7 @@ func TestDeleteActorVolumes(t *testing.T) { { name: "falls back to actorVolumeID when storage volume ID is empty", actorUID: "uid-abc", - volumes: []*ateapipb.ExternalVolumeStatus{ + volumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol1", StorageVolumeId: "", VolumeType: "mock"}, }, wantDeleted: []string{"substrate-uid-abc-vol1"}, @@ -465,8 +465,8 @@ func TestDetachActorVolumes(t *testing.T) { tests := []struct { name string - actor *ateapipb.Actor - template *ateapipb.ActorTemplate + actor *ateapi.Actor + template *ateapi.ActorTemplate plugin *mockDetachVolumePlugin pluginRegistry *mockPluginRegistry wantDetachCalls []detachCall @@ -475,24 +475,24 @@ func TestDetachActorVolumes(t *testing.T) { }{ { name: "success with multiple mounted volumes", - actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "actor-1", Atespace: "default"}, - Status: &ateapipb.ActorStatus{ + actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "actor-1", Atespace: "default"}, + Status: &ateapi.ActorStatus{ AssignedNode: "node-1", - ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{ + ExternalVolumes: &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol1", StorageVolumeId: "storage-vol-1", VolumeType: "mock"}, {Name: "vol2", StorageVolumeId: "storage-vol-2", VolumeType: "mock"}, }}, }, }, - template: &ateapipb.ActorTemplate{ - Volumes: []*ateapipb.Volume{ + template: &ateapi.ActorTemplate{ + Volumes: []*ateapi.Volume{ {Name: "vol1"}, {Name: "vol2"}, }, - Containers: []*ateapipb.Container{ + Containers: []*ateapi.Container{ { - VolumeMounts: []*ateapipb.VolumeMount{ + VolumeMounts: []*ateapi.VolumeMount{ {Name: "vol1"}, {Name: "vol2"}, }, @@ -506,24 +506,24 @@ func TestDetachActorVolumes(t *testing.T) { }, { name: "skips unmounted volume in template", - actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "actor-1", Atespace: "default"}, - Status: &ateapipb.ActorStatus{ + actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "actor-1", Atespace: "default"}, + Status: &ateapi.ActorStatus{ AssignedNode: "node-1", - ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{ + ExternalVolumes: &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{ {Name: "mounted-vol", StorageVolumeId: "storage-vol-mounted", VolumeType: "mock"}, {Name: "unmounted-vol", StorageVolumeId: "storage-vol-unmounted", VolumeType: "mock"}, }}, }, }, - template: &ateapipb.ActorTemplate{ - Volumes: []*ateapipb.Volume{ + template: &ateapi.ActorTemplate{ + Volumes: []*ateapi.Volume{ {Name: "mounted-vol"}, {Name: "unmounted-vol"}, }, - Containers: []*ateapipb.Container{ + Containers: []*ateapi.Container{ { - VolumeMounts: []*ateapipb.VolumeMount{ + VolumeMounts: []*ateapi.VolumeMount{ {Name: "mounted-vol"}, }, }, @@ -535,24 +535,24 @@ func TestDetachActorVolumes(t *testing.T) { }, { name: "skips volume with empty StorageVolumeId", - actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "actor-1", Atespace: "default"}, - Status: &ateapipb.ActorStatus{ + actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "actor-1", Atespace: "default"}, + Status: &ateapi.ActorStatus{ AssignedNode: "node-1", - ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{ + ExternalVolumes: &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol1", StorageVolumeId: "", VolumeType: "mock"}, {Name: "vol2", StorageVolumeId: "storage-vol-2", VolumeType: "mock"}, }}, }, }, - template: &ateapipb.ActorTemplate{ - Volumes: []*ateapipb.Volume{ + template: &ateapi.ActorTemplate{ + Volumes: []*ateapi.Volume{ {Name: "vol1"}, {Name: "vol2"}, }, - Containers: []*ateapipb.Container{ + Containers: []*ateapi.Container{ { - VolumeMounts: []*ateapipb.VolumeMount{ + VolumeMounts: []*ateapi.VolumeMount{ {Name: "vol1"}, {Name: "vol2"}, }, @@ -565,11 +565,11 @@ func TestDetachActorVolumes(t *testing.T) { }, { name: "nil template falls back to detaching all actor volumes", - actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "actor-1", Atespace: "default"}, - Status: &ateapipb.ActorStatus{ + actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "actor-1", Atespace: "default"}, + Status: &ateapi.ActorStatus{ AssignedNode: "node-1", - ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{ + ExternalVolumes: &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol1", StorageVolumeId: "storage-vol-1", VolumeType: "mock"}, {Name: "vol2", StorageVolumeId: "storage-vol-2", VolumeType: "mock"}, }}, @@ -583,11 +583,11 @@ func TestDetachActorVolumes(t *testing.T) { }, { name: "codes.NotFound from plugin is treated as already detached", - actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "actor-1", Atespace: "default"}, - Status: &ateapipb.ActorStatus{ + actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "actor-1", Atespace: "default"}, + Status: &ateapi.ActorStatus{ AssignedNode: "node-1", - ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{ + ExternalVolumes: &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol1", StorageVolumeId: "storage-vol-1", VolumeType: "mock"}, }}, }, @@ -604,11 +604,11 @@ func TestDetachActorVolumes(t *testing.T) { }, { name: "partial failure attempts all volumes and joins errors", - actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "actor-1", Atespace: "default"}, - Status: &ateapipb.ActorStatus{ + actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "actor-1", Atespace: "default"}, + Status: &ateapi.ActorStatus{ AssignedNode: "node-1", - ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{ + ExternalVolumes: &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol1", StorageVolumeId: "storage-vol-1", VolumeType: "mock"}, {Name: "vol2", StorageVolumeId: "storage-vol-2", VolumeType: "mock"}, }}, @@ -628,11 +628,11 @@ func TestDetachActorVolumes(t *testing.T) { }, { name: "unknown plugin returns error", - actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "actor-1", Atespace: "default"}, - Status: &ateapipb.ActorStatus{ + actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "actor-1", Atespace: "default"}, + Status: &ateapi.ActorStatus{ AssignedNode: "node-1", - ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{ + ExternalVolumes: &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol1", StorageVolumeId: "storage-vol-1", VolumeType: "unknown-plugin"}, }}, }, @@ -642,11 +642,11 @@ func TestDetachActorVolumes(t *testing.T) { }, { name: "no assigned node skips detach", - actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "actor-1", Atespace: "default"}, - Status: &ateapipb.ActorStatus{ + actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "actor-1", Atespace: "default"}, + Status: &ateapi.ActorStatus{ AssignedNode: "", - ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{ + ExternalVolumes: &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol1", StorageVolumeId: "storage-vol-1", VolumeType: "mock"}, }}, }, diff --git a/cmd/ateapi/internal/controlapi/worker.go b/cmd/ateapi/internal/controlapi/worker.go index 660d2fa92e..f6a95baef4 100644 --- a/cmd/ateapi/internal/controlapi/worker.go +++ b/cmd/ateapi/internal/controlapi/worker.go @@ -19,12 +19,12 @@ import ( "errors" "fmt" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/defaults" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" "k8s.io/apimachinery/pkg/util/validation/field" ) @@ -32,7 +32,7 @@ import ( // ListWorkerActorAssignments lists the Actors a Worker hosts. The assignments are a // subresource rather than a field on Worker, so this is the only way to read // them and neither GetWorker nor ListWorkers grows with occupancy. -func (s *RPCService) ListWorkerActorAssignments(ctx context.Context, req *ateapipb.ListWorkerActorAssignmentsRequest) (*ateapipb.ListWorkerActorAssignmentsResponse, error) { +func (s *RPCService) ListWorkerActorAssignments(ctx context.Context, req *ateapi.ListWorkerActorAssignmentsRequest) (*ateapi.ListWorkerActorAssignmentsResponse, error) { if errs := apivalidation.ValidateListWorkerActorAssignmentsRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -52,13 +52,13 @@ func (s *RPCService) ListWorkerActorAssignments(ctx context.Context, req *ateapi if err != nil { return nil, mapListError(fmt.Errorf("while listing the assignments of worker %s: %w", name, err)) } - return &ateapipb.ListWorkerActorAssignmentsResponse{ + return &ateapi.ListWorkerActorAssignmentsResponse{ ActorAssignments: page.Items, NextPageToken: page.NextPageToken, }, nil } -func (s *RPCService) ListWorkers(ctx context.Context, req *ateapipb.ListWorkersRequest) (*ateapipb.ListWorkersResponse, error) { +func (s *RPCService) ListWorkers(ctx context.Context, req *ateapi.ListWorkersRequest) (*ateapi.ListWorkersResponse, error) { if errs := apivalidation.ValidateListWorkersRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -67,17 +67,17 @@ func (s *RPCService) ListWorkers(ctx context.Context, req *ateapipb.ListWorkersR if err != nil { return nil, mapListError(fmt.Errorf("while listing workers in db: %w", err)) } - return &ateapipb.ListWorkersResponse{ + return &ateapi.ListWorkersResponse{ Workers: page.Items, NextPageToken: page.NextPageToken, }, nil } -func (s *ServiceImpl) ListWorkers(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapipb.Worker], error) { +func (s *ServiceImpl) ListWorkers(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapi.Worker], error) { return s.store.ListWorkers(ctx, opts) } -func (s *RPCService) GetWorker(ctx context.Context, req *ateapipb.GetWorkerRequest) (*ateapipb.Worker, error) { +func (s *RPCService) GetWorker(ctx context.Context, req *ateapi.GetWorkerRequest) (*ateapi.Worker, error) { if errs := apivalidation.ValidateGetWorkerRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -97,11 +97,11 @@ func (s *RPCService) GetWorker(ctx context.Context, req *ateapipb.GetWorkerReque // the assignments are their own records. The one read that pays O(assignments). // A failed read is an error, not a Worker reported as hosting nothing: the // caller cannot tell those apart. -func (s *ServiceImpl) GetWorker(ctx context.Context, name string) (*ateapipb.Worker, error) { +func (s *ServiceImpl) GetWorker(ctx context.Context, name string) (*ateapi.Worker, error) { return s.store.GetWorker(ctx, name) } -func (s *RPCService) CreateWorker(ctx context.Context, req *ateapipb.CreateWorkerRequest) (*ateapipb.Worker, error) { +func (s *RPCService) CreateWorker(ctx context.Context, req *ateapi.CreateWorkerRequest) (*ateapi.Worker, error) { // First scrub any fields that callers are not allowed to set. status is // output-only, so whatever the request carried there is replaced rather // than rejected. @@ -121,11 +121,11 @@ func (s *RPCService) CreateWorker(ctx context.Context, req *ateapipb.CreateWorke return s.impl.CreateWorker(ctx, inWorker) } -func (s *ServiceImpl) CreateWorker(ctx context.Context, inWorker *ateapipb.Worker) (*ateapipb.Worker, error) { +func (s *ServiceImpl) CreateWorker(ctx context.Context, inWorker *ateapi.Worker) (*ateapi.Worker, error) { // A Worker takes no Actors until MarkWorkerAvailable. outWorker := proto.CloneOf(inWorker) - outWorker.Status = &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE, + outWorker.Status = &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_UNAVAILABLE, } // Verify that the result is properly valid before storing it. @@ -150,7 +150,7 @@ func (s *ServiceImpl) CreateWorker(ctx context.Context, inWorker *ateapipb.Worke // rejected. // The service layer enforces that with declarative validation against the // stored worker inside the update transaction. -func (s *RPCService) UpdateWorker(ctx context.Context, req *ateapipb.UpdateWorkerRequest) (*ateapipb.Worker, error) { +func (s *RPCService) UpdateWorker(ctx context.Context, req *ateapi.UpdateWorkerRequest) (*ateapi.Worker, error) { // First scrub any fields that callers are not allowed to set. inWorker := req.Worker if inWorker != nil { // otherwise validation will flag it @@ -163,7 +163,7 @@ func (s *RPCService) UpdateWorker(ctx context.Context, req *ateapipb.UpdateWorke return nil, resources.ToAPIError(errs) } - return s.mutateWorker(ctx, inWorker.GetMetadata().GetName(), store.PreconditionFrom(inWorker), func(toUpdate *ateapipb.Worker) error { + return s.mutateWorker(ctx, inWorker.GetMetadata().GetName(), store.PreconditionFrom(inWorker), func(toUpdate *ateapi.Worker) error { // Status and metadata are server-owned fields. status, metadata := toUpdate.GetStatus(), toUpdate.GetMetadata() // Reset + merge from the input worker. @@ -179,8 +179,8 @@ func (s *RPCService) UpdateWorker(ctx context.Context, req *ateapipb.UpdateWorke }) } -func (s *ServiceImpl) UpdateWorker(ctx context.Context, name string, precondition store.Precondition, mutate func(toUpdate *ateapipb.Worker) error) (*ateapipb.Worker, error) { - return s.store.UpdateWorker(ctx, name, precondition, func(toUpdate *ateapipb.Worker) error { +func (s *ServiceImpl) UpdateWorker(ctx context.Context, name string, precondition store.Precondition, mutate func(toUpdate *ateapi.Worker) error) (*ateapi.Worker, error) { + return s.store.UpdateWorker(ctx, name, precondition, func(toUpdate *ateapi.Worker) error { // Apply the mutation function to the stored value. oldVal := proto.CloneOf(toUpdate) if err := mutate(toUpdate); err != nil { @@ -209,19 +209,19 @@ func (s *ServiceImpl) UpdateWorker(ctx context.Context, name string, preconditio // The assignment operations are pass-throughs: an assignment is its own record, // so binding and releasing are single store calls rather than a read-modify-write // of the Worker. -func (s *ServiceImpl) BindActorToWorker(ctx context.Context, workerName string, assignment *ateapipb.ActorAssignment, admit func(*ateapipb.Worker) error) error { +func (s *ServiceImpl) BindActorToWorker(ctx context.Context, workerName string, assignment *ateapi.ActorAssignment, admit func(*ateapi.Worker) error) error { return s.store.BindActorToWorker(ctx, workerName, assignment, admit) } -func (s *ServiceImpl) ReleaseActorFromWorker(ctx context.Context, workerName string, actorUID string) (*ateapipb.Worker, error) { +func (s *ServiceImpl) ReleaseActorFromWorker(ctx context.Context, workerName string, actorUID string) (*ateapi.Worker, error) { return s.store.ReleaseActorFromWorker(ctx, workerName, actorUID) } -func (s *ServiceImpl) GetWorkerAssignment(ctx context.Context, workerName, actorUID string) (*ateapipb.ActorAssignment, error) { +func (s *ServiceImpl) GetWorkerAssignment(ctx context.Context, workerName, actorUID string) (*ateapi.ActorAssignment, error) { return s.store.GetWorkerAssignment(ctx, workerName, actorUID) } -func (s *ServiceImpl) ListWorkerAssignments(ctx context.Context, workerName string, opts store.ListOptions) (store.ListResponse[*ateapipb.ActorAssignment], error) { +func (s *ServiceImpl) ListWorkerAssignments(ctx context.Context, workerName string, opts store.ListOptions) (store.ListResponse[*ateapi.ActorAssignment], error) { return s.store.ListWorkerAssignments(ctx, workerName, opts) } @@ -229,7 +229,7 @@ func (s *ServiceImpl) FindWorkerHostingActor(ctx context.Context, actorUID strin return s.store.FindWorkerHostingActor(ctx, actorUID) } -func (s *RPCService) DeleteWorker(ctx context.Context, req *ateapipb.DeleteWorkerRequest) (*ateapipb.Worker, error) { +func (s *RPCService) DeleteWorker(ctx context.Context, req *ateapi.DeleteWorkerRequest) (*ateapi.Worker, error) { if errs := apivalidation.ValidateDeleteWorkerRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -238,24 +238,24 @@ func (s *RPCService) DeleteWorker(ctx context.Context, req *ateapipb.DeleteWorke return s.workerWorkflow.DeleteWorker(ctx, req.GetWorker().GetName(), toDeletePreconditions(req.GetOptions())) } -func (s *ServiceImpl) MarkWorkerForDeletion(ctx context.Context, name string, precondition store.DeletePreconditions, mutate func(*ateapipb.Worker) error) (*ateapipb.Worker, error) { +func (s *ServiceImpl) MarkWorkerForDeletion(ctx context.Context, name string, precondition store.DeletePreconditions, mutate func(*ateapi.Worker) error) (*ateapi.Worker, error) { return s.store.MarkWorkerForDeletion(ctx, name, precondition, mutate) } -func (s *ServiceImpl) DeleteWorker(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapipb.Worker, error) { +func (s *ServiceImpl) DeleteWorker(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.Worker, error) { return s.store.DeleteWorker(ctx, name, precondition) } -func (s *RPCService) DrainWorker(ctx context.Context, req *ateapipb.DrainWorkerRequest) (*ateapipb.DrainWorkerResponse, error) { +func (s *RPCService) DrainWorker(ctx context.Context, req *ateapi.DrainWorkerRequest) (*ateapi.DrainWorkerResponse, error) { if errs := apivalidation.ValidateDrainWorkerRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } - drained, err := s.mutateNamedWorker(ctx, req.GetWorker().GetName(), func(toUpdate *ateapipb.Worker) error { - if toUpdate.GetStatus().GetState() == ateapipb.WorkerState_WORKER_STATE_DRAINING { + drained, err := s.mutateNamedWorker(ctx, req.GetWorker().GetName(), func(toUpdate *ateapi.Worker) error { + if toUpdate.GetStatus().GetState() == ateapi.WorkerState_WORKER_STATE_DRAINING { // already draining, do nothing - return &workerUnchanged{worker: proto.Clone(toUpdate).(*ateapipb.Worker)} + return &workerUnchanged{worker: proto.Clone(toUpdate).(*ateapi.Worker)} } - toUpdate.Status.State = ateapipb.WorkerState_WORKER_STATE_DRAINING + toUpdate.Status.State = ateapi.WorkerState_WORKER_STATE_DRAINING // The assignments are left alone: a draining Worker keeps its Actors // until something releases them. Draining only stops new placements. return nil @@ -263,48 +263,48 @@ func (s *RPCService) DrainWorker(ctx context.Context, req *ateapipb.DrainWorkerR if err != nil { return nil, err } - return &ateapipb.DrainWorkerResponse{Worker: drained}, nil + return &ateapi.DrainWorkerResponse{Worker: drained}, nil } -func (s *RPCService) MarkWorkerAvailable(ctx context.Context, req *ateapipb.MarkWorkerAvailableRequest) (*ateapipb.MarkWorkerAvailableResponse, error) { +func (s *RPCService) MarkWorkerAvailable(ctx context.Context, req *ateapi.MarkWorkerAvailableRequest) (*ateapi.MarkWorkerAvailableResponse, error) { if errs := apivalidation.ValidateMarkWorkerAvailableRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } - marked, err := s.mutateNamedWorker(ctx, req.GetWorker().GetName(), func(toUpdate *ateapipb.Worker) error { + marked, err := s.mutateNamedWorker(ctx, req.GetWorker().GetName(), func(toUpdate *ateapi.Worker) error { switch toUpdate.GetStatus().GetState() { - case ateapipb.WorkerState_WORKER_STATE_ACTIVE: - return &workerUnchanged{worker: proto.Clone(toUpdate).(*ateapipb.Worker)} - case ateapipb.WorkerState_WORKER_STATE_DRAINING: + case ateapi.WorkerState_WORKER_STATE_ACTIVE: + return &workerUnchanged{worker: proto.Clone(toUpdate).(*ateapi.Worker)} + case ateapi.WorkerState_WORKER_STATE_DRAINING: return errWorkerDraining } - toUpdate.Status.State = ateapipb.WorkerState_WORKER_STATE_ACTIVE + toUpdate.Status.State = ateapi.WorkerState_WORKER_STATE_ACTIVE return nil }) if err != nil { return nil, err } - return &ateapipb.MarkWorkerAvailableResponse{Worker: marked}, nil + return &ateapi.MarkWorkerAvailableResponse{Worker: marked}, nil } -func (s *RPCService) MarkWorkerUnavailable(ctx context.Context, req *ateapipb.MarkWorkerUnavailableRequest) (*ateapipb.MarkWorkerUnavailableResponse, error) { +func (s *RPCService) MarkWorkerUnavailable(ctx context.Context, req *ateapi.MarkWorkerUnavailableRequest) (*ateapi.MarkWorkerUnavailableResponse, error) { if errs := apivalidation.ValidateMarkWorkerUnavailableRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } - marked, err := s.mutateNamedWorker(ctx, req.GetWorker().GetName(), func(toUpdate *ateapipb.Worker) error { + marked, err := s.mutateNamedWorker(ctx, req.GetWorker().GetName(), func(toUpdate *ateapi.Worker) error { switch toUpdate.GetStatus().GetState() { - case ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE: - return &workerUnchanged{worker: proto.Clone(toUpdate).(*ateapipb.Worker)} - case ateapipb.WorkerState_WORKER_STATE_DRAINING: + case ateapi.WorkerState_WORKER_STATE_UNAVAILABLE: + return &workerUnchanged{worker: proto.Clone(toUpdate).(*ateapi.Worker)} + case ateapi.WorkerState_WORKER_STATE_DRAINING: return errWorkerDraining } - toUpdate.Status.State = ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE + toUpdate.Status.State = ateapi.WorkerState_WORKER_STATE_UNAVAILABLE // The assignments are left alone, as for draining. return nil }) if err != nil { return nil, err } - return &ateapipb.MarkWorkerUnavailableResponse{Worker: marked}, nil + return &ateapi.MarkWorkerUnavailableResponse{Worker: marked}, nil } // errWorkerDraining refuses to move a draining Worker out of DRAINING, which @@ -315,7 +315,7 @@ var errWorkerDraining = errors.New("worker is draining") // carries no guards, so the ones the store requires come from a read here // rather than from the client. A write that lands in between is reported as a // conflict for the caller to retry, the same as any other guarded update. -func (s *RPCService) mutateNamedWorker(ctx context.Context, name string, mutate func(toUpdate *ateapipb.Worker) error) (*ateapipb.Worker, error) { +func (s *RPCService) mutateNamedWorker(ctx context.Context, name string, mutate func(toUpdate *ateapi.Worker) error) (*ateapi.Worker, error) { observed, err := s.impl.GetWorker(ctx, name) if errors.Is(err, store.ErrNotFound) { return nil, apierror.NotFound("Worker %s not found", name) @@ -329,7 +329,7 @@ func (s *RPCService) mutateNamedWorker(ctx context.Context, name string, mutate // mutateWorker runs mutate against the named Worker and translates what comes // back into the RPC's result. A mutation that found nothing to do reports the // Worker it saw; anything else is a store error. -func (s *RPCService) mutateWorker(ctx context.Context, name string, precondition store.Precondition, mutate func(toUpdate *ateapipb.Worker) error) (*ateapipb.Worker, error) { +func (s *RPCService) mutateWorker(ctx context.Context, name string, precondition store.Precondition, mutate func(toUpdate *ateapi.Worker) error) (*ateapi.Worker, error) { worker, err := s.impl.UpdateWorker(ctx, name, precondition, mutate) if err == nil { return worker, nil @@ -360,7 +360,7 @@ func (s *RPCService) mutateWorker(ctx context.Context, name string, precondition // call with nothing left to do costs no version bump. worker is a copy, because // the store is free to reuse or discard the message once mutate returns. type workerUnchanged struct { - worker *ateapipb.Worker + worker *ateapi.Worker } func (u *workerUnchanged) Error() string { return "worker is already in the requested state" } diff --git a/cmd/ateapi/internal/controlapi/worker_assignment_reconciler.go b/cmd/ateapi/internal/controlapi/worker_assignment_reconciler.go index e4f185eab9..1f8d7d4d5a 100644 --- a/cmd/ateapi/internal/controlapi/worker_assignment_reconciler.go +++ b/cmd/ateapi/internal/controlapi/worker_assignment_reconciler.go @@ -21,8 +21,8 @@ import ( "log/slog" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/util/workqueue" ) @@ -36,7 +36,7 @@ var errWorkerLeased = errors.New("worker is being reconciled by another replica" // workerWatcher delivers every Worker change to a handler. *workercache.Cache // satisfies it. type workerWatcher interface { - AddHandler(handler func(*ateapipb.Worker)) + AddHandler(handler func(*ateapi.Worker)) } // WorkerAssignmentReconciler keeps the Actors assigned to a Worker in line with @@ -76,7 +76,7 @@ func (r *WorkerAssignmentReconciler) Start(ctx context.Context) { } // enqueue queues worker if its epoch has not been observed. -func (r *WorkerAssignmentReconciler) enqueue(worker *ateapipb.Worker) { +func (r *WorkerAssignmentReconciler) enqueue(worker *ateapi.Worker) { if needsAssignmentReconcile(worker) { r.queue.Add(worker.GetMetadata().GetName()) } diff --git a/cmd/ateapi/internal/controlapi/worker_assignment_reconciler_test.go b/cmd/ateapi/internal/controlapi/worker_assignment_reconciler_test.go index af834070c5..9f20d0b645 100644 --- a/cmd/ateapi/internal/controlapi/worker_assignment_reconciler_test.go +++ b/cmd/ateapi/internal/controlapi/worker_assignment_reconciler_test.go @@ -20,20 +20,20 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/workercache" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // noWorkers is a workerWatcher that never delivers a Worker. type noWorkers struct{} -func (noWorkers) AddHandler(func(*ateapipb.Worker)) {} +func (noWorkers) AddHandler(func(*ateapi.Worker)) {} -func epochWorker(name string, registered, observed int64) *ateapipb.Worker { - return &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: name}, - Status: &ateapipb.WorkerStatus{RegisteredEpoch: registered, ObservedEpoch: observed}, +func epochWorker(name string, registered, observed int64) *ateapi.Worker { + return &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: name}, + Status: &ateapi.WorkerStatus{RegisteredEpoch: registered, ObservedEpoch: observed}, } } @@ -41,7 +41,7 @@ func TestWorkerAssignmentReconciler_QueuesUnobservedWorkers(t *testing.T) { r := NewWorkerAssignmentReconciler(nil, noWorkers{}) defer r.queue.ShutDown() - for _, w := range []*ateapipb.Worker{ + for _, w := range []*ateapi.Worker{ epochWorker("observed", 2, 2), epochWorker("restarted", 3, 2), epochWorker("unreported", 0, 0), @@ -82,7 +82,7 @@ func TestWorkerAssignmentReconciler_SkipsWorkerLeasedElsewhere(t *testing.T) { if err := r.reconcileOne(ctx, apiWorkerName); !errors.Is(err, errWorkerLeased) { t.Fatalf("reconcileOne() = %v, want errWorkerLeased", err) } - if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("actor state = %v, want RUNNING: the lease holder releases it", got) } } @@ -123,7 +123,7 @@ func TestWorkerAssignmentReconciler_ReleasesRestartedWorker(t *testing.T) { mustRaiseEpoch(t, ctx, persistence, 2) waitForObservedEpoch(t, ctx, persistence, 2) - if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("actor state = %v, want CRASHED", got) } if a := firstAssignment(t, persistence, apiWorkerName); a != nil { @@ -150,7 +150,7 @@ func TestWorkerAssignmentReconciler_RetriesAfterLeaseFrees(t *testing.T) { lease.Close() waitForObservedEpoch(t, ctx, persistence, 2) - if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("actor state = %v, want CRASHED", got) } } @@ -167,7 +167,7 @@ func TestWorkerAssignmentReconciler_ReleasesWorkerRaisedBeforeStart(t *testing.T startAssignmentReconciler(t, ctx, persistence) waitForObservedEpoch(t, ctx, persistence, 2) - if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("actor state = %v, want CRASHED", got) } } diff --git a/cmd/ateapi/internal/controlapi/worker_assignments.go b/cmd/ateapi/internal/controlapi/worker_assignments.go index a4654c6cf6..e92a5a9e77 100644 --- a/cmd/ateapi/internal/controlapi/worker_assignments.go +++ b/cmd/ateapi/internal/controlapi/worker_assignments.go @@ -19,12 +19,12 @@ import ( "errors" "fmt" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) type workerAssignmentReader interface { - GetWorkerAssignment(ctx context.Context, workerName, actorUID string) (*ateapipb.ActorAssignment, error) + GetWorkerAssignment(ctx context.Context, workerName, actorUID string) (*ateapi.ActorAssignment, error) } // workerHostsActor reports whether a Worker holds an assignment for actorUID. diff --git a/cmd/ateapi/internal/controlapi/worker_test.go b/cmd/ateapi/internal/controlapi/worker_test.go index 54e307323c..11a21bb83f 100644 --- a/cmd/ateapi/internal/controlapi/worker_test.go +++ b/cmd/ateapi/internal/controlapi/worker_test.go @@ -21,10 +21,10 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" @@ -38,9 +38,9 @@ const ( // validWorker returns a Worker in the shape CreateWorker accepts: named, with // its pod coordinates filled in and no status — status is output-only. -func validWorker(name string, mods ...func(*ateapipb.Worker)) *ateapipb.Worker { - w := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: name}, +func validWorker(name string, mods ...func(*ateapi.Worker)) *ateapi.Worker { + w := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: name}, WorkerNamespace: "ate-system", WorkerPool: "pool-1", WorkerPod: "worker-pod-1", @@ -53,9 +53,9 @@ func validWorker(name string, mods ...func(*ateapipb.Worker)) *ateapipb.Worker { return w } -func newAPIAssignment(actorUID string) *ateapipb.ActorAssignment { - return &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "actor-1"}, +func newAPIAssignment(actorUID string) *ateapi.ActorAssignment { + return &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "actor-1"}, ActorUid: actorUID, } } @@ -77,14 +77,14 @@ func newWorkerAPIService(t *testing.T) (*RPCService, store.Interface) { // seedAPIWorker registers a worker directly through the store and returns it as // stored, so tests start from a known uid and version. -func seedAPIWorker(t *testing.T, ctx context.Context, persistence store.Interface, worker *ateapipb.Worker) *ateapipb.Worker { +func seedAPIWorker(t *testing.T, ctx context.Context, persistence store.Interface, worker *ateapi.Worker) *ateapi.Worker { t.Helper() - worker = proto.Clone(worker).(*ateapipb.Worker) + worker = proto.Clone(worker).(*ateapi.Worker) if worker.GetStatus() == nil { // A seeded Worker stands in for one that registered: ACTIVE, with the // gvisor default runtime its class is read from. - worker.Status = &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, + worker.Status = &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, SandboxClasses: workerSandboxClasses(testSandboxRuntime()), } } @@ -97,7 +97,7 @@ func seedAPIWorker(t *testing.T, ctx context.Context, persistence store.Interfac // assignAPIWorker binds an Actor to a worker the way the resume workflow does: // in-process, through the store. There is no AssignWorker RPC to go through. -func assignAPIWorker(t *testing.T, ctx context.Context, persistence store.Interface, name, actorUID string) *ateapipb.Worker { +func assignAPIWorker(t *testing.T, ctx context.Context, persistence store.Interface, name, actorUID string) *ateapi.Worker { t.Helper() if err := persistence.BindActorToWorker(ctx, name, newAPIAssignment(actorUID), nil); err != nil { t.Fatalf("assigning worker %s: %v", name, err) @@ -109,8 +109,8 @@ func assignAPIWorker(t *testing.T, ctx context.Context, persistence store.Interf return assigned } -func workerRef(name string) *ateapipb.ObjectRef { - return &ateapipb.ObjectRef{Name: name} +func workerRef(name string) *ateapi.ObjectRef { + return &ateapi.ObjectRef{Name: name} } // updateFrom builds the body of an UpdateWorker request the way a client does: @@ -118,8 +118,8 @@ func workerRef(name string) *ateapipb.ObjectRef { // The metadata comes along as the uid and version guards every update requires, // and so does everything else — an update replaces the stored worker, so an // immutable field the request drops reads as a request to clear it. -func updateFrom(observed *ateapipb.Worker, mutate func(*ateapipb.Worker)) *ateapipb.Worker { - worker := proto.Clone(observed).(*ateapipb.Worker) +func updateFrom(observed *ateapi.Worker, mutate func(*ateapi.Worker)) *ateapi.Worker { + worker := proto.Clone(observed).(*ateapi.Worker) if mutate != nil { mutate(worker) } @@ -135,7 +135,7 @@ func TestListWorkerAssignments(t *testing.T) { assignAPIWorker(t, ctx, persistence, apiWorkerName, "actor-uid-1") assignAPIWorker(t, ctx, persistence, apiWorkerName, "actor-uid-2") - page, err := svc.ListWorkerActorAssignments(ctx, &ateapipb.ListWorkerActorAssignmentsRequest{Worker: workerRef(apiWorkerName)}) + page, err := svc.ListWorkerActorAssignments(ctx, &ateapi.ListWorkerActorAssignmentsRequest{Worker: workerRef(apiWorkerName)}) if err != nil { t.Fatalf("ListWorkerActorAssignments() failed: %v", err) } @@ -164,7 +164,7 @@ func TestListWorkerAssignments_AbsentWorker(t *testing.T) { ctx := context.Background() svc, _ := newWorkerAPIService(t) - _, err := svc.ListWorkerActorAssignments(ctx, &ateapipb.ListWorkerActorAssignmentsRequest{ + _, err := svc.ListWorkerActorAssignments(ctx, &ateapi.ListWorkerActorAssignmentsRequest{ Worker: workerRef("3b9f1e77-2c4d-4a80-91be-6d5c8f0a7e21"), }) if got := apierror.Code(err); got != codes.NotFound { @@ -181,9 +181,9 @@ func TestUpdateWorker_CannotChangeCapacity(t *testing.T) { seeded := seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) before := seeded.GetStatus().GetCapacity() - got, err := svc.UpdateWorker(ctx, &ateapipb.UpdateWorkerRequest{ - Worker: updateFrom(seeded, func(w *ateapipb.Worker) { - w.Status.Capacity = &ateapipb.WorkerResources{Actors: 4094} + got, err := svc.UpdateWorker(ctx, &ateapi.UpdateWorkerRequest{ + Worker: updateFrom(seeded, func(w *ateapi.Worker) { + w.Status.Capacity = &ateapi.WorkerResources{Actors: 4094} }), }) if err != nil { @@ -201,15 +201,15 @@ func TestGetWorker_Errors(t *testing.T) { tests := []struct { name string - req *ateapipb.GetWorkerRequest + req *ateapi.GetWorkerRequest want codes.Code }{ - {"absent", &ateapipb.GetWorkerRequest{Worker: workerRef(apiOtherWorkerName)}, codes.NotFound}, - {"no ref", &ateapipb.GetWorkerRequest{}, codes.InvalidArgument}, - {"no name", &ateapipb.GetWorkerRequest{Worker: &ateapipb.ObjectRef{}}, codes.InvalidArgument}, + {"absent", &ateapi.GetWorkerRequest{Worker: workerRef(apiOtherWorkerName)}, codes.NotFound}, + {"no ref", &ateapi.GetWorkerRequest{}, codes.InvalidArgument}, + {"no name", &ateapi.GetWorkerRequest{Worker: &ateapi.ObjectRef{}}, codes.InvalidArgument}, // Workers are global-scoped, so naming an atespace is a client bug // rather than a lookup that happens to miss. - {"atespace set", &ateapipb.GetWorkerRequest{Worker: &ateapipb.ObjectRef{Atespace: "team-a", Name: apiWorkerName}}, codes.InvalidArgument}, + {"atespace set", &ateapi.GetWorkerRequest{Worker: &ateapi.ObjectRef{Atespace: "team-a", Name: apiWorkerName}}, codes.InvalidArgument}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { @@ -225,7 +225,7 @@ func TestCreateWorker(t *testing.T) { ctx := context.Background() svc, persistence := newWorkerAPIService(t) - got, err := svc.CreateWorker(ctx, &ateapipb.CreateWorkerRequest{Worker: validWorker(apiWorkerName)}) + got, err := svc.CreateWorker(ctx, &ateapi.CreateWorkerRequest{Worker: validWorker(apiWorkerName)}) if err != nil { t.Fatalf("CreateWorker() failed: %v", err) } @@ -236,8 +236,8 @@ func TestCreateWorker(t *testing.T) { t.Error("created worker has no uid; the store is meant to assign one") } // A Worker takes no Actors until it is marked available. - if got.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE { - t.Errorf("created worker state = %v, want %v", got.GetStatus().GetState(), ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE) + if got.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_UNAVAILABLE { + t.Errorf("created worker state = %v, want %v", got.GetStatus().GetState(), ateapi.WorkerState_WORKER_STATE_UNAVAILABLE) } stored, err := persistence.GetWorker(ctx, apiWorkerName) @@ -256,13 +256,13 @@ func TestCreateWorker_IgnoresRequestStatus(t *testing.T) { svc, _ := newWorkerAPIService(t) in := validWorker(apiWorkerName) - in.Status = &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_DRAINING, Allocated: &ateapipb.WorkerResources{Actors: 9}} + in.Status = &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_DRAINING, Allocated: &ateapi.WorkerResources{Actors: 9}} - got, err := svc.CreateWorker(ctx, &ateapipb.CreateWorkerRequest{Worker: in}) + got, err := svc.CreateWorker(ctx, &ateapi.CreateWorkerRequest{Worker: in}) if err != nil { t.Fatalf("CreateWorker() failed: %v", err) } - want := &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE} + want := &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_UNAVAILABLE} if diff := cmp.Diff(want, got.GetStatus(), protocmp.Transform()); diff != "" { t.Errorf("created worker status mismatch (-want +got):\n%s", diff) } @@ -273,7 +273,7 @@ func TestCreateWorker_AlreadyExists(t *testing.T) { svc, persistence := newWorkerAPIService(t) seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - _, err := svc.CreateWorker(ctx, &ateapipb.CreateWorkerRequest{Worker: validWorker(apiWorkerName)}) + _, err := svc.CreateWorker(ctx, &ateapi.CreateWorkerRequest{Worker: validWorker(apiWorkerName)}) if got := apierror.Code(err); got != codes.AlreadyExists { t.Errorf("CreateWorker() code = %v (err %v), want %v", got, err, codes.AlreadyExists) } @@ -285,19 +285,19 @@ func TestCreateWorker_InvalidArgument(t *testing.T) { tests := []struct { name string - mutate func(*ateapipb.Worker) // nil sends no worker at all + mutate func(*ateapi.Worker) // nil sends no worker at all }{ {name: "no worker"}, - {name: "no name", mutate: func(w *ateapipb.Worker) { w.Metadata = &ateapipb.ResourceMetadata{} }}, - {name: "atespace set", mutate: func(w *ateapipb.Worker) { w.Metadata.Atespace = "team-a" }}, - {name: "no node", mutate: func(w *ateapipb.Worker) { w.NodeName = "" }}, - {name: "no pool", mutate: func(w *ateapipb.Worker) { w.WorkerPool = "" }}, - {name: "no pod", mutate: func(w *ateapipb.Worker) { w.WorkerPod = "" }}, - {name: "pod uid not a uuid", mutate: func(w *ateapipb.Worker) { w.WorkerPodUid = "not-a-uuid" }}, + {name: "no name", mutate: func(w *ateapi.Worker) { w.Metadata = &ateapi.ResourceMetadata{} }}, + {name: "atespace set", mutate: func(w *ateapi.Worker) { w.Metadata.Atespace = "team-a" }}, + {name: "no node", mutate: func(w *ateapi.Worker) { w.NodeName = "" }}, + {name: "no pool", mutate: func(w *ateapi.Worker) { w.WorkerPool = "" }}, + {name: "no pod", mutate: func(w *ateapi.Worker) { w.WorkerPod = "" }}, + {name: "pod uid not a uuid", mutate: func(w *ateapi.Worker) { w.WorkerPodUid = "not-a-uuid" }}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - req := &ateapipb.CreateWorkerRequest{} + req := &ateapi.CreateWorkerRequest{} if tc.mutate != nil { worker := validWorker(apiWorkerName) tc.mutate(worker) @@ -316,8 +316,8 @@ func TestUpdateWorker(t *testing.T) { svc, persistence := newWorkerAPIService(t) seeded := seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - got, err := svc.UpdateWorker(ctx, &ateapipb.UpdateWorkerRequest{ - Worker: updateFrom(seeded, func(w *ateapipb.Worker) { + got, err := svc.UpdateWorker(ctx, &ateapi.UpdateWorkerRequest{ + Worker: updateFrom(seeded, func(w *ateapi.Worker) { w.Labels = map[string]string{"tier": "batch"} }), }) @@ -325,7 +325,7 @@ func TestUpdateWorker(t *testing.T) { t.Fatalf("UpdateWorker() failed: %v", err) } - want := proto.Clone(seeded).(*ateapipb.Worker) + want := proto.Clone(seeded).(*ateapi.Worker) want.Labels = map[string]string{"tier": "batch"} want.Metadata = got.GetMetadata() if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" { @@ -346,8 +346,8 @@ func TestUpdateWorker_OmittedMutableFieldIsCleared(t *testing.T) { labelled.Labels = map[string]string{"tier": "batch"} seeded := seedAPIWorker(t, ctx, persistence, labelled) - got, err := svc.UpdateWorker(ctx, &ateapipb.UpdateWorkerRequest{ - Worker: updateFrom(seeded, func(w *ateapipb.Worker) { + got, err := svc.UpdateWorker(ctx, &ateapi.UpdateWorkerRequest{ + Worker: updateFrom(seeded, func(w *ateapi.Worker) { w.Labels = nil }), }) @@ -368,12 +368,12 @@ func TestUpdateWorker_LeavesStatusAlone(t *testing.T) { seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) assigned := assignAPIWorker(t, ctx, persistence, apiWorkerName, "actor-uid-1") - got, err := svc.UpdateWorker(ctx, &ateapipb.UpdateWorkerRequest{ - Worker: updateFrom(assigned, func(w *ateapipb.Worker) { + got, err := svc.UpdateWorker(ctx, &ateapi.UpdateWorkerRequest{ + Worker: updateFrom(assigned, func(w *ateapi.Worker) { w.Labels = map[string]string{"tier": "batch"} // A forged status: drained, and with the Actor released out from // under the workflow that bound it. Neither may land. - w.Status = &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_DRAINING} + w.Status = &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_DRAINING} }), }) if err != nil { @@ -389,9 +389,9 @@ func TestUpdateWorker_Preconditions(t *testing.T) { svc, persistence := newWorkerAPIService(t) seeded := seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - update := func(bend func(*ateapipb.ResourceMetadata)) error { - _, err := svc.UpdateWorker(ctx, &ateapipb.UpdateWorkerRequest{ - Worker: updateFrom(seeded, func(w *ateapipb.Worker) { + update := func(bend func(*ateapi.ResourceMetadata)) error { + _, err := svc.UpdateWorker(ctx, &ateapi.UpdateWorkerRequest{ + Worker: updateFrom(seeded, func(w *ateapi.Worker) { w.Labels = map[string]string{"tier": "batch"} bend(w.Metadata) }), @@ -400,14 +400,14 @@ func TestUpdateWorker_Preconditions(t *testing.T) { } t.Run("stale version", func(t *testing.T) { - err := update(func(md *ateapipb.ResourceMetadata) { md.Version += 7 }) + err := update(func(md *ateapi.ResourceMetadata) { md.Version += 7 }) if got := apierror.Code(err); got != codes.Aborted { t.Errorf("UpdateWorker() code = %v, want %v", got, codes.Aborted) } }) t.Run("foreign uid", func(t *testing.T) { - err := update(func(md *ateapipb.ResourceMetadata) { md.Uid = apiOtherWorkerName }) + err := update(func(md *ateapi.ResourceMetadata) { md.Uid = apiOtherWorkerName }) if got := apierror.Code(err); got != codes.Aborted { t.Errorf("UpdateWorker() code = %v, want %v", got, codes.Aborted) } @@ -416,21 +416,21 @@ func TestUpdateWorker_Preconditions(t *testing.T) { // Both guards are required: an update that pins neither is a blind write, // which is rejected before it reaches the store. t.Run("missing uid", func(t *testing.T) { - err := update(func(md *ateapipb.ResourceMetadata) { md.Uid = "" }) + err := update(func(md *ateapi.ResourceMetadata) { md.Uid = "" }) if got := apierror.Code(err); got != codes.InvalidArgument { t.Errorf("UpdateWorker() code = %v, want %v", got, codes.InvalidArgument) } }) t.Run("missing version", func(t *testing.T) { - err := update(func(md *ateapipb.ResourceMetadata) { md.Version = 0 }) + err := update(func(md *ateapi.ResourceMetadata) { md.Version = 0 }) if got := apierror.Code(err); got != codes.InvalidArgument { t.Errorf("UpdateWorker() code = %v, want %v", got, codes.InvalidArgument) } }) t.Run("matching", func(t *testing.T) { - if err := update(func(*ateapipb.ResourceMetadata) {}); err != nil { + if err := update(func(*ateapi.ResourceMetadata) {}); err != nil { t.Errorf("UpdateWorker() with matching preconditions failed: %v", err) } }) @@ -445,29 +445,29 @@ func TestUpdateWorker_Errors(t *testing.T) { // stored, so the rule it is named for is the one that rejects it. tests := []struct { name string - mutate func(*ateapipb.Worker) // nil sends no worker at all + mutate func(*ateapi.Worker) // nil sends no worker at all want codes.Code }{ {"no worker", nil, codes.InvalidArgument}, - {"atespace set", func(w *ateapipb.Worker) { w.Metadata.Atespace = "team-a" }, codes.InvalidArgument}, - {"absent", func(w *ateapipb.Worker) { + {"atespace set", func(w *ateapi.Worker) { w.Metadata.Atespace = "team-a" }, codes.InvalidArgument}, + {"absent", func(w *ateapi.Worker) { w.Metadata.Name = "9d1f7b06-3c58-4a2e-8b40-5f7c1e9a2d63" }, codes.NotFound}, // Immutable fields, changed. A replacement update carries the whole // worker, so these are the cases where it carries a different one. - {"worker_pod changed", func(w *ateapipb.Worker) { w.WorkerPod = "worker-pod-2" }, codes.InvalidArgument}, - {"node_name changed", func(w *ateapipb.Worker) { w.NodeName = "node-2" }, codes.InvalidArgument}, + {"worker_pod changed", func(w *ateapi.Worker) { w.WorkerPod = "worker-pod-2" }, codes.InvalidArgument}, + {"node_name changed", func(w *ateapi.Worker) { w.NodeName = "node-2" }, codes.InvalidArgument}, // capacity is deliberately absent here: it may change (the pool's actor // ceiling moves, a pod can be resized, a Worker may report its own). // TestUpdateWorker_CapacityChanges covers that. // // And immutable fields dropped, which a replacement update reads as a // request to clear them. Rejected rather than silently applied. - {"node_name omitted", func(w *ateapipb.Worker) { w.NodeName = "" }, codes.InvalidArgument}, + {"node_name omitted", func(w *ateapi.Worker) { w.NodeName = "" }, codes.InvalidArgument}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - req := &ateapipb.UpdateWorkerRequest{} + req := &ateapi.UpdateWorkerRequest{} if tc.mutate != nil { req.Worker = updateFrom(seeded, tc.mutate) } @@ -485,13 +485,13 @@ func TestUpdateWorker_DrainingWorkerKeepsLabelsMutable(t *testing.T) { ctx := context.Background() svc, persistence := newWorkerAPIService(t) seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - drained, err := svc.DrainWorker(ctx, &ateapipb.DrainWorkerRequest{Worker: workerRef(apiWorkerName)}) + drained, err := svc.DrainWorker(ctx, &ateapi.DrainWorkerRequest{Worker: workerRef(apiWorkerName)}) if err != nil { t.Fatalf("DrainWorker() failed: %v", err) } - got, err := svc.UpdateWorker(ctx, &ateapipb.UpdateWorkerRequest{ - Worker: updateFrom(drained.GetWorker(), func(w *ateapipb.Worker) { w.Labels = map[string]string{"tier": "batch"} }), + got, err := svc.UpdateWorker(ctx, &ateapi.UpdateWorkerRequest{ + Worker: updateFrom(drained.GetWorker(), func(w *ateapi.Worker) { w.Labels = map[string]string{"tier": "batch"} }), }) if err != nil { t.Fatalf("UpdateWorker() failed: %v", err) @@ -499,8 +499,8 @@ func TestUpdateWorker_DrainingWorkerKeepsLabelsMutable(t *testing.T) { if got.GetLabels()["tier"] != "batch" { t.Errorf("labels = %v, want tier=batch", got.GetLabels()) } - if got.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_DRAINING { - t.Errorf("state = %v, want it still %v", got.GetStatus().GetState(), ateapipb.WorkerState_WORKER_STATE_DRAINING) + if got.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_DRAINING { + t.Errorf("state = %v, want it still %v", got.GetStatus().GetState(), ateapi.WorkerState_WORKER_STATE_DRAINING) } } @@ -509,7 +509,7 @@ func TestDeleteWorker(t *testing.T) { svc, persistence := newWorkerAPIService(t) seeded := seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - got, err := svc.DeleteWorker(ctx, &ateapipb.DeleteWorkerRequest{Worker: workerRef(apiWorkerName)}) + got, err := svc.DeleteWorker(ctx, &ateapi.DeleteWorkerRequest{Worker: workerRef(apiWorkerName)}) if err != nil { t.Fatalf("DeleteWorker() failed: %v", err) } @@ -518,11 +518,11 @@ func TestDeleteWorker(t *testing.T) { if got.GetMetadata().GetDeleteTime() == nil { t.Error("DeleteWorker() returned a worker without delete_time") } - want := proto.Clone(seeded).(*ateapipb.Worker) + want := proto.Clone(seeded).(*ateapi.Worker) want.Metadata.Version = seeded.GetMetadata().GetVersion() + 1 want.Metadata.UpdateTime = got.GetMetadata().GetUpdateTime() want.Metadata.DeleteTime = got.GetMetadata().GetDeleteTime() - want.Status.State = ateapipb.WorkerState_WORKER_STATE_DRAINING + want.Status.State = ateapi.WorkerState_WORKER_STATE_DRAINING if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" { t.Errorf("DeleteWorker() returned something other than the worker it removed (-want +got):\n%s", diff) } @@ -538,7 +538,7 @@ func TestDeleteWorker_Absent(t *testing.T) { ctx := context.Background() svc, _ := newWorkerAPIService(t) - _, err := svc.DeleteWorker(ctx, &ateapipb.DeleteWorkerRequest{Worker: workerRef(apiWorkerName)}) + _, err := svc.DeleteWorker(ctx, &ateapi.DeleteWorkerRequest{Worker: workerRef(apiWorkerName)}) if got := apierror.Code(err); got != codes.NotFound { t.Errorf("DeleteWorker() code = %v (err %v), want %v", got, err, codes.NotFound) } @@ -552,7 +552,7 @@ func TestDeleteWorker_AssignedWorkerDeletesAnyway(t *testing.T) { seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) assignAPIWorker(t, ctx, persistence, apiWorkerName, "actor-uid-1") - got, err := svc.DeleteWorker(ctx, &ateapipb.DeleteWorkerRequest{Worker: workerRef(apiWorkerName)}) + got, err := svc.DeleteWorker(ctx, &ateapi.DeleteWorkerRequest{Worker: workerRef(apiWorkerName)}) if err != nil { t.Fatalf("DeleteWorker() failed: %v", err) } @@ -568,9 +568,9 @@ func TestDeleteWorker_Preconditions(t *testing.T) { seeded := seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) t.Run("stale version", func(t *testing.T) { - _, err := svc.DeleteWorker(ctx, &ateapipb.DeleteWorkerRequest{ + _, err := svc.DeleteWorker(ctx, &ateapi.DeleteWorkerRequest{ Worker: workerRef(apiWorkerName), - Options: &ateapipb.DeleteOptions{Version: seeded.GetMetadata().GetVersion() + 7}, + Options: &ateapi.DeleteOptions{Version: seeded.GetMetadata().GetVersion() + 7}, }) if got := apierror.Code(err); got != codes.Aborted { t.Errorf("DeleteWorker() code = %v (err %v), want %v", got, err, codes.Aborted) @@ -578,9 +578,9 @@ func TestDeleteWorker_Preconditions(t *testing.T) { }) t.Run("foreign uid", func(t *testing.T) { - _, err := svc.DeleteWorker(ctx, &ateapipb.DeleteWorkerRequest{ + _, err := svc.DeleteWorker(ctx, &ateapi.DeleteWorkerRequest{ Worker: workerRef(apiWorkerName), - Options: &ateapipb.DeleteOptions{Uid: apiOtherWorkerName}, + Options: &ateapi.DeleteOptions{Uid: apiOtherWorkerName}, }) if got := apierror.Code(err); got != codes.Aborted { t.Errorf("DeleteWorker() code = %v (err %v), want %v", got, err, codes.Aborted) @@ -593,9 +593,9 @@ func TestDeleteWorker_Preconditions(t *testing.T) { } t.Run("matching", func(t *testing.T) { - if _, err := svc.DeleteWorker(ctx, &ateapipb.DeleteWorkerRequest{ + if _, err := svc.DeleteWorker(ctx, &ateapi.DeleteWorkerRequest{ Worker: workerRef(apiWorkerName), - Options: &ateapipb.DeleteOptions{ + Options: &ateapi.DeleteOptions{ Uid: seeded.GetMetadata().GetUid(), Version: seeded.GetMetadata().GetVersion(), }, @@ -610,12 +610,12 @@ func TestDrainWorker(t *testing.T) { svc, persistence := newWorkerAPIService(t) seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - got, err := svc.DrainWorker(ctx, &ateapipb.DrainWorkerRequest{Worker: workerRef(apiWorkerName)}) + got, err := svc.DrainWorker(ctx, &ateapi.DrainWorkerRequest{Worker: workerRef(apiWorkerName)}) if err != nil { t.Fatalf("DrainWorker() failed: %v", err) } - if got.GetWorker().GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_DRAINING { - t.Errorf("state = %v, want %v", got.GetWorker().GetStatus().GetState(), ateapipb.WorkerState_WORKER_STATE_DRAINING) + if got.GetWorker().GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_DRAINING { + t.Errorf("state = %v, want %v", got.GetWorker().GetStatus().GetState(), ateapi.WorkerState_WORKER_STATE_DRAINING) } if got.GetWorker().GetMetadata().GetVersion() != 2 { t.Errorf("version = %d, want 2", got.GetWorker().GetMetadata().GetVersion()) @@ -623,7 +623,7 @@ func TestDrainWorker(t *testing.T) { // Draining again is a no-op, and specifically must not bump the version: // callers re-drive drain on every pod event. - again, err := svc.DrainWorker(ctx, &ateapipb.DrainWorkerRequest{Worker: workerRef(apiWorkerName)}) + again, err := svc.DrainWorker(ctx, &ateapi.DrainWorkerRequest{Worker: workerRef(apiWorkerName)}) if err != nil { t.Fatalf("second DrainWorker() failed: %v", err) } @@ -640,7 +640,7 @@ func TestDrainWorker_KeepsAssignment(t *testing.T) { seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) assignAPIWorker(t, ctx, persistence, apiWorkerName, "actor-uid-1") - got, err := svc.DrainWorker(ctx, &ateapipb.DrainWorkerRequest{Worker: workerRef(apiWorkerName)}) + got, err := svc.DrainWorker(ctx, &ateapi.DrainWorkerRequest{Worker: workerRef(apiWorkerName)}) if err != nil { t.Fatalf("DrainWorker() failed: %v", err) } @@ -655,13 +655,13 @@ func TestDrainWorker_Errors(t *testing.T) { tests := []struct { name string - req *ateapipb.DrainWorkerRequest + req *ateapi.DrainWorkerRequest want codes.Code }{ - {"absent", &ateapipb.DrainWorkerRequest{Worker: workerRef(apiWorkerName)}, codes.NotFound}, - {"no ref", &ateapipb.DrainWorkerRequest{}, codes.InvalidArgument}, - {"no name", &ateapipb.DrainWorkerRequest{Worker: &ateapipb.ObjectRef{}}, codes.InvalidArgument}, - {"atespace set", &ateapipb.DrainWorkerRequest{Worker: &ateapipb.ObjectRef{Atespace: "team-a", Name: apiWorkerName}}, codes.InvalidArgument}, + {"absent", &ateapi.DrainWorkerRequest{Worker: workerRef(apiWorkerName)}, codes.NotFound}, + {"no ref", &ateapi.DrainWorkerRequest{}, codes.InvalidArgument}, + {"no name", &ateapi.DrainWorkerRequest{Worker: &ateapi.ObjectRef{}}, codes.InvalidArgument}, + {"atespace set", &ateapi.DrainWorkerRequest{Worker: &ateapi.ObjectRef{Atespace: "team-a", Name: apiWorkerName}}, codes.InvalidArgument}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { @@ -679,31 +679,31 @@ func TestDrainWorker_Errors(t *testing.T) { func TestMarkWorkerAvailability(t *testing.T) { ctx := context.Background() svc, _ := newWorkerAPIService(t) - created, err := svc.CreateWorker(ctx, &ateapipb.CreateWorkerRequest{Worker: validWorker(apiWorkerName)}) + created, err := svc.CreateWorker(ctx, &ateapi.CreateWorkerRequest{Worker: validWorker(apiWorkerName)}) if err != nil { t.Fatalf("CreateWorker() failed: %v", err) } - markAvailable := func() (*ateapipb.Worker, error) { - resp, err := svc.MarkWorkerAvailable(ctx, &ateapipb.MarkWorkerAvailableRequest{Worker: workerRef(apiWorkerName)}) + markAvailable := func() (*ateapi.Worker, error) { + resp, err := svc.MarkWorkerAvailable(ctx, &ateapi.MarkWorkerAvailableRequest{Worker: workerRef(apiWorkerName)}) return resp.GetWorker(), err } - markUnavailable := func() (*ateapipb.Worker, error) { - resp, err := svc.MarkWorkerUnavailable(ctx, &ateapipb.MarkWorkerUnavailableRequest{Worker: workerRef(apiWorkerName)}) + markUnavailable := func() (*ateapi.Worker, error) { + resp, err := svc.MarkWorkerUnavailable(ctx, &ateapi.MarkWorkerUnavailableRequest{Worker: workerRef(apiWorkerName)}) return resp.GetWorker(), err } version := created.GetMetadata().GetVersion() for i, step := range []struct { name string - mark func() (*ateapipb.Worker, error) - want ateapipb.WorkerState + mark func() (*ateapi.Worker, error) + want ateapi.WorkerState changed bool }{ - {"available", markAvailable, ateapipb.WorkerState_WORKER_STATE_ACTIVE, true}, - {"available again", markAvailable, ateapipb.WorkerState_WORKER_STATE_ACTIVE, false}, - {"unavailable", markUnavailable, ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE, true}, - {"unavailable again", markUnavailable, ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE, false}, - {"available once more", markAvailable, ateapipb.WorkerState_WORKER_STATE_ACTIVE, true}, + {"available", markAvailable, ateapi.WorkerState_WORKER_STATE_ACTIVE, true}, + {"available again", markAvailable, ateapi.WorkerState_WORKER_STATE_ACTIVE, false}, + {"unavailable", markUnavailable, ateapi.WorkerState_WORKER_STATE_UNAVAILABLE, true}, + {"unavailable again", markUnavailable, ateapi.WorkerState_WORKER_STATE_UNAVAILABLE, false}, + {"available once more", markAvailable, ateapi.WorkerState_WORKER_STATE_ACTIVE, true}, } { got, err := step.mark() if err != nil { @@ -728,7 +728,7 @@ func TestMarkWorkerUnavailable_KeepsAssignment(t *testing.T) { seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) assignAPIWorker(t, ctx, persistence, apiWorkerName, "actor-uid-1") - got, err := svc.MarkWorkerUnavailable(ctx, &ateapipb.MarkWorkerUnavailableRequest{Worker: workerRef(apiWorkerName)}) + got, err := svc.MarkWorkerUnavailable(ctx, &ateapi.MarkWorkerUnavailableRequest{Worker: workerRef(apiWorkerName)}) if err != nil { t.Fatalf("MarkWorkerUnavailable() failed: %v", err) } @@ -743,16 +743,16 @@ func TestMarkWorker_Draining(t *testing.T) { ctx := context.Background() svc, persistence := newWorkerAPIService(t) seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - drained, err := svc.DrainWorker(ctx, &ateapipb.DrainWorkerRequest{Worker: workerRef(apiWorkerName)}) + drained, err := svc.DrainWorker(ctx, &ateapi.DrainWorkerRequest{Worker: workerRef(apiWorkerName)}) if err != nil { t.Fatalf("DrainWorker() failed: %v", err) } - _, err = svc.MarkWorkerUnavailable(ctx, &ateapipb.MarkWorkerUnavailableRequest{Worker: workerRef(apiWorkerName)}) + _, err = svc.MarkWorkerUnavailable(ctx, &ateapi.MarkWorkerUnavailableRequest{Worker: workerRef(apiWorkerName)}) if got := apierror.Code(err); got != codes.FailedPrecondition { t.Errorf("MarkWorkerUnavailable() on a draining worker code = %v (err %v), want %v", got, err, codes.FailedPrecondition) } - _, err = svc.MarkWorkerAvailable(ctx, &ateapipb.MarkWorkerAvailableRequest{Worker: workerRef(apiWorkerName)}) + _, err = svc.MarkWorkerAvailable(ctx, &ateapi.MarkWorkerAvailableRequest{Worker: workerRef(apiWorkerName)}) if got := apierror.Code(err); got != codes.FailedPrecondition { t.Errorf("MarkWorkerAvailable() on a draining worker code = %v (err %v), want %v", got, err, codes.FailedPrecondition) } @@ -772,21 +772,21 @@ func TestMarkWorker_Errors(t *testing.T) { refs := []struct { name string - ref *ateapipb.ObjectRef + ref *ateapi.ObjectRef want codes.Code }{ {"absent", workerRef(apiWorkerName), codes.NotFound}, {"no ref", nil, codes.InvalidArgument}, - {"no name", &ateapipb.ObjectRef{}, codes.InvalidArgument}, - {"atespace set", &ateapipb.ObjectRef{Atespace: "team-a", Name: apiWorkerName}, codes.InvalidArgument}, + {"no name", &ateapi.ObjectRef{}, codes.InvalidArgument}, + {"atespace set", &ateapi.ObjectRef{Atespace: "team-a", Name: apiWorkerName}, codes.InvalidArgument}, } for _, tc := range refs { t.Run(tc.name, func(t *testing.T) { - _, err := svc.MarkWorkerAvailable(ctx, &ateapipb.MarkWorkerAvailableRequest{Worker: tc.ref}) + _, err := svc.MarkWorkerAvailable(ctx, &ateapi.MarkWorkerAvailableRequest{Worker: tc.ref}) if got := apierror.Code(err); got != tc.want { t.Errorf("MarkWorkerAvailable() code = %v (err %v), want %v", got, err, tc.want) } - _, err = svc.MarkWorkerUnavailable(ctx, &ateapipb.MarkWorkerUnavailableRequest{Worker: tc.ref}) + _, err = svc.MarkWorkerUnavailable(ctx, &ateapi.MarkWorkerUnavailableRequest{Worker: tc.ref}) if got := apierror.Code(err); got != tc.want { t.Errorf("MarkWorkerUnavailable() code = %v (err %v), want %v", got, err, tc.want) } @@ -811,18 +811,18 @@ func TestServiceImplUpdateWorker_ImmutableFields(t *testing.T) { for _, tc := range []struct { name string field string - mutate func(*ateapipb.Worker) + mutate func(*ateapi.Worker) }{ - {"worker_namespace", "worker_namespace", func(w *ateapipb.Worker) { w.WorkerNamespace = "other-ns" }}, - {"worker_pool", "worker_pool", func(w *ateapipb.Worker) { w.WorkerPool = "other-pool" }}, - {"worker_pod", "worker_pod", func(w *ateapipb.Worker) { w.WorkerPod = "other-pod" }}, - {"worker_pod_uid", "worker_pod_uid", func(w *ateapipb.Worker) { w.WorkerPodUid = apiOtherWorkerName }}, - {"node_name", "node_name", func(w *ateapipb.Worker) { w.NodeName = "other-node" }}, + {"worker_namespace", "worker_namespace", func(w *ateapi.Worker) { w.WorkerNamespace = "other-ns" }}, + {"worker_pool", "worker_pool", func(w *ateapi.Worker) { w.WorkerPool = "other-pool" }}, + {"worker_pod", "worker_pod", func(w *ateapi.Worker) { w.WorkerPod = "other-pod" }}, + {"worker_pod_uid", "worker_pod_uid", func(w *ateapi.Worker) { w.WorkerPodUid = apiOtherWorkerName }}, + {"node_name", "node_name", func(w *ateapi.Worker) { w.NodeName = "other-node" }}, // capacity is absent: it is reported into status, which a client // cannot write. See TestUpdateWorker_CannotChangeCapacity. } { t.Run(tc.name, func(t *testing.T) { - _, err := impl.UpdateWorker(ctx, apiWorkerName, store.PreconditionFrom(created), func(toUpdate *ateapipb.Worker) error { + _, err := impl.UpdateWorker(ctx, apiWorkerName, store.PreconditionFrom(created), func(toUpdate *ateapi.Worker) error { tc.mutate(toUpdate) return nil }) @@ -854,7 +854,7 @@ func TestCreateWorker_IgnoresRequestMetadataServerFields(t *testing.T) { in.Metadata.Uid = "not-a-uuid" in.Metadata.Version = -5 - got, err := svc.CreateWorker(ctx, &ateapipb.CreateWorkerRequest{Worker: in}) + got, err := svc.CreateWorker(ctx, &ateapi.CreateWorkerRequest{Worker: in}) if err != nil { t.Fatalf("CreateWorker() failed: %v", err) } @@ -873,7 +873,7 @@ func TestCreateWorker_HoldsNoCapacityUntilReported(t *testing.T) { ctx := context.Background() svc, _ := newWorkerAPIService(t) - got, err := svc.CreateWorker(ctx, &ateapipb.CreateWorkerRequest{Worker: validWorker(apiWorkerName)}) + got, err := svc.CreateWorker(ctx, &ateapi.CreateWorkerRequest{Worker: validWorker(apiWorkerName)}) if err != nil { t.Fatalf("CreateWorker() failed: %v", err) } @@ -884,8 +884,8 @@ func TestCreateWorker_HoldsNoCapacityUntilReported(t *testing.T) { // Capacity is status, so a request cannot bring its own: a Worker only // gets one by reporting it. carried := validWorker("11111111-2222-3333-4444-555555555555") - carried.Status = &ateapipb.WorkerStatus{Capacity: &ateapipb.WorkerResources{Actors: 4094}} - got, err = svc.CreateWorker(ctx, &ateapipb.CreateWorkerRequest{Worker: carried}) + carried.Status = &ateapi.WorkerStatus{Capacity: &ateapi.WorkerResources{Actors: 4094}} + got, err = svc.CreateWorker(ctx, &ateapi.CreateWorkerRequest{Worker: carried}) if err != nil { t.Fatalf("CreateWorker() carrying a capacity failed: %v", err) } diff --git a/cmd/ateapi/internal/controlapi/workflow.go b/cmd/ateapi/internal/controlapi/workflow.go index 9453882361..40b27cd137 100644 --- a/cmd/ateapi/internal/controlapi/workflow.go +++ b/cmd/ateapi/internal/controlapi/workflow.go @@ -22,6 +22,8 @@ import ( "sync" "time" + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/cmd/ateapi/internal/scheduling" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/workercache" @@ -30,8 +32,6 @@ import ( "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/pluginsocket" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" @@ -82,17 +82,17 @@ func markSkipped(ctx context.Context, reason string) { // // Crashes go through logActorCrashed instead, so read the state off // ate.actor.state rather than off the message. -func logActorStateChanged(ctx context.Context, actor *ateapipb.Actor, opName string) { +func logActorStateChanged(ctx context.Context, actor *ateapi.Actor, opName string) { logActorState(ctx, actor, opName, ateattr.ActorStateValue(actor.GetStatus().GetState())) } // logActorDeleted records the terminal transition. The row is gone, so there is // no committed state left to read and this is the one state named by hand. -func logActorDeleted(ctx context.Context, actor *ateapipb.Actor, opName string) { +func logActorDeleted(ctx context.Context, actor *ateapi.Actor, opName string) { logActorState(ctx, actor, opName, ateattr.ActorStateDeleted) } -func logActorState(ctx context.Context, actor *ateapipb.Actor, opName, state string) { +func logActorState(ctx context.Context, actor *ateapi.Actor, opName, state string) { attrs := ateattr.ActorLogAttrs(resources.ActorAttributionFromActor(actor)) attrs = append(attrs, slog.String(string(ateattr.ActorOperationNameKey), ateattr.NormalizeOperationName(opName)), @@ -115,7 +115,7 @@ type ActorWorkflow struct { egressGatewayAddress string pluginRegistry VolumePluginRegistry workflowDeadline time.Duration - objectStorePlugin objectstorev1.ControlProviderClient + objectStorePlugin objectstore.ControlProviderClient clusterSnapshotLocation string } @@ -134,7 +134,7 @@ func NewActorWorkflow( egressGatewayAddress string, pluginRegistry VolumePluginRegistry, workflowDeadline time.Duration, - objectStorePlugin objectstorev1.ControlProviderClient, + objectStorePlugin objectstore.ControlProviderClient, ) *ActorWorkflow { return &ActorWorkflow{ store: store, @@ -152,48 +152,48 @@ func NewActorWorkflow( // snapshotLocation returns the base object-storage URI actorTemplate's // snapshots are stored under; see resolveSnapshotLocation. -func (w *ActorWorkflow) snapshotLocation(actorTemplate *ateapipb.ActorTemplate) (string, error) { +func (w *ActorWorkflow) snapshotLocation(actorTemplate *ateapi.ActorTemplate) (string, error) { return resolveSnapshotLocation(w.clusterSnapshotLocation, actorTemplate) } // cleanupSnapshot deletes every object under prefix through the control // object-store plugin. func (w *ActorWorkflow) cleanupSnapshot(ctx context.Context, prefix resources.StoragePrefix) error { - _, err := w.objectStorePlugin.CleanupSnapshot(ctx, &objectstorev1.CleanupSnapshotRequest{SnapshotUri: prefix.String()}) + _, err := w.objectStorePlugin.CleanupSnapshot(ctx, &objectstore.CleanupSnapshotRequest{SnapshotUri: prefix.String()}) return pluginsocket.CallError(err) } // copySnapshot copies every object under src to dst through the control // object-store plugin. func (w *ActorWorkflow) copySnapshot(ctx context.Context, src, dst resources.StoragePrefix) error { - _, err := w.objectStorePlugin.CopySnapshot(ctx, &objectstorev1.CopySnapshotRequest{SrcUri: src.String(), DstUri: dst.String()}) + _, err := w.objectStorePlugin.CopySnapshot(ctx, &objectstore.CopySnapshotRequest{SrcUri: src.String(), DstUri: dst.String()}) return pluginsocket.CallError(err) } // actorWorkflowStore enumerates the exact storage methods needed by // ActorWorkflow and nothing more. type actorWorkflowStore interface { - GetActor(ctx context.Context, actorRef resources.ActorRef) (*ateapipb.Actor, error) - UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(toUpdate *ateapipb.Actor) error) (*ateapipb.Actor, error) - MarkActorForDeletion(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions, mutate func(toUpdate *ateapipb.Actor) error) (*ateapipb.Actor, error) - DeleteActor(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (*ateapipb.Actor, error) - GetWorker(ctx context.Context, name string) (*ateapipb.Worker, error) - UpdateWorker(ctx context.Context, name string, precondition store.Precondition, mutate func(toUpdate *ateapipb.Worker) error) (*ateapipb.Worker, error) - BindActorToWorker(ctx context.Context, workerName string, assignment *ateapipb.ActorAssignment, admit func(*ateapipb.Worker) error) error - ReleaseActorFromWorker(ctx context.Context, workerName string, actorUID string) (*ateapipb.Worker, error) - GetWorkerAssignment(ctx context.Context, workerName, actorUID string) (*ateapipb.ActorAssignment, error) + GetActor(ctx context.Context, actorRef resources.ActorRef) (*ateapi.Actor, error) + UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(toUpdate *ateapi.Actor) error) (*ateapi.Actor, error) + MarkActorForDeletion(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions, mutate func(toUpdate *ateapi.Actor) error) (*ateapi.Actor, error) + DeleteActor(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (*ateapi.Actor, error) + GetWorker(ctx context.Context, name string) (*ateapi.Worker, error) + UpdateWorker(ctx context.Context, name string, precondition store.Precondition, mutate func(toUpdate *ateapi.Worker) error) (*ateapi.Worker, error) + BindActorToWorker(ctx context.Context, workerName string, assignment *ateapi.ActorAssignment, admit func(*ateapi.Worker) error) error + ReleaseActorFromWorker(ctx context.Context, workerName string, actorUID string) (*ateapi.Worker, error) + GetWorkerAssignment(ctx context.Context, workerName, actorUID string) (*ateapi.ActorAssignment, error) FindWorkerHostingActor(ctx context.Context, actorUID string) (string, error) // Read from the records rather than the Worker's status: only the service // layer attaches assignments on read, and this workflow holds the store. - ListWorkerAssignments(ctx context.Context, workerName string, opts store.ListOptions) (store.ListResponse[*ateapipb.ActorAssignment], error) - CreateTag(ctx context.Context, tag *ateapipb.Tag) (*ateapipb.Tag, error) - GetTag(ctx context.Context, tagRef resources.TagRef) (*ateapipb.Tag, error) - UpdateTag(ctx context.Context, tagRef resources.TagRef, precondition store.Precondition, mutate func(toUpdate *ateapipb.Tag) error) (*ateapipb.Tag, error) - MarkTagForDeletion(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions, mutate func(toUpdate *ateapipb.Tag) error) (*ateapipb.Tag, error) - DeleteTag(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions) (*ateapipb.Tag, error) - GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapipb.ActorTemplate, error) - MarkActorTemplateForDeletion(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions, mutate func(toUpdate *ateapipb.ActorTemplate) error) (*ateapipb.ActorTemplate, error) - DeleteActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions) (*ateapipb.ActorTemplate, error) + ListWorkerAssignments(ctx context.Context, workerName string, opts store.ListOptions) (store.ListResponse[*ateapi.ActorAssignment], error) + CreateTag(ctx context.Context, tag *ateapi.Tag) (*ateapi.Tag, error) + GetTag(ctx context.Context, tagRef resources.TagRef) (*ateapi.Tag, error) + UpdateTag(ctx context.Context, tagRef resources.TagRef, precondition store.Precondition, mutate func(toUpdate *ateapi.Tag) error) (*ateapi.Tag, error) + MarkTagForDeletion(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions, mutate func(toUpdate *ateapi.Tag) error) (*ateapi.Tag, error) + DeleteTag(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions) (*ateapi.Tag, error) + GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapi.ActorTemplate, error) + MarkActorTemplateForDeletion(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions, mutate func(toUpdate *ateapi.ActorTemplate) error) (*ateapi.ActorTemplate, error) + DeleteActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions) (*ateapi.ActorTemplate, error) AcquireLease(ctx context.Context, key string) (*store.Lease, error) } @@ -228,14 +228,14 @@ func NewWorkerWorkflow(store workerWorkflowStore, dialer *AteletDialer) *WorkerW // workerWorkflowStore enumerates the exact storage methods needed by // WorkerWorkflow and nothing more. type workerWorkflowStore interface { - GetWorker(ctx context.Context, name string) (*ateapipb.Worker, error) - UpdateWorker(ctx context.Context, name string, precondition store.Precondition, mutate func(toUpdate *ateapipb.Worker) error) (*ateapipb.Worker, error) - MarkWorkerForDeletion(ctx context.Context, name string, precondition store.DeletePreconditions, mutate func(toUpdate *ateapipb.Worker) error) (*ateapipb.Worker, error) - DeleteWorker(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapipb.Worker, error) - ListWorkerAssignments(ctx context.Context, workerName string, opts store.ListOptions) (store.ListResponse[*ateapipb.ActorAssignment], error) - ReleaseActorFromWorker(ctx context.Context, workerName string, actorUID string) (*ateapipb.Worker, error) - GetActor(ctx context.Context, actorRef resources.ActorRef) (*ateapipb.Actor, error) - UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(toUpdate *ateapipb.Actor) error) (*ateapipb.Actor, error) + GetWorker(ctx context.Context, name string) (*ateapi.Worker, error) + UpdateWorker(ctx context.Context, name string, precondition store.Precondition, mutate func(toUpdate *ateapi.Worker) error) (*ateapi.Worker, error) + MarkWorkerForDeletion(ctx context.Context, name string, precondition store.DeletePreconditions, mutate func(toUpdate *ateapi.Worker) error) (*ateapi.Worker, error) + DeleteWorker(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.Worker, error) + ListWorkerAssignments(ctx context.Context, workerName string, opts store.ListOptions) (store.ListResponse[*ateapi.ActorAssignment], error) + ReleaseActorFromWorker(ctx context.Context, workerName string, actorUID string) (*ateapi.Worker, error) + GetActor(ctx context.Context, actorRef resources.ActorRef) (*ateapi.Actor, error) + UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(toUpdate *ateapi.Actor) error) (*ateapi.Actor, error) AcquireLease(ctx context.Context, key string) (*store.Lease, error) } diff --git a/cmd/ateapi/internal/controlapi/workflow_delete.go b/cmd/ateapi/internal/controlapi/workflow_delete.go index 070f1a2966..3cf41f8899 100644 --- a/cmd/ateapi/internal/controlapi/workflow_delete.go +++ b/cmd/ateapi/internal/controlapi/workflow_delete.go @@ -20,19 +20,19 @@ import ( "fmt" "log/slog" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // DeleteActor executes the workflow to delete an actor. Idempotent. -func (w *ActorWorkflow) DeleteActor(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (*ateapipb.Actor, error) { +func (w *ActorWorkflow) DeleteActor(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (*ateapi.Actor, error) { ctx = preview.ContextWithOptIn(ctx) ctx, lease, err := w.acquireActorLease(ctx, actorRef) if err != nil { @@ -97,7 +97,7 @@ func (w *ActorWorkflow) DeleteActor(ctx context.Context, actorRef resources.Acto } // ensureAteletTerminated calls atelet to terminate the workload for opName. -func (w *ActorWorkflow) ensureAteletTerminated(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor, actorTemplate *ateapipb.ActorTemplate, opName string) (err error) { +func (w *ActorWorkflow) ensureAteletTerminated(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor, actorTemplate *ateapi.ActorTemplate, opName string) (err error) { ctx, done := stepSpan(ctx, "CallAteletTerminate") defer func() { err = done(err) }() @@ -191,7 +191,7 @@ func (w *ActorWorkflow) ensureAteletTerminated(ctx context.Context, actorRef res // unmounts them from the node. A volume with no StorageVolumeId was never // provisioned (e.g. the actor failed while PENDING), so there is nothing // mounted to name. -func fallbackWorkloadSpec(actor *ateapipb.Actor) *ateletpb.WorkloadSpec { +func fallbackWorkloadSpec(actor *ateapi.Actor) *ateletpb.WorkloadSpec { // Given that external volumes has been in the codebase for a while and // its preview-ness is solely around the API, and that the impact of // disabling the gate while in use would be an orphaned volume @@ -217,7 +217,7 @@ func fallbackWorkloadSpec(actor *ateapipb.Actor) *ateletpb.WorkloadSpec { } // ensureVolumesDetachedForDelete detaches external volumes. -func (w *ActorWorkflow) ensureVolumesDetachedForDelete(ctx context.Context, actor *ateapipb.Actor, actorTemplate *ateapipb.ActorTemplate) (err error) { +func (w *ActorWorkflow) ensureVolumesDetachedForDelete(ctx context.Context, actor *ateapi.Actor, actorTemplate *ateapi.ActorTemplate) (err error) { ctx, done := stepSpan(ctx, "DetachVolumesForDelete") defer func() { err = done(err) }() @@ -233,7 +233,7 @@ func (w *ActorWorkflow) ensureVolumesDetachedForDelete(ctx context.Context, acto // releaseAssignmentWithoutBacklink releases an assignment the Actor does not // reference, found by Actor UID. Absent is the ordinary case and not an error: // most Actors reaching here really were released already. -func (w *ActorWorkflow) releaseAssignmentWithoutBacklink(ctx context.Context, actor *ateapipb.Actor) error { +func (w *ActorWorkflow) releaseAssignmentWithoutBacklink(ctx context.Context, actor *ateapi.Actor) error { actorUID := actor.GetMetadata().GetUid() workerName, err := w.store.FindWorkerHostingActor(ctx, actorUID) if err != nil { @@ -266,7 +266,7 @@ func (w *ActorWorkflow) releaseAssignmentWithoutBacklink(ctx context.Context, ac return nil } -func (w *ActorWorkflow) ensureWorkerReleased(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor) (updated *ateapipb.Actor, err error) { +func (w *ActorWorkflow) ensureWorkerReleased(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor) (updated *ateapi.Actor, err error) { ctx, done := stepSpan(ctx, "ReleaseWorker") defer func() { err = done(err) }() @@ -296,7 +296,7 @@ func (w *ActorWorkflow) ensureWorkerReleased(ctx context.Context, actorRef resou return nil, err } - updatedActor, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(latestActor), func(dbActor *ateapipb.Actor) error { + updatedActor, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(latestActor), func(dbActor *ateapi.Actor) error { if dbActor.Status != nil { clearLocalSnapshots(dbActor.Status) dbActor.Status.AssignedNode = "" @@ -320,17 +320,17 @@ var errAlreadyMarked = errors.New("already marked for deletion") // ensureMarkedDeleting sets the actor's delete_time, checking precondition, // and moves it to DELETING, returning the stored copy. Skips when a previous // attempt already marked the actor. -func (w *ActorWorkflow) ensureMarkedDeleting(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (updated *ateapipb.Actor, err error) { +func (w *ActorWorkflow) ensureMarkedDeleting(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (updated *ateapi.Actor, err error) { ctx, done := stepSpan(ctx, "MarkDeleting") defer func() { err = done(err) }() - var alreadyDeleting *ateapipb.Actor - storedActor, err := w.store.MarkActorForDeletion(ctx, actorRef, precondition, func(toUpdate *ateapipb.Actor) error { + var alreadyDeleting *ateapi.Actor + storedActor, err := w.store.MarkActorForDeletion(ctx, actorRef, precondition, func(toUpdate *ateapi.Actor) error { if toUpdate.GetMetadata().GetDeleteTime() != nil { alreadyDeleting = toUpdate return errAlreadyMarked } - toUpdate.Status.State = ateapipb.ActorState_ACTOR_STATE_DELETING + toUpdate.Status.State = ateapi.ActorState_ACTOR_STATE_DELETING return nil }) if errors.Is(err, errAlreadyMarked) { @@ -355,13 +355,13 @@ func (w *ActorWorkflow) ensureMarkedDeleting(ctx context.Context, actorRef resou // ensureVolumesDeleted removes the actor's external volumes. Volume deletion // is idempotent, so a re-entered workflow can safely run it again. It assumes a no-op success if volume is not found -func (w *ActorWorkflow) ensureVolumesDeleted(ctx context.Context, actor *ateapipb.Actor) (err error) { +func (w *ActorWorkflow) ensureVolumesDeleted(ctx context.Context, actor *ateapi.Actor) (err error) { ctx, done := stepSpan(ctx, "DeleteVolumes") defer func() { err = done(err) }() st := actor.GetStatus().GetState() - if st != ateapipb.ActorState_ACTOR_STATE_DELETING { - return apierror.FailedPrecondition("DeleteVolumes prerequisite not met for Actor: %s (got: %v, want %s)", actor.GetMetadata().GetName(), st, ateapipb.ActorState_ACTOR_STATE_DELETING) + if st != ateapi.ActorState_ACTOR_STATE_DELETING { + return apierror.FailedPrecondition("DeleteVolumes prerequisite not met for Actor: %s (got: %v, want %s)", actor.GetMetadata().GetName(), st, ateapi.ActorState_ACTOR_STATE_DELETING) } // Given that external volumes has been in the codebase for a while and @@ -381,7 +381,7 @@ func (w *ActorWorkflow) ensureVolumesDeleted(ctx context.Context, actor *ateapip // // A snapshot borrowed from a tag lives under the tag's prefix, so it survives: // the tag owns it and outlives the actor. -func (w *ActorWorkflow) ensureExternalSnapshotsReleased(ctx context.Context, actor *ateapipb.Actor) (err error) { +func (w *ActorWorkflow) ensureExternalSnapshotsReleased(ctx context.Context, actor *ateapi.Actor) (err error) { ctx, done := stepSpan(ctx, "ReleaseExternalSnapshots") defer func() { err = done(err) }() @@ -405,9 +405,9 @@ func (w *ActorWorkflow) ensureExternalSnapshotsReleased(ctx context.Context, act // the snapshot it last took, the one a suspend was in the middle of taking, and // anything a crashed suspend stranded. A zero prefix means the actor never // wrote anything. -func actorSnapshotStoragePrefix(actor *ateapipb.Actor) (resources.StoragePrefix, error) { +func actorSnapshotStoragePrefix(actor *ateapi.Actor) (resources.StoragePrefix, error) { actorOwner := actorSnapshotOwner(actor) - if snap := findLatestDurableSnapshot(actor.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED); snap != nil { + if snap := findLatestDurableSnapshot(actor.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED); snap != nil { snapshotURI := snap.GetDurableSnapshot().GetObject().GetSnapshotUri() uri, err := resources.ParseSnapshotURI(snapshotURI) if err != nil { @@ -423,7 +423,7 @@ func actorSnapshotStoragePrefix(actor *ateapipb.Actor) (resources.StoragePrefix, // Nothing of the actor's own is recorded. Unless a suspend died partway, // nothing was ever written under its prefix: the in-progress URI is // recorded before atelet uploads the first object. - inProgressSnap := findLatestDurableSnapshot(actor.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) + inProgressSnap := findLatestDurableSnapshot(actor.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) inProgress := inProgressSnap.GetDurableSnapshot().GetObject().GetSnapshotUri() if inProgress == "" { return resources.StoragePrefix{}, nil @@ -442,7 +442,7 @@ func actorSnapshotStoragePrefix(actor *ateapipb.Actor) (resources.StoragePrefix, // finalizeDeleted removes the actor from the store and returns the deleted // record. -func (w *ActorWorkflow) finalizeDeleted(ctx context.Context, actor *ateapipb.Actor) (_ *ateapipb.Actor, err error) { +func (w *ActorWorkflow) finalizeDeleted(ctx context.Context, actor *ateapi.Actor) (_ *ateapi.Actor, err error) { ctx, done := stepSpan(ctx, "FinalizeDeleted") defer func() { err = done(err) }() diff --git a/cmd/ateapi/internal/controlapi/workflow_delete_test.go b/cmd/ateapi/internal/controlapi/workflow_delete_test.go index e9920d4c9a..54151f9ebd 100644 --- a/cmd/ateapi/internal/controlapi/workflow_delete_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_delete_test.go @@ -22,6 +22,7 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" @@ -30,7 +31,6 @@ import ( "go.ate.dev/substrate/internal/objectstoreplugin/objectstoreplugintest" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/volume" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -38,36 +38,36 @@ import ( func TestDeleteActorWorkflow_ExecutionPaths(t *testing.T) { tests := []struct { name string - seedState ateapipb.ActorState + seedState ateapi.ActorState missingTmpl bool // markActorForDeletion marks the actor before the call, as a failed delete would. markActorForDeletion bool }{ { name: "delete suspended actor succeeds", - seedState: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + seedState: ateapi.ActorState_ACTOR_STATE_SUSPENDED, }, { name: "delete crashed actor succeeds", - seedState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + seedState: ateapi.ActorState_ACTOR_STATE_CRASHED, }, { name: "delete deleting actor succeeds", - seedState: ateapipb.ActorState_ACTOR_STATE_DELETING, + seedState: ateapi.ActorState_ACTOR_STATE_DELETING, markActorForDeletion: true, }, { name: "delete running actor succeeds", - seedState: ateapipb.ActorState_ACTOR_STATE_RUNNING, + seedState: ateapi.ActorState_ACTOR_STATE_RUNNING, }, { name: "delete suspended actor with missing template succeeds", - seedState: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + seedState: ateapi.ActorState_ACTOR_STATE_SUSPENDED, missingTmpl: true, }, { name: "delete running actor with missing template succeeds", - seedState: ateapipb.ActorState_ACTOR_STATE_RUNNING, + seedState: ateapi.ActorState_ACTOR_STATE_RUNNING, missingTmpl: true, }, } @@ -110,7 +110,7 @@ func TestDeleteActorWorkflow_ExecutionPaths(t *testing.T) { // atelet back, and a failed lookup proves nothing, so both stay retryable. func TestEnsureAteletTerminated_NodeGone(t *testing.T) { actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - actor := &ateapipb.Actor{Status: &ateapipb.ActorStatus{AssignedNode: "node1"}} + actor := &ateapi.Actor{Status: &ateapi.ActorStatus{AssignedNode: "node1"}} for _, tc := range []struct { name string nodes []string @@ -153,11 +153,11 @@ func (*detachDeletePlugin) DeleteVolume(context.Context, string) error { return // A volume detach on the gone node still runs: OK and NotFound from the plugin // count as detached, and any other error fails the step as before. func TestRevertAndDelete_AssignedNodeGone(t *testing.T) { - memory := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY - completed := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + memory := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + completed := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED for _, tc := range []struct { name string - state ateapipb.ActorState + state ateapi.ActorState paused bool nodeKept bool volume bool @@ -166,13 +166,13 @@ func TestRevertAndDelete_AssignedNodeGone(t *testing.T) { // wantDetachErr expects the plugin's detach error back. wantDetachErr bool }{ - {name: "paused, node gone", state: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, paused: true}, - {name: "crashed, node gone", state: ateapipb.ActorState_ACTOR_STATE_CRASHED}, - {name: "paused, node kept", state: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, paused: true, nodeKept: true, wantErr: ErrNoAteletOnNode}, - {name: "crashed, node kept", state: ateapipb.ActorState_ACTOR_STATE_CRASHED, nodeKept: true, wantErr: ErrNoAteletOnNode}, - {name: "node gone, volume detach OK", state: ateapipb.ActorState_ACTOR_STATE_CRASHED, volume: true}, - {name: "node gone, volume detach NotFound", state: ateapipb.ActorState_ACTOR_STATE_CRASHED, volume: true, detachErr: status.Error(codes.NotFound, "no such node")}, - {name: "node gone, volume detach fails", state: ateapipb.ActorState_ACTOR_STATE_CRASHED, volume: true, detachErr: status.Error(codes.Internal, "instance not found"), wantDetachErr: true}, + {name: "paused, node gone", state: ateapi.ActorState_ACTOR_STATE_SUSPENDED, paused: true}, + {name: "crashed, node gone", state: ateapi.ActorState_ACTOR_STATE_CRASHED}, + {name: "paused, node kept", state: ateapi.ActorState_ACTOR_STATE_SUSPENDED, paused: true, nodeKept: true, wantErr: ErrNoAteletOnNode}, + {name: "crashed, node kept", state: ateapi.ActorState_ACTOR_STATE_CRASHED, nodeKept: true, wantErr: ErrNoAteletOnNode}, + {name: "node gone, volume detach OK", state: ateapi.ActorState_ACTOR_STATE_CRASHED, volume: true}, + {name: "node gone, volume detach NotFound", state: ateapi.ActorState_ACTOR_STATE_CRASHED, volume: true, detachErr: status.Error(codes.NotFound, "no such node")}, + {name: "node gone, volume detach fails", state: ateapi.ActorState_ACTOR_STATE_CRASHED, volume: true, detachErr: status.Error(codes.Internal, "instance not found"), wantDetachErr: true}, } { for _, verb := range []string{"revert", "delete"} { t.Run(tc.name+"/"+verb, func(t *testing.T) { @@ -188,11 +188,11 @@ func TestRevertAndDelete_AssignedNodeGone(t *testing.T) { WithNodeGetter(nodeGetter(nil, nodes...))) plugin := &detachDeletePlugin{mockDetachVolumePlugin{detachErrs: map[string]error{"storage-vol-1": tc.detachErr}}} w.pluginRegistry = &mockPluginRegistry{plugins: map[string]volume.VolumePluginControlPlane{"mock": plugin}} - tmpl := &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ns", Name: "tmpl-vol"}, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: "gs://snapshots"}, - Volumes: []*ateapipb.Volume{{Name: "vol1"}}, - Containers: []*ateapipb.Container{{VolumeMounts: []*ateapipb.VolumeMount{{Name: "vol1"}}}}, + tmpl := &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ns", Name: "tmpl-vol"}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: "gs://snapshots"}, + Volumes: []*ateapi.Volume{{Name: "vol1"}}, + Containers: []*ateapi.Container{{VolumeMounts: []*ateapi.VolumeMount{{Name: "vol1"}}}}, } if _, err := st.CreateActorTemplate(ctx, tmpl); err != nil { t.Fatalf("create ActorTemplate: %v", err) @@ -204,10 +204,10 @@ func TestRevertAndDelete_AssignedNodeGone(t *testing.T) { if err != nil { t.Fatalf("get seeded actor: %v", err) } - mustUpdateActorStatus(t, ctx, st, actor, func(s *ateapipb.ActorStatus) { + mustUpdateActorStatus(t, ctx, st, actor, func(s *ateapi.ActorStatus) { s.AssignedNode = "node-1" s.LastAssignedGeneration = 1 - s.Snapshots = []*ateapipb.Snapshot{newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", "kept", + s.Snapshots = []*ateapi.Snapshot{newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", "kept", mustActorSnapshotURI(t, tmpl, actor, "kept").String(), completed)} if tc.paused { local := newPausedSnapshot(t, 2, memory, "", "local", "node-1") @@ -216,16 +216,16 @@ func TestRevertAndDelete_AssignedNodeGone(t *testing.T) { s.Snapshots = append(s.Snapshots, local) } if tc.volume { - s.ExternalVolumes = &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{ + s.ExternalVolumes = &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol1", StorageVolumeId: "storage-vol-1", VolumeType: "mock"}}} } }) - wantState := ateapipb.ActorState_ACTOR_STATE_REVERTING + wantState := ateapi.ActorState_ACTOR_STATE_REVERTING if verb == "revert" { _, err = w.RevertActor(ctx, actorRef) } else { - wantState = ateapipb.ActorState_ACTOR_STATE_DELETING + wantState = ateapi.ActorState_ACTOR_STATE_DELETING _, err = w.DeleteActor(ctx, actorRef, store.DeletePreconditions{}) } switch { @@ -259,7 +259,7 @@ func TestRevertAndDelete_AssignedNodeGone(t *testing.T) { if getErr != nil { t.Fatalf("get actor after revert: %v", getErr) } - if s := got.GetStatus(); s.GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED || s.GetAssignedNode() != "" { + if s := got.GetStatus(); s.GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED || s.GetAssignedNode() != "" { t.Errorf("after revert: state %v, assigned node %q, want SUSPENDED with no node", s.GetState(), s.GetAssignedNode()) } if snaps := got.GetStatus().GetSnapshots(); len(snaps) != 1 || snaps[0].GetGeneration() != 1 || snaps[0].GetDurableSnapshot().GetStatus() != completed { @@ -296,7 +296,7 @@ func TestEnsureMarkedDeleting_AllStates(t *testing.T) { if err != nil { t.Fatalf("ensureMarkedDeleting failed: %v", err) } - if got := updated.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_DELETING { + if got := updated.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_DELETING { t.Errorf("ensureMarkedDeleting returned actor in %v, want DELETING", got) } if updated.GetMetadata().GetDeleteTime() == nil { @@ -363,30 +363,30 @@ func TestEnsureExternalSnapshotsReleased(t *testing.T) { template := seedSubstrateTemplate(t, ctx, persistence, "sub-tmpl") w, objects := newFinalizeWorkflow(persistence) - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_DELETING}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_DELETING}, }) // The actor's prefix is keyed on the UID the store just assigned, so // its snapshots can only be placed now. current := mustActorSnapshotURI(t, template, actor, "current") - currentType := ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR + currentType := ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR if tt.tagOwnedSnapshot { current = mustTagSnapshotURI(t, template, "team-a", "v1-snapshot") - currentType = ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG + currentType = ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG } objects.PutSnapshot(t, current, "manifest.json") inFlight := mustActorSnapshotURI(t, template, actor, inFlightSnapshotName) if tt.inFlight != "" { objects.PutSnapshot(t, inFlight, "manifest.json") } - actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 2 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, currentType, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", current.Name(), current.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), - newDurableSnapshot(2, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", inFlight.Name(), inFlight.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, currentType, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", current.Name(), current.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + newDurableSnapshot(2, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", inFlight.Name(), inFlight.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), } }) @@ -414,15 +414,15 @@ func TestEnsureExternalSnapshotsReleased_CollectsStrandedSnapshots(t *testing.T) template := seedSubstrateTemplate(t, ctx, persistence, "sub-tmpl") w, objects := newFinalizeWorkflow(persistence) - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_DELETING}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_DELETING}, }) - otherActor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "actor-2"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + otherActor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "actor-2"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) currentSnapshot := mustActorSnapshotURI(t, template, actor, "current") @@ -431,10 +431,10 @@ func TestEnsureExternalSnapshotsReleased_CollectsStrandedSnapshots(t *testing.T) for _, uri := range []resources.SnapshotURI{currentSnapshot, strandedSnapshot, otherActorsSnapshot} { objects.PutSnapshot(t, uri, "manifest.json") } - actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 1 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", currentSnapshot.Name(), currentSnapshot.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", currentSnapshot.Name(), currentSnapshot.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), } }) @@ -459,22 +459,22 @@ func TestDeleteActor_CollectsInFlightSnapshotWithoutTemplate(t *testing.T) { w := NewActorWorkflow(persistence, nil, nil, nil, nil, "", nil, time.Minute, objectstoreplugintest.ControlClient(objects)) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "gone-tmpl"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_CRASHED}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "gone-tmpl"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_CRASHED}, }) // The template that holds the storage location is gone (was never written to storage). // We should still be able to access/delete the current snapshot for this actor. - inFlight := mustActorSnapshotURI(t, &ateapipb.ActorTemplate{ - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation}, + inFlight := mustActorSnapshotURI(t, &ateapi.ActorTemplate{ + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}, }, actor, "abandoned") objects.PutSnapshot(t, inFlight, "manifest.json") - mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 1 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", inFlight.Name(), inFlight.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", inFlight.Name(), inFlight.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), } }) @@ -496,18 +496,18 @@ func TestEnsureExternalSnapshotsReleased_DeletePrefixFailure(t *testing.T) { template := seedSubstrateTemplate(t, ctx, persistence, "sub-tmpl") w, objects := newFinalizeWorkflow(persistence) - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_DELETING}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_DELETING}, }) current := mustActorSnapshotURI(t, template, actor, "current") objects.PutSnapshot(t, current, "manifest.json", "memory.zst") - actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 1 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", current.Name(), current.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", current.Name(), current.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), } }) @@ -569,11 +569,11 @@ func TestDeleteActor_CollectsSnapshotsAfterWorkerDelete(t *testing.T) { actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} workerName := wireTestAssignment().GetWorker().GetName() - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: wireTestAssignment(), }, }) @@ -582,10 +582,10 @@ func TestDeleteActor_CollectsSnapshotsAfterWorkerDelete(t *testing.T) { if tt.hasBeenSuspended { previous := mustActorSnapshotURI(t, template, actor, "old") objects.PutSnapshot(t, previous, "manifest.json") - mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 1 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", previous.Name(), previous.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", previous.Name(), previous.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), } }) } @@ -621,7 +621,7 @@ func TestDeleteActor_CollectsSnapshotsAfterWorkerDelete(t *testing.T) { if err != nil { t.Fatalf("GetActor: %v", err) } - if got := stored.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got := stored.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Fatalf("state = %v, want CRASHED", got) } if _, err := actorWorkflow.DeleteActor(ctx, actorRef, store.DeletePreconditions{}); err != nil { @@ -645,19 +645,19 @@ func TestDeleteActorWorkflow_RetryKeepsAdmission(t *testing.T) { w := NewActorWorkflow(persistence, nil, nil, nil, nil, "", nil, time.Minute, objectstoreplugintest.ControlClient(objects)) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "gone-tmpl"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_CRASHED}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "gone-tmpl"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_CRASHED}, }) - inFlight := mustActorSnapshotURI(t, &ateapipb.ActorTemplate{ - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation}, + inFlight := mustActorSnapshotURI(t, &ateapi.ActorTemplate{ + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}, }, actor, "abandoned") objects.PutSnapshot(t, inFlight, "manifest.json") - observed := mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + observed := mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 1 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", inFlight.Name(), inFlight.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", inFlight.Name(), inFlight.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), } }) // The guards a client sends after reading the actor. @@ -674,7 +674,7 @@ func TestDeleteActorWorkflow_RetryKeepsAdmission(t *testing.T) { if admitted.GetMetadata().GetDeleteTime() == nil { t.Fatal("a failed delete left delete_time unset") } - if got := admitted.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_DELETING { + if got := admitted.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_DELETING { t.Fatalf("state after the failure = %v, want DELETING", got) } diff --git a/cmd/ateapi/internal/controlapi/workflow_objectstore_plugin_test.go b/cmd/ateapi/internal/controlapi/workflow_objectstore_plugin_test.go index d32191fd5c..c02883f53c 100644 --- a/cmd/ateapi/internal/controlapi/workflow_objectstore_plugin_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_objectstore_plugin_test.go @@ -18,9 +18,9 @@ import ( "context" "testing" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/internal/ateinterceptors" "go.ate.dev/substrate/internal/resources" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -31,11 +31,11 @@ type failingControlPlugin struct { err error } -func (p failingControlPlugin) CleanupSnapshot(context.Context, *objectstorev1.CleanupSnapshotRequest, ...grpc.CallOption) (*objectstorev1.CleanupSnapshotResponse, error) { +func (p failingControlPlugin) CleanupSnapshot(context.Context, *objectstore.CleanupSnapshotRequest, ...grpc.CallOption) (*objectstore.CleanupSnapshotResponse, error) { return nil, p.err } -func (p failingControlPlugin) CopySnapshot(context.Context, *objectstorev1.CopySnapshotRequest, ...grpc.CallOption) (*objectstorev1.CopySnapshotResponse, error) { +func (p failingControlPlugin) CopySnapshot(context.Context, *objectstore.CopySnapshotRequest, ...grpc.CallOption) (*objectstore.CopySnapshotResponse, error) { return nil, p.err } diff --git a/cmd/ateapi/internal/controlapi/workflow_reconcile_assignments.go b/cmd/ateapi/internal/controlapi/workflow_reconcile_assignments.go index 28eb5c2ec8..5f31d82be5 100644 --- a/cmd/ateapi/internal/controlapi/workflow_reconcile_assignments.go +++ b/cmd/ateapi/internal/controlapi/workflow_reconcile_assignments.go @@ -19,15 +19,15 @@ import ( "errors" "fmt" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // needsAssignmentReconcile reports whether worker's registered epoch has risen // past the last one its earlier Actors were released for. -func needsAssignmentReconcile(worker *ateapipb.Worker) bool { +func needsAssignmentReconcile(worker *ateapi.Worker) bool { return worker.GetStatus().GetRegisteredEpoch() > worker.GetStatus().GetObservedEpoch() } @@ -84,7 +84,7 @@ func (w *WorkerWorkflow) recordObservedEpoch(ctx context.Context, name, uid stri if err != nil { return fmt.Errorf("while re-fetching worker %s: %w", name, err) } - _, err = w.store.UpdateWorker(ctx, name, store.Precondition{UID: uid, Version: worker.GetMetadata().GetVersion()}, func(toUpdate *ateapipb.Worker) error { + _, err = w.store.UpdateWorker(ctx, name, store.Precondition{UID: uid, Version: worker.GetMetadata().GetVersion()}, func(toUpdate *ateapi.Worker) error { toUpdate.Status.ObservedEpoch = max(toUpdate.GetStatus().GetObservedEpoch(), epoch) return nil }) @@ -106,7 +106,7 @@ var errActorBusy = errors.New("actor has an operation in progress") // releaseAssignmentsBefore releases every assignment on worker whose Actor ran // under an epoch before epoch. An assignment whose Actor is busy is skipped // until the rest are released, then reported, so the pass is retried. -func (w *WorkerWorkflow) releaseAssignmentsBefore(ctx context.Context, worker *ateapipb.Worker, epoch int64) error { +func (w *WorkerWorkflow) releaseAssignmentsBefore(ctx context.Context, worker *ateapi.Worker, epoch int64) error { name := worker.GetMetadata().GetName() busy := 0 // Releasing deletes rows mid-scan, which paging tolerates: the cursor is @@ -146,7 +146,7 @@ func (w *WorkerWorkflow) releaseAssignmentsBefore(ctx context.Context, worker *a // CRASHED. A row whose Actor does not point here names nothing that ran on the // Worker, so the restart lost nothing of it and it is left alone: it is a claim // a resume is still recording, or one the Actor's next resume recovers. -func (w *WorkerWorkflow) releaseEarlierAssignment(ctx context.Context, worker *ateapipb.Worker, assignment *ateapipb.ActorAssignment, epoch int64) error { +func (w *WorkerWorkflow) releaseEarlierAssignment(ctx context.Context, worker *ateapi.Worker, assignment *ateapi.ActorAssignment, epoch int64) error { name := worker.GetMetadata().GetName() release := func() error { if _, err := w.store.ReleaseActorFromWorker(ctx, name, assignment.GetActorUid()); err != nil { @@ -186,14 +186,14 @@ func (w *WorkerWorkflow) releaseEarlierAssignment(ctx context.Context, worker *a if actor.GetStatus().GetWorkerAssignment().GetWorkerEpoch() >= epoch { return nil } - if actor.GetStatus().GetState() == ateapipb.ActorState_ACTOR_STATE_RESUMING { + if actor.GetStatus().GetState() == ateapi.ActorState_ACTOR_STATE_RESUMING { // A RESUMING Actor is left to its resume, which records the epoch of // the worker process that restores it, and restores it again if that // process is gone, whether finalizeRunning finds it replaced or the // Restore was cut short by the restart. return nil } - if actor.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if actor.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { if err := w.crashBoundActor(ctx, worker, actorRef, actor, "Releasing actor from a restarted worker", crashMessageWorkerRestarted); err != nil { return err } diff --git a/cmd/ateapi/internal/controlapi/workflow_reconcile_assignments_test.go b/cmd/ateapi/internal/controlapi/workflow_reconcile_assignments_test.go index 23bb30a155..684972d66b 100644 --- a/cmd/ateapi/internal/controlapi/workflow_reconcile_assignments_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_reconcile_assignments_test.go @@ -20,21 +20,21 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/scheduling" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/cmd/ateapi/internal/workercache" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // seedEpochWorker stores apiWorkerName with epoch active, and observed as the // epoch its earlier Actors were last released for. func seedEpochWorker(t *testing.T, ctx context.Context, persistence store.Interface, epoch, observed int64) { t.Helper() - seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName, func(w *ateapipb.Worker) { - w.Status = &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, + seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName, func(w *ateapi.Worker) { + w.Status = &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, RegisteredEpoch: epoch, ObservedEpoch: observed, } @@ -46,7 +46,7 @@ func seedEpochWorker(t *testing.T, ctx context.Context, persistence store.Interf func mustRaiseEpoch(t *testing.T, ctx context.Context, persistence store.Interface, epoch int64) { t.Helper() worker := mustGetWorker(t, ctx, persistence) - if _, err := persistence.UpdateWorker(ctx, apiWorkerName, store.PreconditionFrom(worker), func(toUpdate *ateapipb.Worker) error { + if _, err := persistence.UpdateWorker(ctx, apiWorkerName, store.PreconditionFrom(worker), func(toUpdate *ateapi.Worker) error { toUpdate.Status.RegisteredEpoch = epoch return nil }); err != nil { @@ -61,7 +61,7 @@ func mustReconcileAssignments(t *testing.T, ctx context.Context, persistence sto } } -func mustGetWorker(t *testing.T, ctx context.Context, persistence store.Interface) *ateapipb.Worker { +func mustGetWorker(t *testing.T, ctx context.Context, persistence store.Interface) *ateapi.Worker { t.Helper() got, err := persistence.GetWorker(ctx, apiWorkerName) if err != nil { @@ -70,7 +70,7 @@ func mustGetWorker(t *testing.T, ctx context.Context, persistence store.Interfac return got } -func mustGetActor(t *testing.T, ctx context.Context, persistence store.Interface) *ateapipb.Actor { +func mustGetActor(t *testing.T, ctx context.Context, persistence store.Interface) *ateapi.Actor { t.Helper() got, err := persistence.GetActor(ctx, apiActorRef) if err != nil { @@ -82,7 +82,7 @@ func mustGetActor(t *testing.T, ctx context.Context, persistence store.Interface // seedRunningActor stores a RUNNING Actor assigned to apiWorkerName. func seedRunningActor(t *testing.T, ctx context.Context, persistence store.Interface) { t.Helper() - actor := seedAPIActor(t, ctx, persistence, ateapipb.ActorState_ACTOR_STATE_RUNNING) + actor := seedAPIActor(t, ctx, persistence, ateapi.ActorState_ACTOR_STATE_RUNNING) assignAPIWorker(t, ctx, persistence, apiWorkerName, actor.GetMetadata().GetUid()) } @@ -90,10 +90,10 @@ func TestReconcileAssignments_CrashesEarlierActors(t *testing.T) { ctx := context.Background() _, persistence := newWorkerAPIService(t) seedEpochWorker(t, ctx, persistence, 1, 1) - actor := seedAPIActor(t, ctx, persistence, ateapipb.ActorState_ACTOR_STATE_RUNNING, func(a *ateapipb.Actor) { + actor := seedAPIActor(t, ctx, persistence, ateapi.ActorState_ACTOR_STATE_RUNNING, func(a *ateapi.Actor) { a.Status.LastAssignedGeneration = 1 - a.Status.Snapshots = []*ateapipb.Snapshot{ - newPausedSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "partial-local-snapshot", ""), + a.Status.Snapshots = []*ateapi.Snapshot{ + newPausedSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "partial-local-snapshot", ""), } }) assignAPIWorker(t, ctx, persistence, apiWorkerName, actor.GetMetadata().GetUid()) @@ -105,14 +105,14 @@ func TestReconcileAssignments_CrashesEarlierActors(t *testing.T) { if worker.GetStatus().GetObservedEpoch() != 2 { t.Errorf("observed_epoch = %d, want 2", worker.GetStatus().GetObservedEpoch()) } - if worker.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_ACTIVE { + if worker.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_ACTIVE { t.Errorf("worker state = %v, want it left ACTIVE", worker.GetStatus().GetState()) } if worker.GetStatus().GetAllocated().GetActors() != 0 { t.Errorf("worker allocated = %v, want the crashed actor's share freed", worker.GetStatus().GetAllocated()) } got := mustGetActor(t, ctx, persistence) - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("actor state = %v, want CRASHED: its sandbox died with the worker", got.GetStatus().GetState()) } if msg := got.GetStatus().GetCrash().GetMessage(); msg != crashMessageWorkerRestarted { @@ -137,13 +137,13 @@ func TestReconcileAssignments_KeepsActorRestoredOnNewProcess(t *testing.T) { seedEpochWorker(t, ctx, persistence, 1, 1) seedRunningActor(t, ctx, persistence) mustRaiseEpoch(t, ctx, persistence, 2) - mustUpdateActorStatus(t, ctx, persistence, mustGetActor(t, ctx, persistence), func(s *ateapipb.ActorStatus) { + mustUpdateActorStatus(t, ctx, persistence, mustGetActor(t, ctx, persistence), func(s *ateapi.ActorStatus) { s.WorkerAssignment.WorkerEpoch = 2 }) mustReconcileAssignments(t, ctx, persistence) - if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("actor state = %v, want RUNNING", got) } if firstAssignment(t, persistence, apiWorkerName) == nil { @@ -166,7 +166,7 @@ func TestReconcileAssignments_AlreadyObservedWritesNothing(t *testing.T) { if got := mustGetWorker(t, ctx, persistence).GetMetadata().GetVersion(); got != version { t.Errorf("worker version = %d, want %d: nothing to write", got, version) } - if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("actor state = %v, want RUNNING", got) } } @@ -181,30 +181,30 @@ func TestReconcileAssignments_ReleasesByActorState(t *testing.T) { ) tests := []struct { name string - state ateapipb.ActorState + state ateapi.ActorState pointsAt int - wantState ateapipb.ActorState + wantState ateapi.ActorState wantRelease bool }{ // Suspended cleanly before the restart: still resumable. - {name: "suspended stays suspended", state: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, wantState: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, wantRelease: true}, - {name: "crashed is released", state: ateapipb.ActorState_ACTOR_STATE_CRASHED, wantState: ateapipb.ActorState_ACTOR_STATE_CRASHED, wantRelease: true}, + {name: "suspended stays suspended", state: ateapi.ActorState_ACTOR_STATE_SUSPENDED, wantState: ateapi.ActorState_ACTOR_STATE_SUSPENDED, wantRelease: true}, + {name: "crashed is released", state: ateapi.ActorState_ACTOR_STATE_CRASHED, wantState: ateapi.ActorState_ACTOR_STATE_CRASHED, wantRelease: true}, // Nothing it ran on the Worker: a claim a resume is still recording, // or one its next resume recovers. Left alone. - {name: "crashed unassigned is left", state: ateapipb.ActorState_ACTOR_STATE_CRASHED, pointsAt: unassigned, wantState: ateapipb.ActorState_ACTOR_STATE_CRASHED}, - {name: "suspended unassigned is left", state: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, pointsAt: unassigned, wantState: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, - {name: "running elsewhere is left", state: ateapipb.ActorState_ACTOR_STATE_RUNNING, pointsAt: otherWorker, wantState: ateapipb.ActorState_ACTOR_STATE_RUNNING}, - {name: "suspended elsewhere is left", state: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, pointsAt: otherWorker, wantState: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + {name: "crashed unassigned is left", state: ateapi.ActorState_ACTOR_STATE_CRASHED, pointsAt: unassigned, wantState: ateapi.ActorState_ACTOR_STATE_CRASHED}, + {name: "suspended unassigned is left", state: ateapi.ActorState_ACTOR_STATE_SUSPENDED, pointsAt: unassigned, wantState: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, + {name: "running elsewhere is left", state: ateapi.ActorState_ACTOR_STATE_RUNNING, pointsAt: otherWorker, wantState: ateapi.ActorState_ACTOR_STATE_RUNNING}, + {name: "suspended elsewhere is left", state: ateapi.ActorState_ACTOR_STATE_SUSPENDED, pointsAt: otherWorker, wantState: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, // Nothing it ran is kept: its resume restores it on the new process. - {name: "resuming is left to its resume", state: ateapipb.ActorState_ACTOR_STATE_RESUMING, wantState: ateapipb.ActorState_ACTOR_STATE_RESUMING}, - {name: "deleting stays deleting", state: ateapipb.ActorState_ACTOR_STATE_DELETING, wantState: ateapipb.ActorState_ACTOR_STATE_DELETING, wantRelease: true}, + {name: "resuming is left to its resume", state: ateapi.ActorState_ACTOR_STATE_RESUMING, wantState: ateapi.ActorState_ACTOR_STATE_RESUMING}, + {name: "deleting stays deleting", state: ateapi.ActorState_ACTOR_STATE_DELETING, wantState: ateapi.ActorState_ACTOR_STATE_DELETING, wantRelease: true}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() _, persistence := newWorkerAPIService(t) seedEpochWorker(t, ctx, persistence, 1, 1) - actor := seedAPIActor(t, ctx, persistence, tc.state, func(a *ateapipb.Actor) { + actor := seedAPIActor(t, ctx, persistence, tc.state, func(a *ateapi.Actor) { switch tc.pointsAt { case unassigned: a.Status.WorkerAssignment = nil @@ -234,10 +234,10 @@ func TestReconcileAssignments_ReleasesOrphanedAssignments(t *testing.T) { ctx := context.Background() _, persistence := newWorkerAPIService(t) seedEpochWorker(t, ctx, persistence, 1, 1) - seedAPIActor(t, ctx, persistence, ateapipb.ActorState_ACTOR_STATE_RUNNING) + seedAPIActor(t, ctx, persistence, ateapi.ActorState_ACTOR_STATE_RUNNING) assignAPIWorker(t, ctx, persistence, apiWorkerName, "11111111-1111-1111-1111-111111111111") orphan := newAPIAssignment("22222222-2222-2222-2222-222222222222") - orphan.Actor = &ateapipb.ObjectRef{Atespace: "team-a", Name: "gone"} + orphan.Actor = &ateapi.ObjectRef{Atespace: "team-a", Name: "gone"} if err := persistence.BindActorToWorker(ctx, apiWorkerName, orphan, nil); err != nil { t.Fatalf("BindActorToWorker() failed: %v", err) } @@ -245,7 +245,7 @@ func TestReconcileAssignments_ReleasesOrphanedAssignments(t *testing.T) { mustReconcileAssignments(t, ctx, persistence) - if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("actor state = %v, want RUNNING: the assignment named another incarnation of it", got) } if a := firstAssignment(t, persistence, apiWorkerName); a != nil { @@ -261,7 +261,7 @@ func TestReconcileAssignments_WaitsForBusyActor(t *testing.T) { seedEpochWorker(t, ctx, persistence, 1, 1) seedRunningActor(t, ctx, persistence) orphan := newAPIAssignment("22222222-2222-2222-2222-222222222222") - orphan.Actor = &ateapipb.ObjectRef{Atespace: "team-a", Name: "gone"} + orphan.Actor = &ateapi.ObjectRef{Atespace: "team-a", Name: "gone"} if err := persistence.BindActorToWorker(ctx, apiWorkerName, orphan, nil); err != nil { t.Fatalf("BindActorToWorker() failed: %v", err) } @@ -275,7 +275,7 @@ func TestReconcileAssignments_WaitsForBusyActor(t *testing.T) { if !errors.Is(err, errActorBusy) { t.Fatalf("ReconcileAssignments() = %v, want errActorBusy", err) } - if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("actor state = %v, want RUNNING while its lease is held", got) } if _, err := persistence.GetWorkerAssignment(ctx, apiWorkerName, orphan.GetActorUid()); !errors.Is(err, store.ErrNotFound) { @@ -287,7 +287,7 @@ func TestReconcileAssignments_WaitsForBusyActor(t *testing.T) { lease.Close() mustReconcileAssignments(t, ctx, persistence) - if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("actor state = %v, want CRASHED once the lease is free", got) } if got := mustGetWorker(t, ctx, persistence).GetStatus().GetObservedEpoch(); got != 2 { @@ -318,7 +318,7 @@ func (s *hookedStore) AcquireLease(ctx context.Context, key string) (*store.Leas return s.Interface.AcquireLease(ctx, key) } -func (s *hookedStore) UpdateWorker(ctx context.Context, name string, precondition store.Precondition, mutate func(*ateapipb.Worker) error) (*ateapipb.Worker, error) { +func (s *hookedStore) UpdateWorker(ctx context.Context, name string, precondition store.Precondition, mutate func(*ateapi.Worker) error) (*ateapi.Worker, error) { runOnce(&s.beforeUpdateWorker) return s.Interface.UpdateWorker(ctx, name, precondition, mutate) } @@ -341,7 +341,7 @@ func TestReconcileAssignments_KeepsActorReboundSinceList(t *testing.T) { // As finalizeRunning does, the Actor records the epoch of the // process it was restored on. actor := mustGetActor(t, ctx, persistence) - if _, err := persistence.UpdateActor(ctx, apiActorRef, store.PreconditionFrom(actor), func(a *ateapipb.Actor) error { + if _, err := persistence.UpdateActor(ctx, apiActorRef, store.PreconditionFrom(actor), func(a *ateapi.Actor) error { a.Status.WorkerAssignment.WorkerEpoch = 2 return nil }); err != nil { @@ -352,7 +352,7 @@ func TestReconcileAssignments_KeepsActorReboundSinceList(t *testing.T) { t.Fatalf("ReconcileAssignments() failed: %v", err) } - if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("actor state = %v, want RUNNING", got) } if firstAssignment(t, persistence, apiWorkerName) == nil { @@ -384,7 +384,7 @@ func TestReconcileAssignments_RetriesRecordAfterConcurrentBind(t *testing.T) { if got := mustGetWorker(t, ctx, persistence).GetStatus().GetObservedEpoch(); got != 2 { t.Errorf("observed_epoch = %d, want 2", got) } - if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("actor state = %v, want CRASHED", got) } if _, err := persistence.GetWorkerAssignment(ctx, apiWorkerName, boundUID); err != nil { @@ -437,7 +437,7 @@ func TestReconcileAssignments_FailureKeepsObservedEpoch(t *testing.T) { } mustReconcileAssignments(t, ctx, persistence) - if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("actor state after the retry = %v, want CRASHED", got) } if got := mustGetWorker(t, ctx, persistence).GetStatus().GetObservedEpoch(); got != 2 { @@ -457,26 +457,26 @@ func TestAssignWorkerAttempt_LeavesWorkerEpochUnset(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) name := testWorkerUID("pod-1") - _, err := persistence.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: name}, + _, err := persistence.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: name}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "pod-1", WorkerPodUid: name, NodeName: "node-1", - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, RegisteredEpoch: 1, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(testSandboxRuntime()), }, }) if err != nil { t.Fatalf("CreateWorker: %v", err) } - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) cacheCtx, cancel := context.WithCancel(ctx) defer cancel() @@ -486,7 +486,7 @@ func TestAssignWorkerAttempt_LeavesWorkerEpochUnset(t *testing.T) { } w := &ActorWorkflow{store: persistence, workerCache: wc, scheduler: scheduling.New(wc)} - tmpl := &ateapipb.ActorTemplate{} + tmpl := &ateapi.ActorTemplate{} stored, _, err := w.assignWorkerAttempt(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, tmpl) if err != nil { t.Fatalf("assignWorkerAttempt: %v", err) diff --git a/cmd/ateapi/internal/controlapi/workflow_resume.go b/cmd/ateapi/internal/controlapi/workflow_resume.go index 85ba36756c..8f43df3dfe 100644 --- a/cmd/ateapi/internal/controlapi/workflow_resume.go +++ b/cmd/ateapi/internal/controlapi/workflow_resume.go @@ -22,6 +22,7 @@ import ( "slices" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/scheduling" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" @@ -31,7 +32,8 @@ import ( "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/volume" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/wait" @@ -49,11 +51,11 @@ type restoreTelemetry struct { // ResumeActor executes the workflow to resume a suspended actor. Idempotent: // a re-entered workflow fast-forwards past the steps a previous attempt // completed, deriving progress from the persisted actor alone. -func (w *ActorWorkflow) ResumeActor(ctx context.Context, actorRef resources.ActorRef) (_ *ateapipb.Actor, resumed bool, err error) { +func (w *ActorWorkflow) ResumeActor(ctx context.Context, actorRef resources.ActorRef) (_ *ateapi.Actor, resumed bool, err error) { ctx = preview.ContextWithOptIn(ctx) start := time.Now() - var actor *ateapipb.Actor - var actorTemplate *ateapipb.ActorTemplate + var actor *ateapi.Actor + var actorTemplate *ateapi.ActorTemplate var tele restoreTelemetry var wasRunning bool @@ -77,7 +79,7 @@ func (w *ActorWorkflow) ResumeActor(ctx context.Context, actorRef resources.Acto if err != nil { return nil, false, err } - if wasRunning = actor.GetStatus().GetState() == ateapipb.ActorState_ACTOR_STATE_RUNNING; wasRunning { + if wasRunning = actor.GetStatus().GetState() == ateapi.ActorState_ACTOR_STATE_RUNNING; wasRunning { return actor, false, nil } @@ -91,19 +93,19 @@ func (w *ActorWorkflow) ResumeActor(ctx context.Context, actorRef resources.Acto if err != nil { return nil, false, err } - if wasRunning = actor.GetStatus().GetState() == ateapipb.ActorState_ACTOR_STATE_RUNNING; wasRunning { + if wasRunning = actor.GetStatus().GetState() == ateapi.ActorState_ACTOR_STATE_RUNNING; wasRunning { return actor, false, nil } - var created *ateapipb.Actor + var created *ateapi.Actor if created, err = w.ensureVolumesCreated(leaseCtx, actorRef, actor, actorTemplate); err != nil { return nil, false, err } actor = created - var worker *ateapipb.Worker - var assigned *ateapipb.Actor + var worker *ateapi.Worker + var assigned *ateapi.Actor assigned, worker, err = w.ensureWorkerAssigned(leaseCtx, actorRef, actor, actorTemplate) if err != nil && shouldDetachFromNode(actor, err) { - var detached *ateapipb.Actor + var detached *ateapi.Actor if detached, err = w.detachFromFullNode(leaseCtx, actorRef, actor, actorTemplate, err); err != nil { return nil, false, err } @@ -122,7 +124,7 @@ func (w *ActorWorkflow) ResumeActor(ctx context.Context, actorRef resources.Acto if tele, workerEpoch, err = w.ensureAteletRestored(leaseCtx, actorRef, actor, actorTemplate, volumePublishContexts); err != nil { return nil, false, err } - var running *ateapipb.Actor + var running *ateapi.Actor if running, err = w.finalizeRunning(leaseCtx, actorRef, workerEpoch); err != nil { return nil, false, err } @@ -131,7 +133,7 @@ func (w *ActorWorkflow) ResumeActor(ctx context.Context, actorRef resources.Acto } // loadActorForResume fetches the current actor record and its template. -func (w *ActorWorkflow) loadActorForResume(ctx context.Context, actorRef resources.ActorRef) (_ *ateapipb.Actor, _ *ateapipb.ActorTemplate, err error) { +func (w *ActorWorkflow) loadActorForResume(ctx context.Context, actorRef resources.ActorRef) (_ *ateapi.Actor, _ *ateapi.ActorTemplate, err error) { ctx, done := stepSpan(ctx, "LoadActorForResume") defer func() { err = done(err) }() @@ -146,7 +148,7 @@ func (w *ActorWorkflow) loadActorForResume(ctx context.Context, actorRef resourc // If the actor is already running, there is no pending restore to prepare // for. Short-circuit immediately to avoid an unnecessary template read on // the hot resume path. - if actor.GetStatus().GetState() == ateapipb.ActorState_ACTOR_STATE_RUNNING { + if actor.GetStatus().GetState() == ateapi.ActorState_ACTOR_STATE_RUNNING { return actor, nil, nil } @@ -157,23 +159,18 @@ func (w *ActorWorkflow) loadActorForResume(ctx context.Context, actorRef resourc return actor, actorTemplate, nil } -// checkSnapshotURI fails with DataLoss when the URI of snapshotToResume does -// not parse. A local restore also names the snapshot's upload, so its URI -// must parse too. -func checkSnapshotURI(actorRef resources.ActorRef, actor *ateapipb.Actor) error { - snap := snapshotToResume(actor.GetStatus()) - if snap == nil { - return nil - } - if _, err := resources.ParseSnapshotURI(snap.GetDurableSnapshot().GetObject().GetSnapshotUri()); err != nil { - return apierror.DataLoss("Actor %s snapshot %s: %v", actorRef, snap.GetUuid(), err) +// checkSnapshotUpload fails with DataLoss when snapshotToResume records no +// upload. A local restore also names the snapshot's upload. +func checkSnapshotUpload(actorRef resources.ActorRef, actor *ateapi.Actor) error { + if snap := snapshotToResume(actor.GetStatus()); snap != nil && snap.GetDurableSnapshot() == nil { + return apierror.DataLoss("Actor %s snapshot %s records no upload", actorRef, snap.GetUuid()) } return nil } // templateReplaced reports whether snap was captured under a different // ActorTemplate than tmpl. An unstamped snapshot is treated as matching. -func templateReplaced(snap *ateapipb.Snapshot, tmpl *ateapipb.ActorTemplate) bool { +func templateReplaced(snap *ateapi.Snapshot, tmpl *ateapi.ActorTemplate) bool { capturedUnder := snap.GetActorTemplateUid() return capturedUnder != "" && capturedUnder != tmpl.GetMetadata().GetUid() } @@ -183,8 +180,8 @@ func templateReplaced(snap *ateapipb.Snapshot, tmpl *ateapipb.ActorTemplate) boo // every actor created from it, so atelet may serve its files from the // node-local cache; the actor's own is replaced by its next suspend, so // never, and so is one whose owner is not recorded. -func snapshotSharing(owner ateapipb.SnapshotOwner) ateletpb.SnapshotSharing { - if owner == ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG { +func snapshotSharing(owner ateapi.SnapshotOwner) ateletpb.SnapshotSharing { + if owner == ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG { return ateletpb.SnapshotSharing_SNAPSHOT_SHARING_SHARED } return ateletpb.SnapshotSharing_SNAPSHOT_SHARING_PRIVATE @@ -194,18 +191,18 @@ func snapshotSharing(owner ateapipb.SnapshotOwner) ateletpb.SnapshotSharing { // volume ID yet, persisting the resulting volume state (even when creation // partially failed, so progress is not lost) and returning the stored copy. // An actor being deleted gets no new volumes. -func (w *ActorWorkflow) ensureVolumesCreated(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor, actorTemplate *ateapipb.ActorTemplate) (_ *ateapipb.Actor, err error) { +func (w *ActorWorkflow) ensureVolumesCreated(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor, actorTemplate *ateapi.ActorTemplate) (_ *ateapi.Actor, err error) { ctx, done := stepSpan(ctx, "CreateVolumes") defer func() { err = done(err) }() - pending := slices.ContainsFunc(actor.GetStatus().GetExternalVolumes().GetVolumes(), func(vol *ateapipb.ExternalVolumeStatus) bool { + pending := slices.ContainsFunc(actor.GetStatus().GetExternalVolumes().GetVolumes(), func(vol *ateapi.ExternalVolumeStatus) bool { return vol.GetStorageVolumeId() == "" }) if !pending { markSkipped(ctx, "no volumes awaiting creation") return actor, nil } - if st := actor.GetStatus().GetState(); st == ateapipb.ActorState_ACTOR_STATE_DELETING { + if st := actor.GetStatus().GetState(); st == ateapi.ActorState_ACTOR_STATE_DELETING { return nil, apierror.FailedPrecondition("cannot create volumes for Actor %s in state %s", actorRef, st) } @@ -213,7 +210,7 @@ func (w *ActorWorkflow) ensureVolumesCreated(ctx context.Context, actorRef resou // createActorVolumes reports the state it got to even when it fails, so both // paths persist the same field. updatePrecondition := store.PreconditionFrom(actor) - persistVolumes := func(toUpdate *ateapipb.Actor) error { + persistVolumes := func(toUpdate *ateapi.Actor) error { toUpdate.Status.ExternalVolumes = externalVolumesStatus(volumes) return nil } @@ -237,25 +234,25 @@ func (w *ActorWorkflow) ensureVolumesCreated(ctx context.Context, actorRef resou // ensureWorkerAssigned assigns a worker and leaves the actor RESUMING. // Re-entry validates the recorded assignment before reuse. // Version conflicts re-read the actor before retrying. -func (w *ActorWorkflow) ensureWorkerAssigned(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor, actorTemplate *ateapipb.ActorTemplate) (_ *ateapipb.Actor, _ *ateapipb.Worker, err error) { +func (w *ActorWorkflow) ensureWorkerAssigned(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor, actorTemplate *ateapi.ActorTemplate) (_ *ateapi.Actor, _ *ateapi.Worker, err error) { ctx, done := stepSpan(ctx, "AssignWorker") defer func() { err = done(err) }() switch actor.GetStatus().GetState() { - case ateapipb.ActorState_ACTOR_STATE_RESUMING: + case ateapi.ActorState_ACTOR_STATE_RESUMING: worker, err := w.validateAssignedWorker(ctx, actorRef, actor, actorTemplate) if err != nil { return nil, nil, err } markSkipped(ctx, "actor already RESUMING with a valid worker assignment") return actor, worker, nil - case ateapipb.ActorState_ACTOR_STATE_SUSPENDED: + case ateapi.ActorState_ACTOR_STATE_SUSPENDED: default: - return nil, nil, apierror.FailedPrecondition("AssignWorker prerequisite not met for Actor: %s (got: %v, want %s)", actorRef, actor.GetStatus().GetState(), ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + return nil, nil, apierror.FailedPrecondition("AssignWorker prerequisite not met for Actor: %s (got: %v, want %s)", actorRef, actor.GetStatus().GetState(), ateapi.ActorState_ACTOR_STATE_SUSPENDED) } - var assignedActor *ateapipb.Actor - var assignedWorker *ateapipb.Worker + var assignedActor *ateapi.Actor + var assignedWorker *ateapi.Worker // ctxErr marks the loop ending between attempts, where no attempt ran and // so none recorded. var ctxErr error @@ -329,7 +326,7 @@ var assignmentBackoff = wait.Backoff{ // recordExhaustedAssignment writes the one record of an assignment loop that // ended without assigning. No worker was assigned, so no pool is named. -func (w *ActorWorkflow) recordExhaustedAssignment(ctx context.Context, elapsed time.Duration, actor *ateapipb.Actor, err error) { +func (w *ActorWorkflow) recordExhaustedAssignment(ctx context.Context, elapsed time.Duration, actor *ateapi.Actor, err error) { w.instruments.recordSchedulerAssignment(ctx, elapsed, ateattr.SchedulerOutcomeError, "", "", snapshotSandboxClass(actor), err) } @@ -338,7 +335,7 @@ func (w *ActorWorkflow) recordExhaustedAssignment(ctx context.Context, elapsed t // a RESUMING actor whose worker vanished, drained, was reassigned, or is no // longer eligible can never make progress on its own. A worker that is only // unavailable is reported as UNAVAILABLE for the caller to retry. -func (w *ActorWorkflow) validateAssignedWorker(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor, actorTemplate *ateapipb.ActorTemplate) (*ateapipb.Worker, error) { +func (w *ActorWorkflow) validateAssignedWorker(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor, actorTemplate *ateapi.ActorTemplate) (*ateapi.Worker, error) { assignment := actor.GetStatus().GetWorkerAssignment() if assignment == nil { slog.ErrorContext(ctx, "expected a worker assignment on a RESUMING actor, found none") @@ -361,7 +358,7 @@ func (w *ActorWorkflow) validateAssignedWorker(ctx context.Context, actorRef res } return nil, fmt.Errorf("failed to get already assigned worker for actor %w", err) } - if worker.GetStatus().GetState() == ateapipb.WorkerState_WORKER_STATE_DRAINING { + if worker.GetStatus().GetState() == ateapi.WorkerState_WORKER_STATE_DRAINING { slog.InfoContext(ctx, "Assigned worker is draining; crashing actor", slog.String("actor", actorRef.String()), slog.String("worker", worker.GetWorkerNamespace()+"/"+worker.GetWorkerPod())) @@ -373,7 +370,7 @@ func (w *ActorWorkflow) validateAssignedWorker(ctx context.Context, actorRef res // An unavailable worker may come back with its Actors intact. If its worker // process restarted instead, a retried resume restores this Actor on the // new process. - if worker.GetStatus().GetState() == ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE { + if worker.GetStatus().GetState() == ateapi.WorkerState_WORKER_STATE_UNAVAILABLE { return nil, apierror.Unavailable("worker %s assigned to actor %s is unavailable", worker.GetMetadata().GetName(), actorRef) } if !scheduling.Registered(worker) { @@ -412,13 +409,13 @@ func (w *ActorWorkflow) validateAssignedWorker(ctx context.Context, actorRef res // admittedResources is what an assignment books against its worker, or nil // when the actor declared no limits and so reserves nothing. -func admittedResources(constraints scheduling.Constraints) *ateapipb.Resources { +func admittedResources(constraints scheduling.Constraints) *ateapi.Resources { return constraints.Limits } // workerHoldingStaleClaim recovers a claim written before the Actor update. // It releases the claim if the Worker is no longer eligible. -func (w *ActorWorkflow) workerHoldingStaleClaim(ctx context.Context, actor *ateapipb.Actor, constraints scheduling.Constraints, relaxable bool) (*ateapipb.Worker, error) { +func (w *ActorWorkflow) workerHoldingStaleClaim(ctx context.Context, actor *ateapi.Actor, constraints scheduling.Constraints, relaxable bool) (*ateapi.Worker, error) { actorUID := actor.GetMetadata().GetUid() workerName, err := w.store.FindWorkerHostingActor(ctx, actorUID) if err != nil { @@ -460,9 +457,9 @@ func schedulerRecordable(err error) bool { // re-reads the actor: if the fresh copy can still be resumed the refreshed // actor is returned along with the conflict so the caller retries with clean // inputs; any other status aborts the resume. -func (w *ActorWorkflow) assignWorkerAttempt(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor, actorTemplate *ateapipb.ActorTemplate) (_ *ateapipb.Actor, _ *ateapipb.Worker, err error) { +func (w *ActorWorkflow) assignWorkerAttempt(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor, actorTemplate *ateapi.ActorTemplate) (_ *ateapi.Actor, _ *ateapi.Worker, err error) { // Checked before a worker is claimed. - if err := checkSnapshotURI(actorRef, actor); err != nil { + if err := checkSnapshotUpload(actorRef, actor); err != nil { return nil, nil, err } start := time.Now() @@ -511,8 +508,8 @@ func (w *ActorWorkflow) assignWorkerAttempt(ctx context.Context, actorRef resour return nil, nil, apierror.FailedPrecondition("worker %s has no node name", assignedWorker.GetMetadata().GetName()) } - assignment := &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{ + assignment := &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{ Atespace: actor.GetMetadata().GetAtespace(), Name: actor.GetMetadata().GetName(), }, @@ -527,7 +524,7 @@ func (w *ActorWorkflow) assignWorkerAttempt(ctx context.Context, actorRef resour // and two claims for the last place cannot both be admitted. // The bind evaluates the fresh row; record the assignment from the same view. bound := assignedWorker - admit := func(fresh *ateapipb.Worker) error { + admit := func(fresh *ateapi.Worker) error { if !w.scheduler.Applies(fresh, constraints) || !w.scheduler.HasRoom(fresh, constraints) { return errWorkerFilledUp } @@ -546,8 +543,8 @@ func (w *ActorWorkflow) assignWorkerAttempt(ctx context.Context, actorRef resour } newAssignment := workerAssignmentFrom(bound, snapRuntime) - storedActor, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapipb.Actor) error { - toUpdate.Status.State = ateapipb.ActorState_ACTOR_STATE_RESUMING + storedActor, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapi.Actor) error { + toUpdate.Status.State = ateapi.ActorState_ACTOR_STATE_RESUMING toUpdate.Status.WorkerAssignment = newAssignment toUpdate.Status.AssignedNode = newAssignment.GetNodeName() return nil @@ -563,7 +560,7 @@ func (w *ActorWorkflow) assignWorkerAttempt(ctx context.Context, actorRef resour return nil, nil, err } switch fresh.GetStatus().GetState() { - case ateapipb.ActorState_ACTOR_STATE_SUSPENDED: + case ateapi.ActorState_ACTOR_STATE_SUSPENDED: slog.InfoContext(ctx, "Retrying assignment due to actor version conflict", slog.Any("actor", actorRef)) return fresh, nil, err default: @@ -587,9 +584,9 @@ var errNoWorkerRoom = errors.New("no worker has room for the actor") // attempt re-runs scheduling. var errWorkerFilledUp = errors.New("picked worker no longer has room") -func workerAssignmentFrom(w *ateapipb.Worker, snapRuntime hardware.Requirement) *ateapipb.WorkerAssignment { - return &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: w.GetMetadata().GetName()}, +func workerAssignmentFrom(w *ateapi.Worker, snapRuntime hardware.Requirement) *ateapi.WorkerAssignment { + return &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: w.GetMetadata().GetName()}, WorkerNamespace: w.GetWorkerNamespace(), WorkerPool: w.GetWorkerPool(), WorkerPod: w.GetWorkerPod(), @@ -606,7 +603,7 @@ func workerAssignmentFrom(w *ateapipb.Worker, snapRuntime hardware.Requirement) // toAteletSandboxRuntime converts the control plane's ActorSandboxRuntime to // atelet's, which it mirrors field for field. -func toAteletSandboxRuntime(in *ateapipb.ActorSandboxRuntime) *ateletpb.ActorSandboxRuntime { +func toAteletSandboxRuntime(in *ateapi.ActorSandboxRuntime) *ateletpb.ActorSandboxRuntime { if in == nil { return nil } @@ -620,7 +617,7 @@ func toAteletSandboxRuntime(in *ateapipb.ActorSandboxRuntime) *ateletpb.ActorSan return out } -func schedulingConstraints(actor *ateapipb.Actor, tmpl *ateapipb.ActorTemplate) scheduling.Constraints { +func schedulingConstraints(actor *ateapi.Actor, tmpl *ateapi.ActorTemplate) scheduling.Constraints { snap := snapshotToResume(actor.GetStatus()) var requiredNodes []string if node := actor.GetStatus().GetAssignedNode(); node != "" { @@ -642,9 +639,9 @@ func schedulingConstraints(actor *ateapipb.Actor, tmpl *ateapipb.ActorTemplate) // snapshotToResume returns the snapshot ResumeActor restores from: the latest // one that is local or has a completed durable copy (a tag borrowed at // creation included), or nil when the actor has none and cold-boots. -func snapshotToResume(status *ateapipb.ActorStatus) *ateapipb.Snapshot { - return latestSnapshot(status, func(s *ateapipb.Snapshot) bool { - return s.GetLocality() != "" || s.GetDurableSnapshot().GetStatus() == ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED +func snapshotToResume(status *ateapi.ActorStatus) *ateapi.Snapshot { + return latestSnapshot(status, func(s *ateapi.Snapshot) bool { + return s.GetLocality() != "" || s.GetDurableSnapshot().GetStatus() == ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED }) } @@ -652,41 +649,46 @@ func snapshotToResume(status *ateapipb.ActorStatus) *ateapipb.Snapshot { // when the actor has none and cold-boots. Unlike requiredSnapshotRuntime it // does not depend on fidelity: a worker of another class cannot read the // snapshot's files even for a volumes-only restore. -func snapshotSandboxClass(actor *ateapipb.Actor) string { +func snapshotSandboxClass(actor *ateapi.Actor) string { return snapshotToResume(actor.GetStatus()).GetSandboxRuntime().GetSandboxClass() } // requiredSnapshotRuntime returns the ActorSandboxRuntime stamped on snap, the // snapshotToResume, when the resume restores its memory state, or nil when it // does not (cold boot, ROOTFS or VOLUMES fidelity, or replaced template). -func requiredSnapshotRuntime(snap *ateapipb.Snapshot, tmpl *ateapipb.ActorTemplate) *ateapipb.ActorSandboxRuntime { - if snap.GetFidelity() != ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY || templateReplaced(snap, tmpl) { +func requiredSnapshotRuntime(snap *ateapi.Snapshot, tmpl *ateapi.ActorTemplate) *ateapi.ActorSandboxRuntime { + if snap.GetFidelity() != ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY || templateReplaced(snap, tmpl) { return nil } return snap.GetSandboxRuntime() } // canRelaxRuntime reports whether scheduling may drop its runtime requirement. -func canRelaxRuntime(actor *ateapipb.Actor, constraints scheduling.Constraints) bool { +func canRelaxRuntime(actor *ateapi.Actor, constraints scheduling.Constraints) bool { if constraints.RequiredRuntime.Runtime() == nil { return false } status := actor.GetStatus() // A pinned actor detaches first, so a compatible worker elsewhere can keep // its memory state. - if status.GetState() == ateapipb.ActorState_ACTOR_STATE_SUSPENDED && status.GetAssignedNode() != "" { + if status.GetState() == ateapi.ActorState_ACTOR_STATE_SUSPENDED && status.GetAssignedNode() != "" { return false } snap := snapshotToResume(status) if snap.GetLocality() == "" { return true } - return snap.GetDurableSnapshot().GetStatus() == ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + // Its node was deleted, so it restores from its upload, as a durable + // snapshot does. + if localElsewhere(snap, status.GetAssignedNode()) { + return true + } + return snap.GetDurableSnapshot().GetStatus() == ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED } // appliesWithFallback reports whether worker satisfies constraints, or — when // relaxable — satisfies constraints with RequiredRuntime relaxed. -func (w *ActorWorkflow) appliesWithFallback(worker *ateapipb.Worker, constraints scheduling.Constraints, relaxable bool) bool { +func (w *ActorWorkflow) appliesWithFallback(worker *ateapi.Worker, constraints scheduling.Constraints, relaxable bool) bool { relaxed := constraints relaxed.RequiredRuntime = hardware.Requirement{} if !w.scheduler.Applies(worker, relaxed) { @@ -701,7 +703,7 @@ func (w *ActorWorkflow) appliesWithFallback(worker *ateapipb.Worker, constraints // provisioned with a storage volume ID; otherwise nothing is attached. // Attachment is idempotent, so a re-entered workflow safely runs it again. // TODO replace re-execution with a proper check on the volumes' attach state. -func (w *ActorWorkflow) ensureVolumesAttached(ctx context.Context, actor *ateapipb.Actor, worker *ateapipb.Worker, actorTemplate *ateapipb.ActorTemplate) (_ map[string]map[string]string, err error) { +func (w *ActorWorkflow) ensureVolumesAttached(ctx context.Context, actor *ateapi.Actor, worker *ateapi.Worker, actorTemplate *ateapi.ActorTemplate) (_ map[string]map[string]string, err error) { ctx, done := stepSpan(ctx, "AttachVolumes") defer func() { err = done(err) }() @@ -714,7 +716,7 @@ func (w *ActorWorkflow) ensureVolumesAttached(ctx context.Context, actor *ateapi return nil, fmt.Errorf("assigned worker has no node name") } - ref := &ateapipb.ObjectRef{Atespace: actor.GetMetadata().GetAtespace(), Name: actor.GetMetadata().GetName()} + ref := &ateapi.ObjectRef{Atespace: actor.GetMetadata().GetAtespace(), Name: actor.GetMetadata().GetName()} volumes := getMountedActorVolumes(ctx, ref, actor.GetStatus().GetExternalVolumes().GetVolumes(), actorTemplate) // Check every volume before attaching any, so a bad one cannot leave the // ones before it published. @@ -741,7 +743,7 @@ func (w *ActorWorkflow) ensureVolumesAttached(ctx context.Context, actor *ateapi // checkVolumesAttachable returns FailedPrecondition unless every volume has a // storage volume ID. -func checkVolumesAttachable(volumes []*ateapipb.ExternalVolumeStatus) error { +func checkVolumesAttachable(volumes []*ateapi.ExternalVolumeStatus) error { for _, vol := range volumes { if vol.GetStorageVolumeId() == "" { return apierror.FailedPrecondition("volume %q has no storage volume ID to attach", vol.GetName()) @@ -757,12 +759,12 @@ func checkVolumesAttachable(volumes []*ateapipb.ExternalVolumeStatus) error { // the worker pod UID, so a re-entered workflow re-sends the same semantic // request; once atelet's Restore/Run are idempotent on those keys this step // becomes fully reentrant with no changes here. -func (w *ActorWorkflow) ensureAteletRestored(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor, actorTemplate *ateapipb.ActorTemplate, volumePublishContexts map[string]map[string]string) (tele restoreTelemetry, workerEpoch int64, err error) { +func (w *ActorWorkflow) ensureAteletRestored(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor, actorTemplate *ateapi.ActorTemplate, volumePublishContexts map[string]map[string]string) (tele restoreTelemetry, workerEpoch int64, err error) { ctx, done := stepSpan(ctx, "CallAteletRestore") defer func() { err = done(err) }() // A re-entered resume skips assignWorkerAttempt, which checks this too. - if err := checkSnapshotURI(actorRef, actor); err != nil { + if err := checkSnapshotUpload(actorRef, actor); err != nil { return tele, 0, err } @@ -815,7 +817,7 @@ func (w *ActorWorkflow) ensureAteletRestored(ctx context.Context, actorRef resou slog.InfoContext(ctx, "Actor has snapshot; Restoring from snapshot", slog.String("snapshot_uuid", snap.GetUuid())) tele.SnapshotKind = ateattr.SnapshotKindLatest - if snap.GetLocality() != "" { + if snap.GetLocality() != "" && snap.GetLocality() == assignment.GetNodeName() { tele.SnapshotKind = ateattr.SnapshotKindLocal } @@ -862,6 +864,13 @@ func (w *ActorWorkflow) ensureAteletRestored(ctx context.Context, actorRef resou } resp, err := client.Restore(ctx, req) if err != nil { + // The snapshot's node is gone, and atelet found no upload of it. + if ctx.Err() == nil && status.Code(err) == codes.NotFound && localElsewhere(snap, assignment.GetNodeName()) { + slog.LogAttrs(ctx, slog.LevelError, "Setting Actor to crashed due to Atelet error", + append(ateattr.ActorRefLogAttrs(actorRef), slog.Any("err", err))...) + message := fmt.Sprintf("%s: %s", crashMessageLocalSnapshotNodeGone, ateletCrashMessage("Restore", err)) + return tele, 0, crashActorAndFail(ctx, w.store, actorRef, ateattr.OperationResume, message) + } return tele, 0, handleAteletError(ctx, w.store, actorRef, ateattr.OperationResume, "Restore", false, err) } return tele, resp.GetWorkerEpoch(), nil @@ -870,7 +879,7 @@ func (w *ActorWorkflow) ensureAteletRestored(ctx context.Context, actorRef resou // logRuntimeFallback records a resume that restores without memory state // because the assigned worker does not run the runtime the snapshot's memory // state was captured under. -func logRuntimeFallback(ctx context.Context, actorRef resources.ActorRef, assignment *ateapipb.WorkerAssignment, required *ateapipb.ActorSandboxRuntime) { +func logRuntimeFallback(ctx context.Context, actorRef resources.ActorRef, assignment *ateapi.WorkerAssignment, required *ateapi.ActorSandboxRuntime) { slog.WarnContext(ctx, "Assigned worker cannot restore the snapshot's runtime; restoring without memory state", slog.String("actor", actorRef.String()), slog.String("worker", assignment.GetWorkerPod()), @@ -894,7 +903,7 @@ func (w *ActorWorkflow) egressGateway() *ateletpb.EgressGateway { // started did not carry. If a later epoch is registered, that process has exited and taken // the sandbox with it, so RUNNING is not committed: the error is Unavailable, // and the retried resume restores the Actor on the current process. -func (w *ActorWorkflow) finalizeRunning(ctx context.Context, actorRef resources.ActorRef, workerEpoch int64) (_ *ateapipb.Actor, err error) { +func (w *ActorWorkflow) finalizeRunning(ctx context.Context, actorRef resources.ActorRef, workerEpoch int64) (_ *ateapi.Actor, err error) { ctx, done := stepSpan(ctx, "FinalizeRunning") defer func() { err = done(err) }() @@ -923,10 +932,16 @@ func (w *ActorWorkflow) finalizeRunning(ctx context.Context, actorRef resources. return nil, apierror.Internal("worker %s reported epoch %d, above its registered epoch %d", workerName, workerEpoch, registered) } - storedActor, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(latestActor), func(toUpdate *ateapipb.Actor) error { - toUpdate.Status.State = ateapipb.ActorState_ACTOR_STATE_RUNNING + storedActor, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(latestActor), func(toUpdate *ateapi.Actor) error { + toUpdate.Status.State = ateapi.ActorState_ACTOR_STATE_RUNNING toUpdate.Status.WorkerAssignment.WorkerEpoch = workerEpoch toUpdate.Status.WorkerAssignment.WorkerPodIps = slices.Clone(worker.GetStatus().GetIps()) + // The workload already runs, so a record that can't take the upload + // doesn't hold the actor in RESUMING. The next suspend prunes the entry. + if err := recordRestoredUpload(ctx, toUpdate.Status); err != nil { + slog.WarnContext(ctx, "Restored a snapshot from its upload but could not record the upload", + slog.Any("actor", actorRef), slog.Any("err", err)) + } return nil }) if err != nil { @@ -938,3 +953,24 @@ func (w *ActorWorkflow) finalizeRunning(ctx context.Context, actorRef resources. logActorStateChanged(ctx, storedActor, ateattr.OperationResume) return storedActor, nil } + +// recordRestoredUpload records the upload of a snapshot that resume restored +// on another node after its own node was deleted. The restore proved the +// upload complete, and the deleted node no longer holds a copy. On an error +// it leaves status unchanged. +func recordRestoredUpload(ctx context.Context, status *ateapi.ActorStatus) error { + snap := snapshotToResume(status) + if !localElsewhere(snap, status.GetAssignedNode()) { + return nil + } + node := snap.GetLocality() + if err := applyLatestDurable(ctx, status, &ateapi.SnapshotReport{ + Uuid: snap.GetUuid(), + Generation: snap.GetGeneration(), + Fidelity: snap.GetFidelity(), + Object: snap.GetDurableSnapshot().GetObject(), + }); err != nil { + return err + } + return applyDetach(status, node, snap.GetGeneration()) +} diff --git a/cmd/ateapi/internal/controlapi/workflow_resume_detach.go b/cmd/ateapi/internal/controlapi/workflow_resume_detach.go index 665ed311d5..3b9495995c 100644 --- a/cmd/ateapi/internal/controlapi/workflow_resume_detach.go +++ b/cmd/ateapi/internal/controlapi/workflow_resume_detach.go @@ -20,14 +20,13 @@ import ( "fmt" "log/slog" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/scheduling" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" - "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/hardware" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" @@ -35,16 +34,17 @@ import ( // shouldDetachFromNode reports whether a SUSPENDED actor's assignment failed // for lack of room on the node it is pinned to. -func shouldDetachFromNode(actor *ateapipb.Actor, assignErr error) bool { +func shouldDetachFromNode(actor *ateapi.Actor, assignErr error) bool { return errors.Is(assignErr, errNoWorkerRoom) && - actor.GetStatus().GetState() == ateapipb.ActorState_ACTOR_STATE_SUSPENDED && + actor.GetStatus().GetState() == ateapi.ActorState_ACTOR_STATE_SUSPENDED && actor.GetStatus().GetAssignedNode() != "" } // detachFromFullNode releases the node binding so scheduling can retry. // Unreachable nodes can be forgotten when the latest local snapshot is durable. -// A deleted node crashes the actor when that snapshot is not durable. -func (w *ActorWorkflow) detachFromFullNode(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor, actorTemplate *ateapipb.ActorTemplate, assignErr error) (_ *ateapipb.Actor, err error) { +// A deleted node is released even when that snapshot is not durable, so resume +// tries its upload. +func (w *ActorWorkflow) detachFromFullNode(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor, actorTemplate *ateapi.ActorTemplate, assignErr error) (_ *ateapi.Actor, err error) { ctx, done := stepSpan(ctx, "DetachFromFullNode") defer func() { err = done(err) }() @@ -115,13 +115,13 @@ func (w *ActorWorkflow) detachFromFullNode(ctx context.Context, actorRef resourc // loadPinnedActor reads the actor, and fails with Aborted unless it is still // the SUSPENDED incarnation uid, pinned to node. -func (w *ActorWorkflow) loadPinnedActor(ctx context.Context, actorRef resources.ActorRef, uid, node string) (*ateapipb.Actor, error) { +func (w *ActorWorkflow) loadPinnedActor(ctx context.Context, actorRef resources.ActorRef, uid, node string) (*ateapi.Actor, error) { actor, err := w.store.GetActor(ctx, actorRef) if err != nil { return nil, fmt.Errorf("while reading Actor %s: %w", actorRef, err) } if actor.GetMetadata().GetUid() != uid || - actor.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED || + actor.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED || actor.GetStatus().GetAssignedNode() != node { return nil, apierror.Aborted("Actor %s changed during the resume, please retry", actorRef) } @@ -130,7 +130,7 @@ func (w *ActorWorkflow) loadPinnedActor(ctx context.Context, actorRef resources. // recordDetach forgets local copies after the latest local generation is durable. // state may be nil when atelet is unreachable. -func (w *ActorWorkflow) recordDetach(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor, node string, state *ateletpb.ActorSnapshotState) (*ateapipb.Actor, error) { +func (w *ActorWorkflow) recordDetach(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor, node string, state *ateletpb.ActorSnapshotState) (*ateapi.Actor, error) { applied := proto.CloneOf(actor.GetStatus()) if err := applyLatestDurable(ctx, applied, snapshotReportFromAtelet(state.GetLatestDurable())); err != nil { return nil, apierror.Internal("atelet on node %q reported a state for Actor %s that conflicts with its record: %w", node, actorRef, err) @@ -139,10 +139,10 @@ func (w *ActorWorkflow) recordDetach(ctx context.Context, actorRef resources.Act if err := applyDetach(applied, node, applied.GetLastAssignedGeneration()); err != nil { return nil, err } - if applied.GetState() == ateapipb.ActorState_ACTOR_STATE_REVERTING && applied.GetWorkerAssignment() == nil { + if applied.GetState() == ateapi.ActorState_ACTOR_STATE_REVERTING && applied.GetWorkerAssignment() == nil { applied.AssignedNode = "" } - stored, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapipb.Actor) error { + stored, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapi.Actor) error { // The precondition makes toUpdate the version applied was built from. toUpdate.Status.Snapshots = applied.GetSnapshots() toUpdate.Status.AssignedNode = applied.GetAssignedNode() @@ -157,10 +157,12 @@ func (w *ActorWorkflow) recordDetach(ctx context.Context, actorRef resources.Act return stored, nil } -// recordGoneNode crashes an actor whose latest snapshot went with its deleted -// node. It reads the actor again first, so an upload recorded during the node -// lookup detaches it instead, and it crashes only the version it checked. -func (w *ActorWorkflow) recordGoneNode(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor, node string) (*ateapipb.Actor, error) { +// recordGoneNode releases an actor from its deleted node when its latest +// snapshot is not recorded durable. atelet may have uploaded it without +// reporting, so the snapshot keeps its locality and resume restores it from +// the upload on another node. It reads the actor again first, so an upload +// recorded during the node lookup detaches it instead. +func (w *ActorWorkflow) recordGoneNode(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor, node string) (*ateapi.Actor, error) { actor, err := w.loadPinnedActor(ctx, actorRef, actor.GetMetadata().GetUid(), node) if err != nil { return nil, err @@ -168,23 +170,38 @@ func (w *ActorWorkflow) recordGoneNode(ctx context.Context, actorRef resources.A if !latestLocalNotDurable(actor) { return w.recordDetach(ctx, actorRef, actor, node, nil) } - if err := crashActorVersion(ctx, w.store, actorRef, actor, ateattr.OperationResume, crashMessageLocalSnapshotNodeGone); err != nil { + stored, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapi.Actor) error { + toUpdate.Status.AssignedNode = "" + return nil + }) + if err != nil { if errors.Is(err, store.ErrVersionConflict) { return nil, apierror.Aborted("Actor %s changed during the resume, please retry", actorRef) } - return nil, err + return nil, fmt.Errorf("while releasing Actor %s from deleted node %q: %w", actorRef, node, err) } - return nil, apierror.FailedPrecondition("actor %s is CRASHED: %s", actorRef, crashMessageLocalSnapshotNodeGone) + slog.InfoContext(ctx, "Released actor from its deleted node to restore its snapshot's upload on another node", + slog.Any("actor", actorRef), + slog.String("node", node), + slog.Int("generation", int(findLatestLocalSnapshot(stored.GetStatus()).GetGeneration()))) + return stored, nil +} + +// localElsewhere reports whether snap is recorded local on a node other than +// node. Resume restores such a snapshot from its upload after recordGoneNode +// released its deleted node. +func localElsewhere(snap *ateapi.Snapshot, node string) bool { + return snap.GetLocality() != "" && snap.GetLocality() != node } // latestLocalNotDurable reports whether the actor's latest local snapshot has // no completed durable copy. -func latestLocalNotDurable(actor *ateapipb.Actor) bool { +func latestLocalNotDurable(actor *ateapi.Actor) bool { local := findLatestLocalSnapshot(actor.GetStatus()) - return local != nil && local.GetDurableSnapshot().GetStatus() != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + return local != nil && local.GetDurableSnapshot().GetStatus() != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED } -func canDetachWithoutAtelet(ctx context.Context, actor *ateapipb.Actor, err error) bool { +func canDetachWithoutAtelet(ctx context.Context, actor *ateapi.Actor, err error) bool { if ctx.Err() != nil || actor.GetStatus().GetWorkerAssignment() != nil { return false } @@ -200,7 +217,7 @@ func canDetachWithoutAtelet(ctx context.Context, actor *ateapipb.Actor, err erro return false } local := findLatestLocalSnapshot(actor.GetStatus()) - return local != nil && local.GetDurableSnapshot().GetStatus() == ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + return local != nil && local.GetDurableSnapshot().GetStatus() == ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED } // detachActorError maps a DetachActor error to the one the resume fails with. diff --git a/cmd/ateapi/internal/controlapi/workflow_resume_detach_test.go b/cmd/ateapi/internal/controlapi/workflow_resume_detach_test.go index 74b79e4ac1..e4848bcd57 100644 --- a/cmd/ateapi/internal/controlapi/workflow_resume_detach_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_resume_detach_test.go @@ -21,6 +21,7 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/scheduling" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" @@ -29,7 +30,6 @@ import ( "go.ate.dev/substrate/internal/installdefaults" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" corev1 "k8s.io/api/core/v1" @@ -54,16 +54,16 @@ func newDetachTestWorkflow(t *testing.T, ctx context.Context, st store.Interface } // fillWorker binds another actor to worker, using up its one place. -func fillWorker(t *testing.T, st store.Interface, worker *ateapipb.Worker) { +func fillWorker(t *testing.T, st store.Interface, worker *ateapi.Worker) { t.Helper() - seedAssignment(t, st, worker.GetMetadata().GetName(), &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "other"}, + seedAssignment(t, st, worker.GetMetadata().GetName(), &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "other"}, ActorUid: "other-uid", }) } // detachedState is atelet's state after detaching snap. -func detachedState(snap *ateapipb.Snapshot) *ateletpb.ActorSnapshotState { +func detachedState(snap *ateapi.Snapshot) *ateletpb.ActorSnapshotState { return &ateletpb.ActorSnapshotState{LatestDurable: &ateletpb.SnapshotReport{Snapshot: &ateletpb.Snapshot{ SnapshotUuid: snap.GetUuid(), Generation: snap.GetGeneration(), @@ -74,21 +74,21 @@ func detachedState(snap *ateapipb.Snapshot) *ateletpb.ActorSnapshotState { func TestShouldDetachFromNode(t *testing.T) { noRoom := apierror.ResourceExhausted("%w", errNoWorkerRoom) - pinned := func(state ateapipb.ActorState, node string) *ateapipb.Actor { - return &ateapipb.Actor{Status: &ateapipb.ActorStatus{State: state, AssignedNode: node}} + pinned := func(state ateapi.ActorState, node string) *ateapi.Actor { + return &ateapi.Actor{Status: &ateapi.ActorStatus{State: state, AssignedNode: node}} } tests := []struct { name string - actor *ateapipb.Actor + actor *ateapi.Actor err error want bool }{ - {"pinned suspended actor with no room", pinned(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), noRoom, true}, - {"no room wrapped by a step", pinned(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), errors.Join(noRoom), true}, - {"assigned", pinned(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), nil, false}, - {"another error", pinned(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), apierror.Aborted("conflict"), false}, - {"not pinned", pinned(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, ""), noRoom, false}, - {"resuming", pinned(ateapipb.ActorState_ACTOR_STATE_RESUMING, "node-1"), noRoom, false}, + {"pinned suspended actor with no room", pinned(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), noRoom, true}, + {"no room wrapped by a step", pinned(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), errors.Join(noRoom), true}, + {"assigned", pinned(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), nil, false}, + {"another error", pinned(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), apierror.Aborted("conflict"), false}, + {"not pinned", pinned(ateapi.ActorState_ACTOR_STATE_SUSPENDED, ""), noRoom, false}, + {"resuming", pinned(ateapi.ActorState_ACTOR_STATE_RESUMING, "node-1"), noRoom, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -102,7 +102,7 @@ func TestShouldDetachFromNode(t *testing.T) { // TestDetachFromFullNode runs the step for an actor pinned to a full node. func TestDetachFromFullNode(t *testing.T) { actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - suspended := ateapipb.ActorState_ACTOR_STATE_SUSPENDED + suspended := ateapi.ActorState_ACTOR_STATE_SUSPENDED const uuid = "pause-snap-1" noRoom := apierror.ResourceExhausted("%w", errNoWorkerRoom) amd64RT := testRuntime("amd64", "") @@ -115,9 +115,9 @@ func TestDetachFromFullNode(t *testing.T) { // otherNode adds a free worker on node-2 with otherRuntime, or the // test runtime when unset. otherNode bool - otherRuntime *ateapipb.ActorSandboxRuntime + otherRuntime *ateapi.ActorSandboxRuntime // snapRuntime stamps the MEMORY snapshot. - snapRuntime *ateapipb.ActorSandboxRuntime + snapRuntime *ateapi.ActorSandboxRuntime // completed records the snapshot's upload COMPLETED. completed bool cancel bool @@ -131,12 +131,13 @@ func TestDetachFromFullNode(t *testing.T) { completeOnNodeLookup bool // before updates the actor after it was read and before the step // runs, and during while atelet detaches it. - before, during func(*ateapipb.Actor) + before, during func(*ateapi.Actor) // detachState builds DetachActor's reply from the snapshot. - detachState func(*ateapipb.Snapshot) *ateletpb.ActorSnapshotState + detachState func(*ateapi.Snapshot) *ateletpb.ActorSnapshotState detachErr error wantDetached bool - wantCrashed bool + // wantReleased expects the node released with the snapshot unchanged. + wantReleased bool wantCode codes.Code // wantErrText is text the error must contain. wantErrText string @@ -161,7 +162,7 @@ func TestDetachFromFullNode(t *testing.T) { name: "actor updated after it was read: detaches", node: "node-1", otherNode: true, - before: func(*ateapipb.Actor) {}, + before: func(*ateapi.Actor) {}, detachState: detachedState, wantDetached: true, wantCall: true, @@ -169,15 +170,15 @@ func TestDetachFromFullNode(t *testing.T) { name: "selector changed after the actor was read: no room under the new one", node: "node-1", otherNode: true, - before: func(a *ateapipb.Actor) { - a.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}} + before: func(a *ateapi.Actor) { + a.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}} }, wantCode: codes.ResourceExhausted, }, { name: "actor updated while atelet detaches: Aborted, record unchanged", node: "node-1", otherNode: true, - during: func(*ateapipb.Actor) {}, + during: func(*ateapi.Actor) {}, detachState: detachedState, wantCode: codes.Aborted, wantCall: true, @@ -186,14 +187,14 @@ func TestDetachFromFullNode(t *testing.T) { node: "node-1", otherNode: true, completed: true, - detachState: func(*ateapipb.Snapshot) *ateletpb.ActorSnapshotState { return &ateletpb.ActorSnapshotState{} }, + detachState: func(*ateapi.Snapshot) *ateletpb.ActorSnapshotState { return &ateletpb.ActorSnapshotState{} }, wantDetached: true, wantCall: true, }, { name: "atelet holds no entry, upload PENDING: FailedPrecondition, record unchanged", node: "node-1", otherNode: true, - detachState: func(*ateapipb.Snapshot) *ateletpb.ActorSnapshotState { return &ateletpb.ActorSnapshotState{} }, + detachState: func(*ateapi.Snapshot) *ateletpb.ActorSnapshotState { return &ateletpb.ActorSnapshotState{} }, wantCode: codes.FailedPrecondition, wantCall: true, }, { @@ -236,7 +237,7 @@ func TestDetachFromFullNode(t *testing.T) { node: "node-1", otherNode: true, completed: true, - during: func(*ateapipb.Actor) {}, + during: func(*ateapi.Actor) {}, detachErr: apierror.Unavailable("connection refused"), wantCode: codes.Aborted, wantCall: true, @@ -268,12 +269,11 @@ func TestDetachFromFullNode(t *testing.T) { nodeGone: true, wantDetached: true, }, { - name: "node gone, upload PENDING: crashes on its node", - node: "node-3", - otherNode: true, - nodeGone: true, - wantCrashed: true, - wantCode: codes.FailedPrecondition, + name: "node gone, upload PENDING: releases the node, keeps the snapshot", + node: "node-3", + otherNode: true, + nodeGone: true, + wantReleased: true, }, { name: "node gone, upload completes during the node lookup: detaches", node: "node-3", @@ -290,8 +290,8 @@ func TestDetachFromFullNode(t *testing.T) { otherNode: true, completed: true, nodeGone: true, - before: func(a *ateapipb.Actor) { - a.Status.Crash = &ateapipb.ActorCrash{Message: "restore failed"} + before: func(a *ateapi.Actor) { + a.Status.Crash = &ateapi.ActorCrash{Message: "restore failed"} }, wantCode: codes.Unavailable, }, { @@ -327,7 +327,7 @@ func TestDetachFromFullNode(t *testing.T) { name: "atelet keeps a local copy: Internal, actor stays on its node", node: "node-1", otherNode: true, - detachState: func(snap *ateapipb.Snapshot) *ateletpb.ActorSnapshotState { + detachState: func(snap *ateapi.Snapshot) *ateletpb.ActorSnapshotState { st := detachedState(snap) st.LatestLocal = st.GetLatestDurable() return st @@ -338,7 +338,7 @@ func TestDetachFromFullNode(t *testing.T) { name: "returned state conflicts with the record: Internal, actor stays on its node", node: "node-1", otherNode: true, - detachState: func(snap *ateapipb.Snapshot) *ateletpb.ActorSnapshotState { + detachState: func(snap *ateapi.Snapshot) *ateletpb.ActorSnapshotState { st := detachedState(snap) st.LatestDurable.Snapshot.Object.SnapshotUri = someActorSnapshotURI(t, testStorageLocation, "team-a", "other") return st @@ -359,10 +359,10 @@ func TestDetachFromFullNode(t *testing.T) { } seedRuntimeWorker(t, ctx, st, "pod-2", "node-2", otherRuntime) } - snap := newPausedSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", uuid, tt.node) + snap := newPausedSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", uuid, tt.node) snap.SandboxRuntime = tt.snapRuntime if tt.completed { - snap.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + snap.DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED } actor := seedActorWithSnapshot(t, ctx, st, suspended, tt.node, snap) w, atelet := newDetachTestWorkflow(t, ctx, st) @@ -389,8 +389,8 @@ func TestDetachFromFullNode(t *testing.T) { cur, err := st.GetActor(ctx, actorRef) if err != nil { t.Errorf("GetActor: %v", err) - } else if _, err := st.UpdateActor(ctx, actorRef, store.PreconditionFrom(cur), func(a *ateapipb.Actor) error { - a.Status.Snapshots[0].DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + } else if _, err := st.UpdateActor(ctx, actorRef, store.PreconditionFrom(cur), func(a *ateapi.Actor) error { + a.Status.Snapshots[0].DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED return nil }); err != nil { t.Errorf("UpdateActor: %v", err) @@ -404,13 +404,13 @@ func TestDetachFromFullNode(t *testing.T) { } atelet.detachErr = tt.detachErr // update writes mutate to the stored actor, moving its version on. - update := func(mutate func(*ateapipb.Actor)) { + update := func(mutate func(*ateapi.Actor)) { t.Helper() cur, err := st.GetActor(ctx, actorRef) if err != nil { t.Fatalf("GetActor: %v", err) } - if _, err := st.UpdateActor(ctx, actorRef, store.PreconditionFrom(cur), func(toUpdate *ateapipb.Actor) error { + if _, err := st.UpdateActor(ctx, actorRef, store.PreconditionFrom(cur), func(toUpdate *ateapi.Actor) error { mutate(toUpdate) return nil }); err != nil { @@ -432,7 +432,7 @@ func TestDetachFromFullNode(t *testing.T) { t.Fatalf("GetActor: %v", err) } - stored, err := w.detachFromFullNode(ctx, actorRef, actor, &ateapipb.ActorTemplate{}, noRoom) + stored, err := w.detachFromFullNode(ctx, actorRef, actor, &ateapi.ActorTemplate{}, noRoom) if got := apierror.Code(err); got != tt.wantCode { t.Fatalf("detachFromFullNode() = %v, want code %v", err, tt.wantCode) } @@ -454,17 +454,16 @@ func TestDetachFromFullNode(t *testing.T) { if err != nil { t.Fatalf("GetActor: %v", err) } - if tt.wantCrashed { - // Only the state and crash change. The node and the PENDING - // snapshot stay for revert to clean up. - crashed := proto.CloneOf(want.GetStatus()) - crashed.State = ateapipb.ActorState_ACTOR_STATE_CRASHED - crashed.Crash = after.GetStatus().GetCrash() - if !proto.Equal(after.GetStatus(), crashed) { - t.Errorf("status = %v, want %v", after.GetStatus(), crashed) + if tt.wantReleased { + // Only assigned_node changes. The PENDING snapshot keeps its + // locality, so the resume restores it from its upload. + released := proto.CloneOf(want.GetStatus()) + released.AssignedNode = "" + if !proto.Equal(after.GetStatus(), released) { + t.Errorf("status = %v, want %v", after.GetStatus(), released) } - if got := after.GetStatus().GetCrash().GetMessage(); !strings.Contains(got, crashMessageLocalSnapshotNodeGone) { - t.Errorf("crash message = %q, want %q", got, crashMessageLocalSnapshotNodeGone) + if !proto.Equal(stored, after) { + t.Errorf("returned actor = %v, want the stored %v", stored, after) } return } @@ -482,7 +481,7 @@ func TestDetachFromFullNode(t *testing.T) { } got := after.GetStatus().GetSnapshots() if len(got) != 1 || got[0].GetLocality() != "" || - got[0].GetDurableSnapshot().GetStatus() != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { + got[0].GetDurableSnapshot().GetStatus() != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { t.Errorf("snapshots = %v, want %s durable only and COMPLETED", got, uuid) } }) @@ -507,24 +506,24 @@ func TestResumeActor_DetachesFromFullNode(t *testing.T) { actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} storetest.MustCreateAtespace(t, ctx, st, "ns") - if _, err := st.CreateActorTemplate(ctx, &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ns", Name: "tmpl1"}, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation}, + if _, err := st.CreateActorTemplate(ctx, &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ns", Name: "tmpl1"}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}, }); err != nil { t.Fatalf("create template: %v", err) } - workers := map[string]*ateapipb.Worker{ + workers := map[string]*ateapi.Worker{ "node-1": seedRuntimeWorker(t, ctx, st, "pod-1", "node-1", testSandboxRuntime()), "node-2": seedRuntimeWorker(t, ctx, st, "pod-2", "node-2", testSandboxRuntime()), } if !tt.node1 { fillWorker(t, st, workers["node-1"]) } - snap := newPausedSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "pause-snap-1", "node-1") - seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_SUSPENDED, func(a *ateapipb.Actor) { + snap := newPausedSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "pause-snap-1", "node-1") + seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_SUSPENDED, func(a *ateapi.Actor) { a.Status.AssignedNode = "node-1" a.Status.LastAssignedGeneration = 1 - a.Status.Snapshots = []*ateapipb.Snapshot{proto.CloneOf(snap)} + a.Status.Snapshots = []*ateapi.Snapshot{proto.CloneOf(snap)} }) w, atelet := newDetachTestWorkflow(t, ctx, st) addAteletOnNode(t, w, "node-2") @@ -534,7 +533,7 @@ func TestResumeActor_DetachesFromFullNode(t *testing.T) { if err != nil { t.Fatalf("ResumeActor: %v", err) } - if !resumed || got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if !resumed || got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Fatalf("ResumeActor = (state %v, resumed %v), want RUNNING and resumed", got.GetStatus().GetState(), resumed) } detached := atelet.detachRequest() != nil @@ -569,61 +568,127 @@ func TestResumeActor_DetachesFromFullNode(t *testing.T) { } } -// TestResumeActor_NodeGoneWithPendingUpload resumes a paused actor whose node -// was deleted before atelet uploaded its latest snapshot. The resume crashes -// the actor, a revert returns it to its older durable snapshot, and the next -// resume restores that snapshot on another node. +// TestResumeActor_NodeGoneWithPendingUpload resumes a suspended actor whose +// node was deleted before atelet reported the upload of its latest snapshot. +// Resume restores that snapshot from its upload on another node. When atelet +// finds no upload, the actor crashes, a revert returns it to its older durable +// snapshot, and the next resume restores that one. func TestResumeActor_NodeGoneWithPendingUpload(t *testing.T) { - ctx := context.Background() - st := newTestPersistence(t) - actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} + for _, tt := range []struct { + name string + // assignedNode is node-3, the deleted node, or empty when an earlier + // resume already released it. + assignedNode string + // uploaded is false when atelet finds no upload to restore. + uploaded bool + // otherRuntime gives the only free worker a runtime other than the + // snapshot's, so the restore falls back to ROOTFS. + otherRuntime bool + }{ + {name: "uploaded: restores on another node", assignedNode: "node-3", uploaded: true}, + {name: "released by an earlier resume: restores on another node", uploaded: true}, + {name: "uploaded, only another runtime has room: restores at ROOTFS", assignedNode: "node-3", uploaded: true, otherRuntime: true}, + {name: "never uploaded: crashes, then revert and resume restore the older snapshot", assignedNode: "node-3"}, + } { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + st := newTestPersistence(t) + actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - storetest.MustCreateAtespace(t, ctx, st, "ns") - if _, err := st.CreateActorTemplate(ctx, &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ns", Name: "tmpl1"}, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation}, - }); err != nil { - t.Fatalf("create template: %v", err) - } - worker := seedRuntimeWorker(t, ctx, st, "pod-2", "node-2", testSandboxRuntime()) - memory := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY - durable := newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", "durable-1", - someActorSnapshotURI(t, testStorageLocation, "team-a", "durable-1"), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) - paused := newPausedSnapshot(t, 2, memory, "", "pause-snap-2", "node-3") - seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_SUSPENDED, func(a *ateapipb.Actor) { - a.Status.AssignedNode = "node-3" - a.Status.LastAssignedGeneration = 2 - a.Status.Snapshots = []*ateapipb.Snapshot{proto.CloneOf(durable), proto.CloneOf(paused)} - }) - w, atelet := newDetachTestWorkflow(t, ctx, st) - addAteletOnNode(t, w, "node-2") - WithNodeGetter(nodeGetter(nil, "node-1", "node-2"))(w.dialer) + storetest.MustCreateAtespace(t, ctx, st, "ns") + if _, err := st.CreateActorTemplate(ctx, &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ns", Name: "tmpl1"}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}, + }); err != nil { + t.Fatalf("create template: %v", err) + } + workerRuntime := testSandboxRuntime() + wantFidelity := ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + if tt.otherRuntime { + workerRuntime = testRuntime("arm64", "") + wantFidelity = ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS + } + worker := seedRuntimeWorker(t, ctx, st, "pod-2", "node-2", workerRuntime) + memory := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + durable := newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", "durable-1", + someActorSnapshotURI(t, testStorageLocation, "team-a", "durable-1"), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + pending := newPausedSnapshot(t, 2, memory, "", "pending-2", "node-3") + if tt.otherRuntime { + pending.SandboxRuntime = testRuntime("amd64", "") + } + seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_SUSPENDED, func(a *ateapi.Actor) { + a.Status.AssignedNode = tt.assignedNode + a.Status.LastAssignedGeneration = 2 + a.Status.Snapshots = []*ateapi.Snapshot{proto.CloneOf(durable), proto.CloneOf(pending)} + }) + w, atelet := newDetachTestWorkflow(t, ctx, st) + addAteletOnNode(t, w, "node-2") + WithNodeGetter(nodeGetter(nil, "node-1", "node-2"))(w.dialer) + if !tt.uploaded { + atelet.restoreErr = apierror.NotFound("snapshot has no usable local copy and no uploaded copy") + } - if _, _, err := w.ResumeActor(ctx, actorRef); apierror.Code(err) != codes.FailedPrecondition { - t.Fatalf("first ResumeActor = %v, want FailedPrecondition", err) - } - if got, err := st.GetActor(ctx, actorRef); err != nil || got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { - t.Fatalf("after first resume: state %v, err %v, want CRASHED", got.GetStatus().GetState(), err) - } + got, resumed, err := w.ResumeActor(ctx, actorRef) + restore, _ := atelet.requests() + if restore.GetWorkerPodUid() != worker.GetWorkerPodUid() || restore.GetSnapshot().GetSnapshotUuid() != pending.GetUuid() { + t.Fatalf("Restore = (worker %q, snapshot %q), want (%q, %q)", restore.GetWorkerPodUid(), restore.GetSnapshot().GetSnapshotUuid(), worker.GetWorkerPodUid(), pending.GetUuid()) + } + if got := restore.GetSnapshot().GetFidelity(); got != wantFidelity { + t.Errorf("Restore fidelity = %v, want %v", got, wantFidelity) + } - reverted, err := w.RevertActor(ctx, actorRef) - if err != nil { - t.Fatalf("RevertActor: %v", err) - } - if s := reverted.GetStatus(); s.GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED || s.GetAssignedNode() != "" { - t.Fatalf("after revert: state %v, assigned node %q, want SUSPENDED with no node", s.GetState(), s.GetAssignedNode()) - } + if tt.uploaded { + if err != nil { + t.Fatalf("ResumeActor: %v", err) + } + s := got.GetStatus() + if !resumed || s.GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING || s.GetAssignedNode() != "node-2" { + t.Fatalf("ResumeActor = (state %v, node %q, resumed %v), want RUNNING on node-2", s.GetState(), s.GetAssignedNode(), resumed) + } + // The restore proved the upload complete. + snap := findSnapshotByGeneration(s.GetSnapshots(), 2) + if snap.GetDurableSnapshot().GetStatus() != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED || snap.GetLocality() != "" { + t.Errorf("generation 2 = %v, want COMPLETED with no locality", snap) + } + return + } - got, resumed, err := w.ResumeActor(ctx, actorRef) - if err != nil { - t.Fatalf("second ResumeActor: %v", err) - } - if !resumed || got.GetStatus().GetAssignedNode() != "node-2" { - t.Fatalf("second ResumeActor = (node %q, resumed %v), want node-2 and resumed", got.GetStatus().GetAssignedNode(), resumed) - } - restore, _ := atelet.requests() - if restore.GetWorkerPodUid() != worker.GetWorkerPodUid() || restore.GetSnapshot().GetSnapshotUuid() != durable.GetUuid() { - t.Errorf("Restore = (worker %q, snapshot %q), want (%q, %q)", restore.GetWorkerPodUid(), restore.GetSnapshot().GetSnapshotUuid(), worker.GetWorkerPodUid(), durable.GetUuid()) + if apierror.Code(err) != codes.FailedPrecondition { + t.Fatalf("ResumeActor = %v, want FailedPrecondition", err) + } + crashed, err := st.GetActor(ctx, actorRef) + if err != nil { + t.Fatalf("GetActor: %v", err) + } + s := crashed.GetStatus() + if s.GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED || !strings.Contains(s.GetCrash().GetMessage(), crashMessageLocalSnapshotNodeGone) { + t.Fatalf("after resume: state %v, crash %v, want CRASHED with %q", s.GetState(), s.GetCrash(), crashMessageLocalSnapshotNodeGone) + } + // Both snapshots stay, so a revert can delete the partial upload + // and return to generation 1. + if snaps := s.GetSnapshots(); len(snaps) != 2 || !proto.Equal(snaps[0], durable) || !proto.Equal(snaps[1], pending) { + t.Errorf("snapshots = %v, want %v and %v unchanged", snaps, durable, pending) + } + + // The crash leaves the actor on node-2, so revert terminates it + // there. + reverted, err := w.RevertActor(ctx, actorRef) + if err != nil { + t.Fatalf("RevertActor: %v", err) + } + if s := reverted.GetStatus(); s.GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED || s.GetAssignedNode() != "" { + t.Fatalf("after revert: state %v, assigned node %q, want SUSPENDED with no node", s.GetState(), s.GetAssignedNode()) + } + atelet.mu.Lock() + atelet.restoreErr = nil + atelet.mu.Unlock() + if _, _, err := w.ResumeActor(ctx, actorRef); err != nil { + t.Fatalf("second ResumeActor: %v", err) + } + if restore, _ := atelet.requests(); restore.GetSnapshot().GetSnapshotUuid() != durable.GetUuid() { + t.Errorf("second Restore snapshot = %q, want %q", restore.GetSnapshot().GetSnapshotUuid(), durable.GetUuid()) + } + }) } } @@ -654,8 +719,8 @@ func TestDetachFromFullNode_ReentryRecordsAfterConflict(t *testing.T) { actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} fillWorker(t, st, seedRuntimeWorker(t, ctx, st, "pod-node-1", "node-1", testSandboxRuntime())) seedRuntimeWorker(t, ctx, st, "pod-2", "node-2", testSandboxRuntime()) - snap := newPausedSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "pause-snap-1", "node-1") - actor := seedActorWithSnapshot(t, ctx, st, ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1", snap) + snap := newPausedSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "pause-snap-1", "node-1") + actor := seedActorWithSnapshot(t, ctx, st, ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1", snap) w, atelet := newDetachTestWorkflow(t, ctx, st) atelet.detachState = detachedState(snap) noRoom := apierror.ResourceExhausted("%w", errNoWorkerRoom) @@ -667,16 +732,16 @@ func TestDetachFromFullNode_ReentryRecordsAfterConflict(t *testing.T) { t.Errorf("GetActor: %v", err) return } - if _, err := st.UpdateActor(ctx, actorRef, store.PreconditionFrom(cur), func(*ateapipb.Actor) error { return nil }); err != nil { + if _, err := st.UpdateActor(ctx, actorRef, store.PreconditionFrom(cur), func(*ateapi.Actor) error { return nil }); err != nil { t.Errorf("UpdateActor: %v", err) } } - if _, err := w.detachFromFullNode(ctx, actorRef, actor, &ateapipb.ActorTemplate{}, noRoom); apierror.Code(err) != codes.Aborted { + if _, err := w.detachFromFullNode(ctx, actorRef, actor, &ateapi.ActorTemplate{}, noRoom); apierror.Code(err) != codes.Aborted { t.Fatalf("first detachFromFullNode() = %v, want Aborted", err) } atelet.onDetach = nil - stored, err := w.detachFromFullNode(ctx, actorRef, actor, &ateapipb.ActorTemplate{}, noRoom) + stored, err := w.detachFromFullNode(ctx, actorRef, actor, &ateapi.ActorTemplate{}, noRoom) if err != nil { t.Fatalf("second detachFromFullNode() = %v, want success", err) } @@ -684,7 +749,7 @@ func TestDetachFromFullNode_ReentryRecordsAfterConflict(t *testing.T) { t.Errorf("AssignedNode = %q, want none", got) } if got := stored.GetStatus().GetSnapshots(); len(got) != 1 || got[0].GetLocality() != "" || - got[0].GetDurableSnapshot().GetStatus() != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { + got[0].GetDurableSnapshot().GetStatus() != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { t.Errorf("snapshots = %v, want pause-snap-1 durable only and COMPLETED", got) } } diff --git a/cmd/ateapi/internal/controlapi/workflow_resume_test.go b/cmd/ateapi/internal/controlapi/workflow_resume_test.go index 9ba5ec5dc2..6409e679c3 100644 --- a/cmd/ateapi/internal/controlapi/workflow_resume_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_resume_test.go @@ -25,6 +25,7 @@ import ( "time" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/scheduling" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" @@ -38,7 +39,6 @@ import ( "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/volume" - "go.ate.dev/substrate/pkg/proto/ateapipb" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/metricdata" "google.golang.org/grpc" @@ -93,9 +93,9 @@ func (s *leaseCountingStore) AcquireLease(ctx context.Context, key string) (*sto func TestResumeActor_RunningFastPathDoesNotAcquireLease(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - created := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + created := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, }) st := &leaseCountingStore{Interface: persistence} w := &ActorWorkflow{store: st} @@ -121,35 +121,35 @@ func TestResumeActor_RunningFastPathDoesNotAcquireLease(t *testing.T) { func seedFinalizeActor(t *testing.T, ctx context.Context, persistence store.Interface, registered int64, newIPs []string) { t.Helper() workerName := testWorkerUID("pod-1") - if _, err := persistence.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: workerName}, + if _, err := persistence.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: workerName}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "pod-1", WorkerPodUid: workerName, NodeName: "node-1", - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, RegisteredEpoch: registered, Ips: newIPs, }, }); err != nil { t.Fatalf("CreateWorker: %v", err) } - storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "tmpl-2"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RESUMING, + storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "tmpl-2"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RESUMING, AssignedNode: "node-1", LastAssignedGeneration: 1, - WorkerAssignment: &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: workerName}, + WorkerAssignment: &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: workerName}, WorkerPodIps: []string{"10.0.0.1"}, WorkerEpoch: 1, }, - Snapshots: []*ateapipb.Snapshot{ - newPausedSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "local-1", "node-1"), + Snapshots: []*ateapi.Snapshot{ + newPausedSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "local-1", "node-1"), }, }, }) @@ -169,7 +169,7 @@ func TestFinalizeRunning_CommitsRunning(t *testing.T) { if err != nil { t.Fatalf("finalizeRunning: %v", err) } - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("state = %v, want RUNNING", got.GetStatus().GetState()) } if locality := findLatestLocalSnapshot(got.GetStatus()).GetLocality(); locality != "node-1" { @@ -224,13 +224,88 @@ func TestFinalizeRunning_ReplacedWorkerProcess(t *testing.T) { if err != nil { t.Fatalf("GetActor: %v", err) } - if got := actor.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RESUMING { + if got := actor.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RESUMING { t.Errorf("state = %v, want RESUMING", got) } }) } } +// A restore from the upload of a snapshot on a deleted node commits RUNNING +// even when the record can't take the upload, since the workload already runs. +func TestFinalizeRunning_UnrecordableUploadStillRuns(t *testing.T) { + ctx := context.Background() + persistence := newTestPersistence(t) + ref := resources.ActorRef{Atespace: "team-a", Name: "id1"} + seedFinalizeActor(t, ctx, persistence, 1, []string{"10.0.0.1"}) + actor, err := persistence.GetActor(ctx, ref) + if err != nil { + t.Fatalf("GetActor: %v", err) + } + mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { + s.Snapshots[0].Locality = "node-3" + s.Snapshots[0].Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED + }) + w := &ActorWorkflow{store: persistence} + + got, err := w.finalizeRunning(ctx, ref, 1) + if err != nil { + t.Fatalf("finalizeRunning: %v", err) + } + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { + t.Errorf("state = %v, want RUNNING", got.GetStatus().GetState()) + } + if snap := got.GetStatus().GetSnapshots()[0]; snap.GetDurableSnapshot().GetStatus() != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING || snap.GetLocality() != "node-3" { + t.Errorf("snapshot = %v, want it unrecorded: PENDING on node-3", snap) + } +} + +func TestRecordRestoredUpload(t *testing.T) { + memory := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + pending := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + completed := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + snapshot := func(locality string, fidelity ateapi.SnapshotFidelity, storage ateapi.SnapshotStorageStatus) *ateapi.Snapshot { + snap := newPausedSnapshot(t, 1, fidelity, "", "snap-1", locality) + snap.DurableSnapshot.Status = storage + return snap + } + for _, tt := range []struct { + name string + snap *ateapi.Snapshot + // want is the snapshot after the call, or nil when it is unchanged. + want *ateapi.Snapshot + wantErr bool + }{ + {name: "local on the assigned node: unchanged", snap: snapshot("node-2", memory, pending)}, + {name: "durable only: unchanged", snap: snapshot("", memory, completed)}, + {name: "local on a deleted node: recorded", snap: snapshot("node-1", memory, pending), want: snapshot("", memory, completed)}, + {name: "local on a deleted node with no fidelity: unchanged, error", snap: snapshot("node-1", ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED, pending), wantErr: true}, + } { + t.Run(tt.name, func(t *testing.T) { + status := &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + AssignedNode: "node-2", + LastAssignedGeneration: 1, + Snapshots: []*ateapi.Snapshot{proto.CloneOf(tt.snap)}, + } + err := recordRestoredUpload(context.Background(), status) + if (err != nil) != tt.wantErr { + t.Fatalf("recordRestoredUpload() = %v, want error %v", err, tt.wantErr) + } + want := tt.want + if want == nil { + want = tt.snap + } + if got := status.GetSnapshots()[0]; !proto.Equal(got, want) { + t.Errorf("snapshot = %v, want %v", got, want) + } + if status.GetAssignedNode() != "node-2" { + t.Errorf("assigned node = %q, want node-2", status.GetAssignedNode()) + } + }) + } +} + // bindErrorStore fails every claim, standing in for a worker that moved or // vanished between the pick and the write. type bindErrorStore struct { @@ -238,7 +313,7 @@ type bindErrorStore struct { err error } -func (s *bindErrorStore) BindActorToWorker(context.Context, string, *ateapipb.ActorAssignment, func(*ateapipb.Worker) error) error { +func (s *bindErrorStore) BindActorToWorker(context.Context, string, *ateapi.ActorAssignment, func(*ateapi.Worker) error) error { return s.err } @@ -248,7 +323,7 @@ func TestAssignWorkerAttempt_MissingSelectedWorkerIsRetried(t *testing.T) { actor, wc := seedAssignFixture(t, ctx, persistence) st := &bindErrorStore{Interface: persistence, err: store.ErrNotFound} w := &ActorWorkflow{store: st, workerCache: wc, scheduler: scheduling.New(wc)} - tmpl := &ateapipb.ActorTemplate{} + tmpl := &ateapi.ActorTemplate{} _, _, err := w.assignWorkerAttempt(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, tmpl) if !errors.Is(err, store.ErrVersionConflict) { @@ -269,7 +344,7 @@ func TestEnsureWorkerAssigned_ConflictExhaustionIsRetryable(t *testing.T) { actor, wc := seedAssignFixture(t, ctx, persistence) st := &bindErrorStore{Interface: persistence, err: store.ErrVersionConflict} w := &ActorWorkflow{store: st, workerCache: wc, scheduler: scheduling.New(wc)} - tmpl := &ateapipb.ActorTemplate{} + tmpl := &ateapi.ActorTemplate{} _, _, err := w.ensureWorkerAssigned(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, tmpl) if !errors.Is(err, store.ErrVersionConflict) { @@ -283,23 +358,23 @@ func TestAssignWorkerAttempt_SkipsWorkerAssignedInOtherAtespace(t *testing.T) { // The only worker is held by a same-named actor in another atespace. It is // eligible for the template, so a name-only match would adopt it. - worker := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerUID("pod-1")}, + worker := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerUID("pod-1")}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "pod-1", WorkerPodUid: testWorkerUID("pod-1"), - Status: registered(&ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Status: registered(&ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(testSandboxRuntime()), }), } if _, err := persistence.CreateWorker(ctx, worker); err != nil { t.Fatalf("CreateWorker: %v", err) } - seedAssignment(t, persistence, testWorkerUID("pod-1"), &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: "team-b", Name: "shared"}, + seedAssignment(t, persistence, testWorkerUID("pod-1"), &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: "team-b", Name: "shared"}, ActorUid: "team-b-actor-uid", }) @@ -311,10 +386,10 @@ func TestAssignWorkerAttempt_SkipsWorkerAssignedInOtherAtespace(t *testing.T) { } w := &ActorWorkflow{store: persistence, workerCache: wc, scheduler: scheduling.New(wc)} - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "shared", Uid: "actor-uid"}, + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "shared", Uid: "actor-uid"}, } - tmpl := &ateapipb.ActorTemplate{} + tmpl := &ateapi.ActorTemplate{} _, _, err := w.assignWorkerAttempt(ctx, resources.ActorRef{Atespace: "team-a", Name: "shared"}, actor, tmpl) if apierror.Code(err) != codes.ResourceExhausted { t.Fatalf("assignWorkerAttempt() error = %v, want ResourceExhausted (no worker has room)", err) @@ -329,22 +404,22 @@ func TestAssignWorkerAttempt_SkipsWorkerAssignedInOtherAtespace(t *testing.T) { } } -// TestEnsureWorkerAssigned_MalformedSnapshotURIClaimsNoWorker verifies that a -// snapshot URI that does not parse fails the resume before a worker is claimed, +// TestEnsureWorkerAssigned_MissingUploadClaimsNoWorker verifies that a local +// snapshot that records no upload fails the resume before a worker is claimed, // so the actor stays SUSPENDED and the worker stays free. -func TestEnsureWorkerAssigned_MalformedSnapshotURIClaimsNoWorker(t *testing.T) { +func TestEnsureWorkerAssigned_MissingUploadClaimsNoWorker(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - worker := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerUID("pod-1")}, + worker := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerUID("pod-1")}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "pod-1", WorkerPodUid: testWorkerUID("pod-1"), - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(testSandboxRuntime()), }, } @@ -360,11 +435,11 @@ func TestEnsureWorkerAssigned_MalformedSnapshotURIClaimsNoWorker(t *testing.T) { } actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - seedWorkflowActor(t, ctx, persistence, actorRef, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_SUSPENDED, func(a *ateapipb.Actor) { + seedWorkflowActor(t, ctx, persistence, actorRef, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_SUSPENDED, func(a *ateapi.Actor) { a.Status.LastAssignedGeneration = 1 - a.Status.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "snap-1", "not-a-valid-snapshot-uri", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), - } + snap := newPausedSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "snap-1", "node-1") + snap.DurableSnapshot = nil + a.Status.Snapshots = []*ateapi.Snapshot{snap} }) actor, err := persistence.GetActor(ctx, actorRef) if err != nil { @@ -372,7 +447,7 @@ func TestEnsureWorkerAssigned_MalformedSnapshotURIClaimsNoWorker(t *testing.T) { } w := &ActorWorkflow{store: persistence, workerCache: wc, scheduler: scheduling.New(wc)} - if _, _, err := w.ensureWorkerAssigned(ctx, actorRef, actor, &ateapipb.ActorTemplate{}); apierror.Code(err) != codes.DataLoss { + if _, _, err := w.ensureWorkerAssigned(ctx, actorRef, actor, &ateapi.ActorTemplate{}); apierror.Code(err) != codes.DataLoss { t.Fatalf("ensureWorkerAssigned() error = %v, want DataLoss", err) } @@ -383,7 +458,7 @@ func TestEnsureWorkerAssigned_MalformedSnapshotURIClaimsNoWorker(t *testing.T) { if err != nil { t.Fatalf("GetActor: %v", err) } - if got := stored.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := stored.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("stored state = %v, want SUSPENDED", got) } if got := stored.GetStatus().GetWorkerAssignment(); got != nil { @@ -399,47 +474,47 @@ func TestAssignWorkerAttempt_ReleasesIneligibleStaleWorker(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) // stale-pod is claimed by this actor from a failed attempt but its labels // do not match the template's selector; free-pod is eligible and free. - stale := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerUID("stale-pod")}, + stale := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerUID("stale-pod")}, WorkerNamespace: "worker-ns", WorkerPool: "pool-a", WorkerPod: "stale-pod", WorkerPodUid: testWorkerUID("stale-pod"), NodeName: "node-1", - Status: registered(&ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Status: registered(&ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(testSandboxRuntime()), }), } - free := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerUID("free-pod")}, + free := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerUID("free-pod")}, WorkerNamespace: "worker-ns", WorkerPool: "pool-b", WorkerPod: "free-pod", WorkerPodUid: testWorkerUID("free-pod"), NodeName: "node-1", Labels: map[string]string{"pool": "b"}, - Status: registered(&ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Status: registered(&ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(testSandboxRuntime()), }), } - for _, w := range []*ateapipb.Worker{stale, free} { + for _, w := range []*ateapi.Worker{stale, free} { if _, err := persistence.CreateWorker(ctx, w); err != nil { t.Fatalf("CreateWorker(%s): %v", w.GetWorkerPod(), err) } } - seedAssignment(t, persistence, testWorkerUID("stale-pod"), &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "id1"}, + seedAssignment(t, persistence, testWorkerUID("stale-pod"), &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "id1"}, ActorUid: actor.GetMetadata().GetUid(), }) @@ -451,8 +526,8 @@ func TestAssignWorkerAttempt_ReleasesIneligibleStaleWorker(t *testing.T) { } w := &ActorWorkflow{store: persistence, workerCache: wc, scheduler: scheduling.New(wc)} - tmpl := &ateapipb.ActorTemplate{ - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"pool": "b"}}, + tmpl := &ateapi.ActorTemplate{ + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"pool": "b"}}, } _, worker, err := w.assignWorkerAttempt(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, tmpl) if err != nil { @@ -480,33 +555,33 @@ func TestAssignWorkerAttempt_RetryAfterConflictPicksFreshWorker(t *testing.T) { persistence := newTestPersistence(t) wantRuntime := testSandboxRuntime() - contested := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerUID("contested-pod")}, + contested := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerUID("contested-pod")}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "contested-pod", WorkerPodUid: testWorkerUID("contested-pod"), NodeName: "node-1", - Status: registered(&ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Status: registered(&ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(wantRuntime), }), } - fallback := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerUID("fallback-pod")}, + fallback := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerUID("fallback-pod")}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "fallback-pod", WorkerPodUid: testWorkerUID("fallback-pod"), NodeName: "node-1", - Status: registered(&ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Status: registered(&ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(wantRuntime), }), } - for _, w := range []*ateapipb.Worker{contested, fallback} { + for _, w := range []*ateapi.Worker{contested, fallback} { if _, err := persistence.CreateWorker(ctx, w); err != nil { t.Fatalf("CreateWorker(%s): %v", w.GetWorkerPod(), err) } @@ -514,14 +589,14 @@ func TestAssignWorkerAttempt_RetryAfterConflictPicksFreshWorker(t *testing.T) { // A concurrent resume of another actor wins the contested worker, bumping // its stored version past the failed attempt's snapshot. - seedAssignment(t, persistence, testWorkerUID("contested-pod"), &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "other"}, + seedAssignment(t, persistence, testWorkerUID("contested-pod"), &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "other"}, ActorUid: "other-actor-uid", }) - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) cacheCtx, cancel := context.WithCancel(ctx) @@ -532,7 +607,7 @@ func TestAssignWorkerAttempt_RetryAfterConflictPicksFreshWorker(t *testing.T) { } w := &ActorWorkflow{store: persistence, workerCache: wc, scheduler: scheduling.New(wc)} - tmpl := &ateapipb.ActorTemplate{} + tmpl := &ateapi.ActorTemplate{} _, worker, err := w.assignWorkerAttempt(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, tmpl) if err != nil { t.Fatalf("assignWorkerAttempt() on retry = %v, want nil (must re-pick a free worker)", err) @@ -554,8 +629,8 @@ func TestAssignWorkerAttempt_RetryAfterConflictPicksFreshWorker(t *testing.T) { if err != nil { t.Fatalf("GetActor: %v", err) } - if storedActor.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RESUMING { - t.Errorf("stored actor state = %v, want %v", storedActor.GetStatus().GetState(), ateapipb.ActorState_ACTOR_STATE_RESUMING) + if storedActor.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RESUMING { + t.Errorf("stored actor state = %v, want %v", storedActor.GetStatus().GetState(), ateapi.ActorState_ACTOR_STATE_RESUMING) } if got := storedActor.GetStatus().GetWorkerAssignment().GetWorkerPod(); got != "fallback-pod" { t.Errorf("stored actor WorkerAssignment.WorkerPod = %q, want %q", got, "fallback-pod") @@ -574,38 +649,38 @@ type conflictInjectingStore struct { inject func() } -func (c *conflictInjectingStore) UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(*ateapipb.Actor) error) (*ateapipb.Actor, error) { +func (c *conflictInjectingStore) UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(*ateapi.Actor) error) (*ateapi.Actor, error) { c.once.Do(c.inject) return c.Interface.UpdateActor(ctx, actorRef, precondition, mutate) } -func (c *conflictInjectingStore) UpdateTag(ctx context.Context, tagRef resources.TagRef, precondition store.Precondition, mutate func(*ateapipb.Tag) error) (*ateapipb.Tag, error) { +func (c *conflictInjectingStore) UpdateTag(ctx context.Context, tagRef resources.TagRef, precondition store.Precondition, mutate func(*ateapi.Tag) error) (*ateapi.Tag, error) { c.once.Do(c.inject) return c.Interface.UpdateTag(ctx, tagRef, precondition, mutate) } // seedAssignFixture stores one free gvisor worker and a SUSPENDED actor and // returns the actor plus a started worker cache. -func seedAssignFixture(t *testing.T, ctx context.Context, persistence store.Interface) (*ateapipb.Actor, *workercache.Cache) { +func seedAssignFixture(t *testing.T, ctx context.Context, persistence store.Interface) (*ateapi.Actor, *workercache.Cache) { t.Helper() - if _, err := persistence.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerUID("pod-1")}, + if _, err := persistence.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerUID("pod-1")}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "pod-1", WorkerPodUid: testWorkerUID("pod-1"), NodeName: "node-1", - Status: registered(&ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Status: registered(&ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(testSandboxRuntime()), }), }); err != nil { t.Fatalf("CreateWorker: %v", err) } - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) cacheCtx, cancel := context.WithCancel(ctx) t.Cleanup(cancel) @@ -625,28 +700,28 @@ func TestAssignWorkerAttempt_ConflictRefreshesActor(t *testing.T) { tests := []struct { name string // mutate is the racing concurrent write applied to the fresh actor. - mutate func(fresh *ateapipb.Actor) + mutate func(fresh *ateapi.Actor) // wantRetry means the attempt surfaces ErrVersionConflict with the // refreshed actor returned; otherwise Aborted. wantRetry bool // wantStoredState is the persisted state after Execute. - wantStoredState ateapipb.ActorState + wantStoredState ateapi.ActorState }{ { name: "another writer refreshes state.Actor - can recover", - mutate: func(fresh *ateapipb.Actor) { - fresh.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"team": "blue"}} + mutate: func(fresh *ateapi.Actor) { + fresh.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"team": "blue"}} }, wantRetry: true, - wantStoredState: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + wantStoredState: ateapi.ActorState_ACTOR_STATE_SUSPENDED, }, { name: "another writer crash the Actor", - mutate: func(fresh *ateapipb.Actor) { - fresh.Status.State = ateapipb.ActorState_ACTOR_STATE_CRASHED + mutate: func(fresh *ateapi.Actor) { + fresh.Status.State = ateapi.ActorState_ACTOR_STATE_CRASHED }, wantRetry: false, - wantStoredState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + wantStoredState: ateapi.ActorState_ACTOR_STATE_CRASHED, }, } for _, tc := range tests { @@ -656,7 +731,7 @@ func TestAssignWorkerAttempt_ConflictRefreshesActor(t *testing.T) { persistence := newTestPersistence(t) actor, wc := seedAssignFixture(t, ctx, persistence) - var injected *ateapipb.Actor + var injected *ateapi.Actor st := &conflictInjectingStore{Interface: persistence, inject: func() { fresh, err := persistence.GetActor(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}) if err != nil { @@ -665,7 +740,7 @@ func TestAssignWorkerAttempt_ConflictRefreshesActor(t *testing.T) { } // Guards on the uid and version just read, so the racing // write lands and the attempt under test is the one that loses. - injected, err = persistence.UpdateActor(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, store.PreconditionFrom(fresh), func(toUpdate *ateapipb.Actor) error { + injected, err = persistence.UpdateActor(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, store.PreconditionFrom(fresh), func(toUpdate *ateapi.Actor) error { tc.mutate(toUpdate) return nil }) @@ -675,7 +750,7 @@ func TestAssignWorkerAttempt_ConflictRefreshesActor(t *testing.T) { }} w := &ActorWorkflow{store: st, workerCache: wc, scheduler: scheduling.New(wc)} - tmpl := &ateapipb.ActorTemplate{} + tmpl := &ateapi.ActorTemplate{} refreshed, _, err := w.assignWorkerAttempt(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, tmpl) if tc.wantRetry { @@ -711,27 +786,27 @@ func TestAssignWorkerAttempt_ConflictRefreshesActor(t *testing.T) { func TestResumeActorWorkflow_RejectedAndIdempotentPaths(t *testing.T) { tests := []struct { name string - seedState ateapipb.ActorState + seedState ateapi.ActorState // wantErr true means ResumeActor must fail with FailedPrecondition. wantErr bool // wantState is the stored state after the call. - wantState ateapipb.ActorState + wantState ateapi.ActorState }{ { // The resume edge only exists from SUSPENDED and RESUMING; a // CRASHED actor is rejected by ensureWorkerAssigned // and its state is left untouched. name: "crashed rejected", - seedState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + seedState: ateapi.ActorState_ACTOR_STATE_CRASHED, wantErr: true, - wantState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + wantState: ateapi.ActorState_ACTOR_STATE_CRASHED, }, { // Resuming a RUNNING actor succeeds idempotently: every step // fast-forwards via IsComplete. name: "already running succeeds", - seedState: ateapipb.ActorState_ACTOR_STATE_RUNNING, - wantState: ateapipb.ActorState_ACTOR_STATE_RUNNING, + seedState: ateapi.ActorState_ACTOR_STATE_RUNNING, + wantState: ateapi.ActorState_ACTOR_STATE_RUNNING, }, } for _, tc := range tests { @@ -741,9 +816,9 @@ func TestResumeActorWorkflow_RejectedAndIdempotentPaths(t *testing.T) { defer cleanup() w := newTestActorWorkflow(t, st, "ns", "tmpl1") - seedWorkflowActor(t, ctx, st, resources.ActorRef{Atespace: "team-a", Name: "id1"}, "ns", "tmpl1", tc.seedState, func(a *ateapipb.Actor) { - a.Status.WorkerAssignment = &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: "uid"}, + seedWorkflowActor(t, ctx, st, resources.ActorRef{Atespace: "team-a", Name: "id1"}, "ns", "tmpl1", tc.seedState, func(a *ateapi.Actor) { + a.Status.WorkerAssignment = &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: "uid"}, WorkerNamespace: "wns", WorkerPool: "pool1", WorkerPod: "wpod", @@ -764,7 +839,7 @@ func TestResumeActorWorkflow_RejectedAndIdempotentPaths(t *testing.T) { if actor.GetStatus().GetState() != tc.wantState { t.Errorf("returned state = %v, want %v", actor.GetStatus().GetState(), tc.wantState) } - if tc.seedState == ateapipb.ActorState_ACTOR_STATE_RUNNING { + if tc.seedState == ateapi.ActorState_ACTOR_STATE_RUNNING { if resumed { t.Errorf("expected resumed = false for already running actor, got true") } @@ -797,11 +872,11 @@ func TestEnsureWorkerAssigned_RejectsNonResumableStates(t *testing.T) { w := &ActorWorkflow{} for _, st := range allActorStates { switch st { - case ateapipb.ActorState_ACTOR_STATE_SUSPENDED, ateapipb.ActorState_ACTOR_STATE_RESUMING: + case ateapi.ActorState_ACTOR_STATE_SUSPENDED, ateapi.ActorState_ACTOR_STATE_RESUMING: continue } - actor := &ateapipb.Actor{Status: &ateapipb.ActorStatus{State: st}, Metadata: &ateapipb.ResourceMetadata{Name: "id1", Uid: "actor-uid-1"}} - _, _, err := w.ensureWorkerAssigned(ctx, resources.ActorRef{Name: "id1"}, actor, &ateapipb.ActorTemplate{}) + actor := &ateapi.Actor{Status: &ateapi.ActorStatus{State: st}, Metadata: &ateapi.ResourceMetadata{Name: "id1", Uid: "actor-uid-1"}} + _, _, err := w.ensureWorkerAssigned(ctx, resources.ActorRef{Name: "id1"}, actor, &ateapi.ActorTemplate{}) assertPrerequisiteResult(t, st, err, false) } } @@ -812,11 +887,11 @@ func TestEnsureWorkerAssigned_RejectsNonResumableStates(t *testing.T) { func TestResumeActor_MetricSkipsAlreadyRunningNoop(t *testing.T) { tests := []struct { name string - seedState ateapipb.ActorState + seedState ateapi.ActorState wantRecord bool }{ - {name: "already running no-op is skipped", seedState: ateapipb.ActorState_ACTOR_STATE_RUNNING, wantRecord: false}, - {name: "failed resume is recorded", seedState: ateapipb.ActorState_ACTOR_STATE_CRASHED, wantRecord: true}, + {name: "already running no-op is skipped", seedState: ateapi.ActorState_ACTOR_STATE_RUNNING, wantRecord: false}, + {name: "failed resume is recorded", seedState: ateapi.ActorState_ACTOR_STATE_CRASHED, wantRecord: true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -827,9 +902,9 @@ func TestResumeActor_MetricSkipsAlreadyRunningNoop(t *testing.T) { inst, reader := newTestInstruments(t) w.instruments = inst - seedWorkflowActor(t, ctx, st, resources.ActorRef{Atespace: "team-a", Name: "id1"}, "ns", "tmpl1", tt.seedState, func(a *ateapipb.Actor) { - a.Status.WorkerAssignment = &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: "uid"}, + seedWorkflowActor(t, ctx, st, resources.ActorRef{Atespace: "team-a", Name: "id1"}, "ns", "tmpl1", tt.seedState, func(a *ateapi.Actor) { + a.Status.WorkerAssignment = &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: "uid"}, WorkerNamespace: "wns", WorkerPool: "pool1", WorkerPod: "wpod", @@ -864,7 +939,7 @@ func TestResumeActor_CrashesOnMissingWorkerAssignment(t *testing.T) { defer cleanup() w := newTestActorWorkflow(t, st, "ns", "tmpl1") - seedWorkflowActor(t, ctx, st, resources.ActorRef{Atespace: "team-a", Name: "id1"}, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_RESUMING, func(a *ateapipb.Actor) { + seedWorkflowActor(t, ctx, st, resources.ActorRef{Atespace: "team-a", Name: "id1"}, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_RESUMING, func(a *ateapi.Actor) { a.Status.WorkerAssignment = nil // RESUMING without a worker: corrupt record }) @@ -877,8 +952,8 @@ func TestResumeActor_CrashesOnMissingWorkerAssignment(t *testing.T) { if err != nil { t.Fatalf("GetActor failed: %v", err) } - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { - t.Errorf("stored state = %v, want %v", got.GetStatus().GetState(), ateapipb.ActorState_ACTOR_STATE_CRASHED) + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { + t.Errorf("stored state = %v, want %v", got.GetStatus().GetState(), ateapi.ActorState_ACTOR_STATE_CRASHED) } if msg, want := got.GetStatus().GetCrash().GetMessage(), "resume failed: "+crashMessageWorkerAssignmentMissing; msg != want { t.Errorf("crash message = %q, want %q", msg, want) @@ -892,48 +967,48 @@ func TestResumeActor_CrashesOnMissingWorkerAssignment(t *testing.T) { // a mismatch the actor is crashed and the worker — which is not ours — must // not be written. func TestValidateAssignedWorker(t *testing.T) { - ownAssignment := &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "shared"}, + ownAssignment := &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "shared"}, ActorUid: "own-actor-uid", } - otherAssignment := &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: "team-b", Name: "shared"}, + otherAssignment := &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: "team-b", Name: "shared"}, ActorUid: "other-actor-uid", } - staleIncarnationAssignment := &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "shared"}, + staleIncarnationAssignment := &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "shared"}, ActorUid: "stale-incarnation-uid", } - activeStatus := registered(&ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + activeStatus := registered(&ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(testSandboxRuntime()), }) - drainingStatus := &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_DRAINING, Capacity: &ateapipb.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(testSandboxRuntime())} - unavailableStatus := &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE, Capacity: &ateapipb.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(testSandboxRuntime())} + drainingStatus := &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_DRAINING, Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(testSandboxRuntime())} + unavailableStatus := &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_UNAVAILABLE, Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(testSandboxRuntime())} tests := []struct { name string // workerStatus is the stored worker's status, nil for a worker that // is gone. - workerStatus *ateapipb.WorkerStatus + workerStatus *ateapi.WorkerStatus tmplSelector map[string]string - assignment *ateapipb.ActorAssignment + assignment *ateapi.ActorAssignment // wantCode is codes.OK when validateAssignedWorker must return nil. wantCode codes.Code - wantActorState ateapipb.ActorState + wantActorState ateapi.ActorState // wantCrashMessage is the crash recorded when the actor is crashed. wantCrashMessage string // wantAssignment is the assignment expected on the stored worker // afterwards; wantWorkerWrite false additionally asserts the worker // version did not move (no write at all). - wantAssignment *ateapipb.ActorAssignment + wantAssignment *ateapi.ActorAssignment wantWorkerWrite bool }{ { name: "crashes actor when worker is gone", wantCode: codes.Aborted, - wantActorState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + wantActorState: ateapi.ActorState_ACTOR_STATE_CRASHED, wantCrashMessage: "resume failed: " + crashMessageWorkerGone, }, { @@ -941,7 +1016,7 @@ func TestValidateAssignedWorker(t *testing.T) { workerStatus: drainingStatus, assignment: ownAssignment, wantCode: codes.Aborted, - wantActorState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + wantActorState: ateapi.ActorState_ACTOR_STATE_CRASHED, wantCrashMessage: "resume failed: " + crashMessageWorkerDraining, wantAssignment: ownAssignment, }, @@ -950,21 +1025,21 @@ func TestValidateAssignedWorker(t *testing.T) { workerStatus: unavailableStatus, assignment: ownAssignment, wantCode: codes.Unavailable, - wantActorState: ateapipb.ActorState_ACTOR_STATE_RESUMING, + wantActorState: ateapi.ActorState_ACTOR_STATE_RESUMING, wantAssignment: ownAssignment, }, { // A restarted worker process between registering and reporting // its runtimes takes Actors again shortly. name: "leaves actor and worker untouched while the worker process finishes registering", - workerStatus: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, + workerStatus: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, RegisteredEpoch: 2, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Capacity: &ateapi.WorkerResources{Actors: 1}, }, assignment: ownAssignment, wantCode: codes.Unavailable, - wantActorState: ateapipb.ActorState_ACTOR_STATE_RESUMING, + wantActorState: ateapi.ActorState_ACTOR_STATE_RESUMING, wantAssignment: ownAssignment, }, { @@ -972,7 +1047,7 @@ func TestValidateAssignedWorker(t *testing.T) { workerStatus: activeStatus, assignment: otherAssignment, wantCode: codes.Aborted, - wantActorState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + wantActorState: ateapi.ActorState_ACTOR_STATE_CRASHED, wantCrashMessage: "resume failed: " + crashMessageWorkerReassigned, wantAssignment: otherAssignment, }, @@ -981,7 +1056,7 @@ func TestValidateAssignedWorker(t *testing.T) { workerStatus: activeStatus, assignment: staleIncarnationAssignment, wantCode: codes.Aborted, - wantActorState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + wantActorState: ateapi.ActorState_ACTOR_STATE_CRASHED, wantCrashMessage: "resume failed: " + crashMessageWorkerReassigned, wantAssignment: staleIncarnationAssignment, }, @@ -990,7 +1065,7 @@ func TestValidateAssignedWorker(t *testing.T) { workerStatus: activeStatus, assignment: nil, wantCode: codes.Aborted, - wantActorState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + wantActorState: ateapi.ActorState_ACTOR_STATE_CRASHED, wantCrashMessage: "resume failed: " + crashMessageWorkerReassigned, wantAssignment: nil, }, @@ -999,7 +1074,7 @@ func TestValidateAssignedWorker(t *testing.T) { workerStatus: activeStatus, assignment: ownAssignment, wantCode: codes.OK, - wantActorState: ateapipb.ActorState_ACTOR_STATE_RESUMING, + wantActorState: ateapi.ActorState_ACTOR_STATE_RESUMING, wantAssignment: ownAssignment, }, { @@ -1008,7 +1083,7 @@ func TestValidateAssignedWorker(t *testing.T) { tmplSelector: map[string]string{"pool": "other"}, assignment: ownAssignment, wantCode: codes.Aborted, - wantActorState: ateapipb.ActorState_ACTOR_STATE_CRASHED, + wantActorState: ateapi.ActorState_ACTOR_STATE_CRASHED, wantCrashMessage: "resume failed: " + crashMessageWorkerIneligible, wantAssignment: nil, wantWorkerWrite: true, @@ -1020,10 +1095,10 @@ func TestValidateAssignedWorker(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - var seeded *ateapipb.Worker + var seeded *ateapi.Worker if tt.workerStatus != nil { - if _, err := persistence.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerUID("pod-1")}, + if _, err := persistence.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerUID("pod-1")}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "pod-1", @@ -1041,15 +1116,15 @@ func TestValidateAssignedWorker(t *testing.T) { } } - seedWorkflowActor(t, ctx, persistence, resources.ActorRef{Atespace: "team-a", Name: "shared"}, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_RESUMING) + seedWorkflowActor(t, ctx, persistence, resources.ActorRef{Atespace: "team-a", Name: "shared"}, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_RESUMING) w := &ActorWorkflow{store: persistence, scheduler: scheduling.New(nil)} - resumingActor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "shared", Uid: "own-actor-uid"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RESUMING, - WorkerAssignment: &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: testWorkerUID("pod-1")}, + resumingActor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "shared", Uid: "own-actor-uid"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RESUMING, + WorkerAssignment: &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: testWorkerUID("pod-1")}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "pod-1", @@ -1057,9 +1132,9 @@ func TestValidateAssignedWorker(t *testing.T) { }, }, } - tmpl := &ateapipb.ActorTemplate{} + tmpl := &ateapi.ActorTemplate{} if tt.tmplSelector != nil { - tmpl.WorkerSelector = &ateapipb.Selector{MatchLabels: tt.tmplSelector} + tmpl.WorkerSelector = &ateapi.Selector{MatchLabels: tt.tmplSelector} } _, err := w.validateAssignedWorker(ctx, resources.ActorRef{Atespace: "team-a", Name: "shared"}, resumingActor, tmpl) if got := apierror.Code(err); got != tt.wantCode { @@ -1102,7 +1177,7 @@ func TestLoadActorForResume_RunningActorShortCircuits(t *testing.T) { // Seed the actor as RUNNING. Note: No snapshot or template is seeded in the // store, proving that loadActorForResume short-circuits before attempting // to fetch either. - seedWorkflowActor(t, ctx, persistence, actorRef, "ns", "missing-tmpl", ateapipb.ActorState_ACTOR_STATE_RUNNING) + seedWorkflowActor(t, ctx, persistence, actorRef, "ns", "missing-tmpl", ateapi.ActorState_ACTOR_STATE_RUNNING) w := &ActorWorkflow{store: persistence} @@ -1110,8 +1185,8 @@ func TestLoadActorForResume_RunningActorShortCircuits(t *testing.T) { if err != nil { t.Fatalf("loadActorForResume() unexpected error = %v", err) } - if actor.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { - t.Errorf("actor state = %v, want %v", actor.GetStatus().GetState(), ateapipb.ActorState_ACTOR_STATE_RUNNING) + if actor.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { + t.Errorf("actor state = %v, want %v", actor.GetStatus().GetState(), ateapi.ActorState_ACTOR_STATE_RUNNING) } if tmpl != nil { t.Errorf("expected nil template, got %v", tmpl) @@ -1131,6 +1206,8 @@ type capturingAtelet struct { checkpoints int promotes int + // restoreErr, when set, fails Restore after it is recorded. + restoreErr error // onCheckpoint, when set, runs before Checkpoint returns, standing in for // whatever else happens while the workload checkpoints. Its error fails // the RPC. @@ -1157,6 +1234,9 @@ func (f *capturingAtelet) Restore(ctx context.Context, req *ateletpb.RestoreRequ f.mu.Lock() defer f.mu.Unlock() f.restore = proto.Clone(req).(*ateletpb.RestoreRequest) + if f.restoreErr != nil { + return nil, f.restoreErr + } return &ateletpb.RestoreResponse{WorkerEpoch: registeredEpoch}, nil } @@ -1223,7 +1303,7 @@ func (f *capturingAtelet) Terminate(ctx context.Context, req *ateletpb.Terminate if err != nil { return nil, err } - return f.UnimplementedAteletServer.Terminate(ctx, req) + return &ateletpb.TerminateResponse{}, nil } func (f *capturingAtelet) detachRequest() *ateletpb.DetachActorRequest { @@ -1275,9 +1355,9 @@ func (f *capturingAtelet) requests() (*ateletpb.RestoreRequest, *ateletpb.RunReq // wireTestAssignment is the worker assignment matching the pods // newWireCaptureWorkflow seeds in the dialer's informer caches. -func wireTestAssignment() *ateapipb.WorkerAssignment { - return &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: "worker-1"}, +func wireTestAssignment() *ateapi.WorkerAssignment { + return &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: "worker-1"}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "pod-1", @@ -1346,40 +1426,39 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { const localSnapshotName = "pause-snap-1" // durableSnapshotName is the uuid of every durable snapshot a row seeds. const durableSnapshotName = "snap-1" - const malformedURI = "not-a-valid-snapshot-uri" actorURI := someActorSnapshotURI(t, testStorageLocation, "team-a", durableSnapshotName) goldenURI := someActorSnapshotURI(t, "gs://bucket/golden-root", "team-a", "golden-1") - fullScope := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY - rootfsScope := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS - dataScope := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES - unspecScope := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED + fullScope := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + rootfsScope := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS + dataScope := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES + unspecScope := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED - extSnap := func(uri string, fidelity ateapipb.SnapshotFidelity) *ateapipb.Snapshot { - return newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, fidelity, "", durableSnapshotName, uri, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + extSnap := func(uri string, fidelity ateapi.SnapshotFidelity) *ateapi.Snapshot { + return newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, fidelity, "", durableSnapshotName, uri, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) } - localSnap := func(name string, fidelity ateapipb.SnapshotFidelity) *ateapipb.Snapshot { + localSnap := func(name string, fidelity ateapi.SnapshotFidelity) *ateapi.Snapshot { return newPausedSnapshot(t, 1, fidelity, "", name, "node-1") } - stampedLocalSnap := func(name string, fidelity ateapipb.SnapshotFidelity, rt *ateapipb.ActorSandboxRuntime) *ateapipb.Snapshot { + stampedLocalSnap := func(name string, fidelity ateapi.SnapshotFidelity, rt *ateapi.ActorSandboxRuntime) *ateapi.Snapshot { snap := localSnap(name, fidelity) snap.SandboxRuntime = rt return snap } // pauseUploadURI is where atelet uploads the local snapshot. pauseUploadURI := someActorSnapshotURI(t, testStorageLocation, "team-a", localSnapshotName) - uploadedLocalSnap := func(name string, fidelity ateapipb.SnapshotFidelity) *ateapipb.Snapshot { + uploadedLocalSnap := func(name string, fidelity ateapi.SnapshotFidelity) *ateapi.Snapshot { snap := localSnap(name, fidelity) - snap.DurableSnapshot = &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: pauseUploadURI}, + snap.DurableSnapshot = &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, + Object: &ateapi.ObjectSnapshot{SnapshotUri: pauseUploadURI}, } return snap } // localSnapWithUpload is a local snapshot whose record names upload as // its durable copy, or none when upload is nil. - localSnapWithUpload := func(name string, fidelity ateapipb.SnapshotFidelity, upload *ateapipb.SnapshotStorage) *ateapipb.Snapshot { + localSnapWithUpload := func(name string, fidelity ateapi.SnapshotFidelity, upload *ateapi.SnapshotStorage) *ateapi.Snapshot { snap := localSnap(name, fidelity) snap.DurableSnapshot = upload return snap @@ -1389,17 +1468,17 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { type actorSeed struct { // localSnapshot seeds a completed local snapshot; // a non-nil value also pins the actor to the snapshot's node. - localSnapshot *ateapipb.Snapshot + localSnapshot *ateapi.Snapshot // externalSnapshot seeds a completed durable snapshot. - externalSnapshot *ateapipb.Snapshot + externalSnapshot *ateapi.Snapshot // tmplUID stamps externalSnapshot. "current" means the created template's UID. tmplUID string // localTmplUID stamps localSnapshot independently. localTmplUID string // sourceTag seeds Actor.SourceTag when testing explicit tag clones. - sourceTag *ateapipb.ObjectRef + sourceTag *ateapi.ObjectRef // assignedRuntime seeds WorkerAssignment.SandboxRuntime. - assignedRuntime *ateapipb.ActorSandboxRuntime + assignedRuntime *ateapi.ActorSandboxRuntime // externalNewer gives externalSnapshot a higher generation than // localSnapshot. By default the local snapshot is newer. externalNewer bool @@ -1407,7 +1486,7 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { // templateSeed is the ActorTemplate configuration a row persists. type templateSeed struct { // golden seeds the template's golden tag snapshot. - golden *ateapipb.Snapshot + golden *ateapi.Snapshot } // restoreWant pins the request atelet receives. On a non-OK code neither // Restore nor Run may reach atelet; with run set the Run RPC (cold boot) @@ -1429,7 +1508,7 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { amd64RT := testSandboxRuntime() arm64RT := testRuntime("arm64", "") - wantAteletRuntime := map[*ateapipb.ActorSandboxRuntime]*ateletpb.ActorSandboxRuntime{ + wantAteletRuntime := map[*ateapi.ActorSandboxRuntime]*ateletpb.ActorSandboxRuntime{ amd64RT: { SandboxClass: "gvisor", Version: &ateletpb.VersionedSandboxCompat{ @@ -1445,8 +1524,8 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { }, }, } - stampedExtSnap := func(owner ateapipb.SnapshotOwner, uri string, fidelity ateapipb.SnapshotFidelity, rt *ateapipb.ActorSandboxRuntime) *ateapipb.Snapshot { - snap := newDurableSnapshot(1, owner, fidelity, "", durableSnapshotName, uri, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + stampedExtSnap := func(owner ateapi.SnapshotOwner, uri string, fidelity ateapi.SnapshotFidelity, rt *ateapi.ActorSandboxRuntime) *ateapi.Snapshot { + snap := newDurableSnapshot(1, owner, fidelity, "", durableSnapshotName, uri, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) snap.SandboxRuntime = rt return snap } @@ -1478,12 +1557,6 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { tmpl: templateSeed{golden: extSnap(goldenURI, dataScope)}, want: restoreWant{run: true}, }, - { - name: "04 inherited golden snapshot rejects a malformed URI", - actor: actorSeed{externalSnapshot: extSnap(malformedURI, fullScope), tmplUID: "current"}, - tmpl: templateSeed{golden: extSnap(malformedURI, fullScope)}, - want: restoreWant{code: codes.DataLoss}, - }, { name: "05 template repoint with a late golden still cold-boots", actor: actorSeed{tmplUID: "old-template-uid"}, @@ -1590,11 +1663,6 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { scope: ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED, }, }, - { - name: "12 malformed durable snapshot URI fails with DataLoss", - actor: actorSeed{externalSnapshot: extSnap(malformedURI, fullScope)}, - want: restoreWant{code: codes.DataLoss}, - }, { // An async suspend snapshot's upload is PENDING until atelet reports // it, but a local restore names it anyway, so atelet can download the @@ -1697,7 +1765,7 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { // local restore captured under the current template. name: "18 local snapshot ignores an older external snapshot's template mismatch", actor: actorSeed{ - localSnapshot: func() *ateapipb.Snapshot { + localSnapshot: func() *ateapi.Snapshot { s := localSnap(localSnapshotName, fullScope) s.ActorTemplateUid = "current" return s @@ -1730,7 +1798,7 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { { name: "19 stamped Full durable snapshot on matching worker restores in Full", actor: actorSeed{ - externalSnapshot: stampedExtSnap(ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, actorURI, fullScope, amd64RT), + externalSnapshot: stampedExtSnap(ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, actorURI, fullScope, amd64RT), tmplUID: "current", assignedRuntime: amd64RT, }, @@ -1744,7 +1812,7 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { { name: "20 stamped actor-owned Full durable snapshot on incompatible worker drops to Rootfs", actor: actorSeed{ - externalSnapshot: stampedExtSnap(ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, actorURI, fullScope, amd64RT), + externalSnapshot: stampedExtSnap(ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, actorURI, fullScope, amd64RT), tmplUID: "current", assignedRuntime: arm64RT, }, @@ -1758,11 +1826,11 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { { name: "21 stamped borrowed golden snapshot on incompatible worker drops to Rootfs", actor: actorSeed{ - externalSnapshot: stampedExtSnap(ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, goldenURI, fullScope, amd64RT), + externalSnapshot: stampedExtSnap(ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, goldenURI, fullScope, amd64RT), tmplUID: "current", assignedRuntime: arm64RT, }, - tmpl: templateSeed{golden: stampedExtSnap(ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, goldenURI, fullScope, amd64RT)}, + tmpl: templateSeed{golden: stampedExtSnap(ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, goldenURI, fullScope, amd64RT)}, want: restoreWant{ snapshotName: durableSnapshotName, kind: ateattr.SnapshotKindLatest, @@ -1773,9 +1841,9 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { { name: "22 stamped explicit source_tag clone on incompatible worker drops to Rootfs", actor: actorSeed{ - externalSnapshot: stampedExtSnap(ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, actorURI, fullScope, amd64RT), + externalSnapshot: stampedExtSnap(ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, actorURI, fullScope, amd64RT), tmplUID: "current", - sourceTag: &ateapipb.ObjectRef{Atespace: "team-a", Name: "user-tag"}, + sourceTag: &ateapi.ObjectRef{Atespace: "team-a", Name: "user-tag"}, assignedRuntime: arm64RT, }, want: restoreWant{ @@ -1789,7 +1857,7 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { // A repointed actor drops to Volumes whatever the worker's runtime. name: "23 stamped Full durable snapshot with replaced template on incompatible worker drops to Volumes", actor: actorSeed{ - externalSnapshot: stampedExtSnap(ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, actorURI, fullScope, amd64RT), + externalSnapshot: stampedExtSnap(ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, actorURI, fullScope, amd64RT), tmplUID: "mismatch", assignedRuntime: arm64RT, }, @@ -1803,7 +1871,7 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { { name: "24 stamped Rootfs durable snapshot on worker with different runtime stays Rootfs", actor: actorSeed{ - externalSnapshot: stampedExtSnap(ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, actorURI, rootfsScope, amd64RT), + externalSnapshot: stampedExtSnap(ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, actorURI, rootfsScope, amd64RT), tmplUID: "current", assignedRuntime: arm64RT, }, @@ -1858,20 +1926,11 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { }, { // A local restore names the local snapshot's upload, so a record - // that cannot name it fails, as a malformed durable snapshot URI - // does. + // that cannot name it fails. name: "26 local snapshot with no upload recorded fails with DataLoss", actor: actorSeed{localSnapshot: localSnapWithUpload(localSnapshotName, fullScope, nil)}, want: restoreWant{code: codes.DataLoss}, }, - { - name: "27 local snapshot with a malformed upload URI fails with DataLoss", - actor: actorSeed{localSnapshot: localSnapWithUpload(localSnapshotName, fullScope, &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: malformedURI}, - })}, - want: restoreWant{code: codes.DataLoss}, - }, } for _, tt := range tests { @@ -1881,15 +1940,15 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { w, atelet := newWireCaptureWorkflow(t, persistence) storetest.MustCreateAtespace(t, ctx, persistence, "ns") - tmpl := &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ns", Name: "tmpl1"}, - SnapshotConfig: &ateapipb.SnapshotConfig{ + tmpl := &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ns", Name: "tmpl1"}, + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: testStorageLocation, }, } if tt.tmpl.golden != nil { - tmpl.Status = &ateapipb.ActorTemplateStatus{GoldenSnapshotStatus: &ateapipb.GoldenSnapshotStatus{ - GoldenTag: &ateapipb.ObjectRef{Atespace: "ns", Name: "golden"}, + tmpl.Status = &ateapi.ActorTemplateStatus{GoldenSnapshotStatus: &ateapi.GoldenSnapshotStatus{ + GoldenTag: &ateapi.ObjectRef{Atespace: "ns", Name: "golden"}, }} } createdTmpl, err := persistence.CreateActorTemplate(ctx, tmpl) @@ -1897,11 +1956,11 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { t.Fatalf("create template: %v", err) } if tt.tmpl.golden != nil { - if _, err := persistence.CreateTag(ctx, &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ns", Name: "golden"}, - SourceActor: &ateapipb.ObjectRef{Atespace: "ns", Name: "golden"}, - Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED, - Status: &ateapipb.TagStatus{ActorTemplateUid: createdTmpl.GetMetadata().GetUid(), Snapshot: tt.tmpl.golden}, + if _, err := persistence.CreateTag(ctx, &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ns", Name: "golden"}, + SourceActor: &ateapi.ObjectRef{Atespace: "ns", Name: "golden"}, + Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED, + Status: &ateapi.TagStatus{ActorTemplateUid: createdTmpl.GetMetadata().GetUid(), Snapshot: tt.tmpl.golden}, }); err != nil { t.Fatalf("create golden tag: %v", err) } @@ -1914,7 +1973,7 @@ func TestResumeActor_AteletWireRequest(t *testing.T) { // checkpoint is what makes the resume local. actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} var extGen, localGen int32 - seedWorkflowActor(t, ctx, persistence, actorRef, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_SUSPENDED, func(a *ateapipb.Actor) { + seedWorkflowActor(t, ctx, persistence, actorRef, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_SUSPENDED, func(a *ateapi.Actor) { a.SourceTag = tt.actor.sourceTag a.Status.WorkerAssignment = wireTestAssignment() a.Status.WorkerAssignment.SandboxRuntime = proto.CloneOf(tt.actor.assignedRuntime) @@ -2047,11 +2106,11 @@ func TestEnsureVolumesAttached_ReturnsPublishContext(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RESUMING, - ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{ + storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RESUMING, + ExternalVolumes: &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{ {Name: "mounted", StorageVolumeId: "storage-mounted", VolumeType: "mock"}, {Name: "unmounted", StorageVolumeId: "storage-unmounted", VolumeType: "mock"}, }}, @@ -2069,14 +2128,14 @@ func TestEnsureVolumesAttached_ReturnsPublishContext(t *testing.T) { "mock": plugin, }}, } - worker := &ateapipb.Worker{NodeName: "node-1"} - tmpl := &ateapipb.ActorTemplate{ - Volumes: []*ateapipb.Volume{ - {Name: "mounted", External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{StorageClassName: "sc"}}}, - {Name: "unmounted", External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{StorageClassName: "sc"}}}, + worker := &ateapi.Worker{NodeName: "node-1"} + tmpl := &ateapi.ActorTemplate{ + Volumes: []*ateapi.Volume{ + {Name: "mounted", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "sc"}}}, + {Name: "unmounted", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "sc"}}}, }, - Containers: []*ateapipb.Container{ - {Name: "main", Image: "img", VolumeMounts: []*ateapipb.VolumeMount{{Name: "mounted", MountPath: "/data"}}}, + Containers: []*ateapi.Container{ + {Name: "main", Image: "img", VolumeMounts: []*ateapi.VolumeMount{{Name: "mounted", MountPath: "/data"}}}, }, } @@ -2115,31 +2174,31 @@ func (p *createCountingVolumePlugin) CreateVolume(ctx context.Context, req volum // An actor being deleted gets no volume provisioned by a resume. func TestEnsureVolumesCreated(t *testing.T) { - tmpl := &ateapipb.ActorTemplate{ - Volumes: []*ateapipb.Volume{{ + tmpl := &ateapi.ActorTemplate{ + Volumes: []*ateapi.Volume{{ Name: "data", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{StorageClassName: "sc"}}, + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "sc"}}, }}, } tests := []struct { name string - state ateapipb.ActorState + state ateapi.ActorState wantCode codes.Code wantCreates int }{ - {"suspended actor gets its volume", ateapipb.ActorState_ACTOR_STATE_SUSPENDED, codes.OK, 1}, - {"deleting actor gets no volume", ateapipb.ActorState_ACTOR_STATE_DELETING, codes.FailedPrecondition, 0}, + {"suspended actor gets its volume", ateapi.ActorState_ACTOR_STATE_SUSPENDED, codes.OK, 1}, + {"deleting actor gets no volume", ateapi.ActorState_ACTOR_STATE_DELETING, codes.FailedPrecondition, 0}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1"}, - Status: &ateapipb.ActorStatus{ + storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1"}, + Status: &ateapi.ActorStatus{ State: tt.state, - ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{{Name: "data", VolumeType: "mock"}}}, + ExternalVolumes: &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{{Name: "data", VolumeType: "mock"}}}, }, }) actor, err := persistence.GetActor(ctx, actorRef) @@ -2179,7 +2238,7 @@ func TestEnsureVolumesCreated(t *testing.T) { // worker that looked free, and the admit callback that BindActorToWorker runs // under the Worker's row lock then refuses it with errWorkerFilledUp. type filledUpScheduler struct { - workers []*ateapipb.Worker + workers []*ateapi.Worker full map[string]bool calls int // onSchedule runs after each Schedule call, with the number of calls made @@ -2191,7 +2250,7 @@ type filledUpScheduler struct { // Schedule repeats the last worker, so a test that offers no free one keeps // returning a full worker until the backoff ends. -func (s *filledUpScheduler) Schedule(context.Context, scheduling.Constraints) (*ateapipb.Worker, error) { +func (s *filledUpScheduler) Schedule(context.Context, scheduling.Constraints) (*ateapi.Worker, error) { i := min(s.calls, len(s.workers)-1) s.calls++ if s.onSchedule != nil { @@ -2203,9 +2262,9 @@ func (s *filledUpScheduler) Schedule(context.Context, scheduling.Constraints) (* return s.workers[i], nil } -func (s *filledUpScheduler) Applies(*ateapipb.Worker, scheduling.Constraints) bool { return true } +func (s *filledUpScheduler) Applies(*ateapi.Worker, scheduling.Constraints) bool { return true } -func (s *filledUpScheduler) HasRoom(worker *ateapipb.Worker, _ scheduling.Constraints) bool { +func (s *filledUpScheduler) HasRoom(worker *ateapi.Worker, _ scheduling.Constraints) bool { return !s.full[worker.GetWorkerPod()] } @@ -2213,8 +2272,8 @@ func (s *filledUpScheduler) HasRoom(worker *ateapipb.Worker, _ scheduling.Constr // bug under test is in the metric path, so nothing here reaches a database. type contentionStore struct { actorWorkflowStore - workers map[string]*ateapipb.Worker - actor *ateapipb.Actor + workers map[string]*ateapi.Worker + actor *ateapi.Actor } func (s *contentionStore) FindWorkerHostingActor(context.Context, string) (string, error) { @@ -2223,7 +2282,7 @@ func (s *contentionStore) FindWorkerHostingActor(context.Context, string) (strin // BindActorToWorker runs admit as the real store does under the Worker's row // lock, and returns its refusal unchanged. -func (s *contentionStore) BindActorToWorker(_ context.Context, workerName string, _ *ateapipb.ActorAssignment, admit func(*ateapipb.Worker) error) error { +func (s *contentionStore) BindActorToWorker(_ context.Context, workerName string, _ *ateapi.ActorAssignment, admit func(*ateapi.Worker) error) error { worker, ok := s.workers[workerName] if !ok { return store.ErrNotFound @@ -2234,8 +2293,8 @@ func (s *contentionStore) BindActorToWorker(_ context.Context, workerName string return nil } -func (s *contentionStore) UpdateActor(_ context.Context, _ resources.ActorRef, _ store.Precondition, mutate func(*ateapipb.Actor) error) (*ateapipb.Actor, error) { - updated := proto.Clone(s.actor).(*ateapipb.Actor) +func (s *contentionStore) UpdateActor(_ context.Context, _ resources.ActorRef, _ store.Precondition, mutate func(*ateapi.Actor) error) (*ateapi.Actor, error) { + updated := proto.Clone(s.actor).(*ateapi.Actor) if err := mutate(updated); err != nil { return nil, err } @@ -2305,17 +2364,17 @@ func assignmentSum(t *testing.T, reader *sdkmetric.ManualReader) float64 { return sum } -func contendedWorker(podName string) *ateapipb.Worker { - return &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerUID(podName)}, +func contendedWorker(podName string) *ateapi.Worker { + return &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerUID(podName)}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: podName, WorkerPodUid: testWorkerUID(podName), NodeName: "node-1", - Status: registered(&ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Status: registered(&ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(testSandboxRuntime()), }), } @@ -2324,26 +2383,26 @@ func contendedWorker(podName string) *ateapipb.Worker { // staticWorkerSource feeds a worker cache a fixed fleet and a watch that // never fires, which is the stale cache this contention arises from. type staticWorkerSource struct { - workers []*ateapipb.Worker + workers []*ateapi.Worker } func (s *staticWorkerSource) WatchWorkers(context.Context) (*store.WorkerWatch, error) { return store.NewWorkerWatch(make(chan store.WorkerEvent), func() {}), nil } -func (s *staticWorkerSource) ListWorkers(context.Context, store.ListOptions) (store.ListResponse[*ateapipb.Worker], error) { - return store.ListResponse[*ateapipb.Worker]{Items: s.workers}, nil +func (s *staticWorkerSource) ListWorkers(context.Context, store.ListOptions) (store.ListResponse[*ateapi.Worker], error) { + return store.ListResponse[*ateapi.Worker]{Items: s.workers}, nil } // newContendedWorkflow builds a workflow around sched, with a SUSPENDED actor // ready to resume and a cache that holds every worker sched offers. -func newContendedWorkflow(t *testing.T, sched *filledUpScheduler) (*ActorWorkflow, *ateapipb.Actor, *sdkmetric.ManualReader) { +func newContendedWorkflow(t *testing.T, sched *filledUpScheduler) (*ActorWorkflow, *ateapi.Actor, *sdkmetric.ManualReader) { t.Helper() - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1", Uid: "actor-uid", Version: 1}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1", Uid: "actor-uid", Version: 1}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, } - byName := make(map[string]*ateapipb.Worker, len(sched.workers)) + byName := make(map[string]*ateapi.Worker, len(sched.workers)) for _, worker := range sched.workers { byName[worker.GetMetadata().GetName()] = worker } @@ -2371,12 +2430,12 @@ func newContendedWorkflow(t *testing.T, sched *filledUpScheduler) (*ActorWorkflo // capacity condition, and the registry says a lack of room is not a failure. func TestEnsureWorkerAssigned_ContentionRecordsOneObservation(t *testing.T) { sched := &filledUpScheduler{ - workers: []*ateapipb.Worker{contendedWorker("full-pod"), contendedWorker("free-pod")}, + workers: []*ateapi.Worker{contendedWorker("full-pod"), contendedWorker("free-pod")}, full: map[string]bool{"full-pod": true}, } w, actor, reader := newContendedWorkflow(t, sched) - _, worker, err := w.ensureWorkerAssigned(context.Background(), resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, &ateapipb.ActorTemplate{}) + _, worker, err := w.ensureWorkerAssigned(context.Background(), resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, &ateapi.ActorTemplate{}) if err != nil { t.Fatalf("ensureWorkerAssigned: %v", err) } @@ -2405,12 +2464,12 @@ func TestEnsureWorkerAssigned_ContentionRecordsOneObservation(t *testing.T) { // not the backoff, as every other record on the histogram does. func TestEnsureWorkerAssigned_ExhaustedBackoffRecordsOneError(t *testing.T) { sched := &filledUpScheduler{ - workers: []*ateapipb.Worker{contendedWorker("full-pod")}, + workers: []*ateapi.Worker{contendedWorker("full-pod")}, full: map[string]bool{"full-pod": true}, } w, actor, reader := newContendedWorkflow(t, sched) - _, _, err := w.ensureWorkerAssigned(context.Background(), resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, &ateapipb.ActorTemplate{}) + _, _, err := w.ensureWorkerAssigned(context.Background(), resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, &ateapi.ActorTemplate{}) if err == nil { t.Fatal("ensureWorkerAssigned succeeded, want a failure after the backoff ended") } @@ -2461,7 +2520,7 @@ func replayBackoff(t *testing.T, b wait.Backoff) (attempts int, lastSleep time.D // record times the attempt that lost the race, not the context check after it. func TestEnsureWorkerAssigned_CancelledDuringBackoffRecordsOne(t *testing.T) { sched := &filledUpScheduler{ - workers: []*ateapipb.Worker{contendedWorker("full-pod")}, + workers: []*ateapi.Worker{contendedWorker("full-pod")}, full: map[string]bool{"full-pod": true}, } w, actor, reader := newContendedWorkflow(t, sched) @@ -2479,7 +2538,7 @@ func TestEnsureWorkerAssigned_CancelledDuringBackoffRecordsOne(t *testing.T) { } defer cancel() - _, _, err := w.ensureWorkerAssigned(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, &ateapipb.ActorTemplate{}) + _, _, err := w.ensureWorkerAssigned(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, &ateapi.ActorTemplate{}) if !errors.Is(err, context.Canceled) { t.Fatalf("ensureWorkerAssigned error = %v, want context.Canceled", err) } @@ -2502,14 +2561,14 @@ func TestEnsureWorkerAssigned_CancelledDuringBackoffRecordsOne(t *testing.T) { // attempt to time and the histogram gets no record. func TestEnsureWorkerAssigned_CancelledBeforeFirstAttemptRecordsNothing(t *testing.T) { sched := &filledUpScheduler{ - workers: []*ateapipb.Worker{contendedWorker("free-pod")}, + workers: []*ateapi.Worker{contendedWorker("free-pod")}, } w, actor, reader := newContendedWorkflow(t, sched) ctx, cancel := context.WithCancel(context.Background()) cancel() - _, _, err := w.ensureWorkerAssigned(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, &ateapipb.ActorTemplate{}) + _, _, err := w.ensureWorkerAssigned(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, &ateapi.ActorTemplate{}) if !errors.Is(err, context.Canceled) { t.Fatalf("ensureWorkerAssigned error = %v, want context.Canceled", err) } @@ -2527,7 +2586,7 @@ func TestEnsureWorkerAssigned_CancelledBeforeFirstAttemptRecordsNothing(t *testi // context error and not that the retries ran out. func TestEnsureWorkerAssigned_CancelledInLastSleepRecordsOne(t *testing.T) { sched := &filledUpScheduler{ - workers: []*ateapipb.Worker{contendedWorker("full-pod")}, + workers: []*ateapi.Worker{contendedWorker("full-pod")}, full: map[string]bool{"full-pod": true}, } w, actor, reader := newContendedWorkflow(t, sched) @@ -2541,7 +2600,7 @@ func TestEnsureWorkerAssigned_CancelledInLastSleepRecordsOne(t *testing.T) { } defer cancel() - _, _, err := w.ensureWorkerAssigned(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, &ateapipb.ActorTemplate{}) + _, _, err := w.ensureWorkerAssigned(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, &ateapi.ActorTemplate{}) if !errors.Is(err, context.Canceled) { t.Fatalf("ensureWorkerAssigned error = %v, want context.Canceled", err) } @@ -2565,12 +2624,12 @@ func TestEnsureWorkerAssigned_CancelledInLastSleepRecordsOne(t *testing.T) { // context error and not Aborted. func TestEnsureWorkerAssigned_ContextEndsInsideAttemptRecordsOne(t *testing.T) { sched := &filledUpScheduler{ - workers: []*ateapipb.Worker{contendedWorker("free-pod")}, + workers: []*ateapi.Worker{contendedWorker("free-pod")}, err: fmt.Errorf("list workers: %w", context.DeadlineExceeded), } w, actor, reader := newContendedWorkflow(t, sched) - _, _, err := w.ensureWorkerAssigned(context.Background(), resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, &ateapipb.ActorTemplate{}) + _, _, err := w.ensureWorkerAssigned(context.Background(), resources.ActorRef{Atespace: "team-a", Name: "id1"}, actor, &ateapi.ActorTemplate{}) if !errors.Is(err, context.DeadlineExceeded) { t.Fatalf("ensureWorkerAssigned error = %v, want context.DeadlineExceeded", err) } @@ -2592,19 +2651,19 @@ func TestEnsureWorkerAssigned_ContextEndsInsideAttemptRecordsOne(t *testing.T) { // v1. A non-empty bundleHash adds a sandbox_bundle_hash attribute, so two // runtimes can share an architecture and still differ, as two versions of // one SandboxConfig do. -func testRuntime(arch, bundleHash string) *ateapipb.ActorSandboxRuntime { - attrs := []*ateapipb.AttributeEntry{{Key: "architecture", Value: arch}} +func testRuntime(arch, bundleHash string) *ateapi.ActorSandboxRuntime { + attrs := []*ateapi.AttributeEntry{{Key: "architecture", Value: arch}} if bundleHash != "" { - attrs = append(attrs, &ateapipb.AttributeEntry{Key: hardware.AttrSandboxBundleHash, Value: bundleHash}) + attrs = append(attrs, &ateapi.AttributeEntry{Key: hardware.AttrSandboxBundleHash, Value: bundleHash}) } - return &ateapipb.ActorSandboxRuntime{ + return &ateapi.ActorSandboxRuntime{ SandboxClass: "gvisor", - Version: &ateapipb.VersionedSandboxCompat{SchemaVersion: "v1", Attributes: attrs}, + Version: &ateapi.VersionedSandboxCompat{SchemaVersion: "v1", Attributes: attrs}, } } // testSandboxRuntime is the amd64 gvisor runtime most tests report and stamp. -func testSandboxRuntime() *ateapipb.ActorSandboxRuntime { +func testSandboxRuntime() *ateapi.ActorSandboxRuntime { return testRuntime("amd64", "") } @@ -2612,29 +2671,29 @@ func testSandboxRuntime() *ateapipb.ActorSandboxRuntime { // its default runtime and restore restorable beyond it, all of def's class. // The arguments are the ActorSandboxRuntimes a test also stamps snapshots and // assignments with, so both sides of a match derive from one value. -func workerSandboxClasses(def *ateapipb.ActorSandboxRuntime, restorable ...*ateapipb.ActorSandboxRuntime) []*ateapipb.WorkerSandboxClass { - class := &ateapipb.WorkerSandboxClass{SandboxClass: def.GetSandboxClass(), DefaultRuntime: &ateapipb.WorkerSandboxRuntime{Version: def.GetVersion()}} +func workerSandboxClasses(def *ateapi.ActorSandboxRuntime, restorable ...*ateapi.ActorSandboxRuntime) []*ateapi.WorkerSandboxClass { + class := &ateapi.WorkerSandboxClass{SandboxClass: def.GetSandboxClass(), DefaultRuntime: &ateapi.WorkerSandboxRuntime{Version: def.GetVersion()}} for _, r := range restorable { - class.RestorableRuntimes = append(class.RestorableRuntimes, &ateapipb.WorkerSandboxRuntime{Version: r.GetVersion()}) + class.RestorableRuntimes = append(class.RestorableRuntimes, &ateapi.WorkerSandboxRuntime{Version: r.GetVersion()}) } - return []*ateapipb.WorkerSandboxClass{class} + return []*ateapi.WorkerSandboxClass{class} } // seedRuntimeWorker stores an ACTIVE gvisor worker on node with room for one // actor, reporting def as its default runtime and restorable beyond it. -func seedRuntimeWorker(t *testing.T, ctx context.Context, st store.Interface, pod, node string, def *ateapipb.ActorSandboxRuntime, restorable ...*ateapipb.ActorSandboxRuntime) *ateapipb.Worker { +func seedRuntimeWorker(t *testing.T, ctx context.Context, st store.Interface, pod, node string, def *ateapi.ActorSandboxRuntime, restorable ...*ateapi.ActorSandboxRuntime) *ateapi.Worker { t.Helper() - worker, err := st.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerUID(pod)}, + worker, err := st.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerUID(pod)}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: pod, WorkerPodUid: testWorkerUID(pod), NodeName: node, - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, RegisteredEpoch: registeredEpoch, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(def, restorable...), }, }) @@ -2646,31 +2705,31 @@ func seedRuntimeWorker(t *testing.T, ctx context.Context, st store.Interface, po // durableMemorySnapshot is a completed, actor-owned MEMORY snapshot of // generation 1 under team-a/id1's own prefix, stamped with runtime. -func durableMemorySnapshot(t *testing.T, runtime *ateapipb.ActorSandboxRuntime) *ateapipb.Snapshot { +func durableMemorySnapshot(t *testing.T, runtime *ateapi.ActorSandboxRuntime) *ateapi.Snapshot { t.Helper() - snap := newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "snap-1", someActorSnapshotURI(t, testStorageLocation, "team-a", "snap-1"), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + snap := newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "snap-1", someActorSnapshotURI(t, testStorageLocation, "team-a", "snap-1"), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) snap.SandboxRuntime = runtime return snap } // seedMicroVMWorker stores an ACTIVE microvm worker on node with room for one // actor, reporting a microvm default runtime. -func seedMicroVMWorker(t *testing.T, ctx context.Context, st store.Interface, pod, node string) *ateapipb.Worker { +func seedMicroVMWorker(t *testing.T, ctx context.Context, st store.Interface, pod, node string) *ateapi.Worker { t.Helper() - worker, err := st.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerUID(pod)}, + worker, err := st.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerUID(pod)}, WorkerNamespace: "worker-ns", WorkerPool: "vm-pool", WorkerPod: pod, WorkerPodUid: testWorkerUID(pod), NodeName: node, - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, RegisteredEpoch: registeredEpoch, - Capacity: &ateapipb.WorkerResources{Actors: 1}, - SandboxClasses: []*ateapipb.WorkerSandboxClass{{ + Capacity: &ateapi.WorkerResources{Actors: 1}, + SandboxClasses: []*ateapi.WorkerSandboxClass{{ SandboxClass: "microvm", - DefaultRuntime: &ateapipb.WorkerSandboxRuntime{Version: &ateapipb.VersionedSandboxCompat{SchemaVersion: "v1", Attributes: []*ateapipb.AttributeEntry{ + DefaultRuntime: &ateapi.WorkerSandboxRuntime{Version: &ateapi.VersionedSandboxCompat{SchemaVersion: "v1", Attributes: []*ateapi.AttributeEntry{ {Key: "architecture", Value: "amd64"}, }}}, }}, @@ -2685,15 +2744,15 @@ func seedMicroVMWorker(t *testing.T, ctx context.Context, st store.Interface, po // seedActorWithSnapshot stores actor team-a/id1 in state holding snap as its // only snapshot. node is the AssignedNode a suspended actor with a local // snapshot keeps. -func seedActorWithSnapshot(t *testing.T, ctx context.Context, st store.Interface, state ateapipb.ActorState, node string, snap *ateapipb.Snapshot) *ateapipb.Actor { +func seedActorWithSnapshot(t *testing.T, ctx context.Context, st store.Interface, state ateapi.ActorState, node string, snap *ateapi.Snapshot) *ateapi.Actor { t.Helper() - return storetest.MustCreateActor(t, ctx, st, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1"}, - Status: &ateapipb.ActorStatus{ + return storetest.MustCreateActor(t, ctx, st, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1"}, + Status: &ateapi.ActorStatus{ State: state, AssignedNode: node, LastAssignedGeneration: snap.GetGeneration(), - Snapshots: []*ateapipb.Snapshot{snap}, + Snapshots: []*ateapi.Snapshot{snap}, }, }) } @@ -2713,7 +2772,7 @@ func newSchedulingWorkflow(t *testing.T, ctx context.Context, st store.Interface // assertAssignedRuntime checks the runtime recorded on actor's assignment, // which is what its next checkpoint will be stamped with. -func assertAssignedRuntime(t *testing.T, actor *ateapipb.Actor, want *ateapipb.ActorSandboxRuntime) { +func assertAssignedRuntime(t *testing.T, actor *ateapi.Actor, want *ateapi.ActorSandboxRuntime) { t.Helper() if diff := cmp.Diff(want, actor.GetStatus().GetWorkerAssignment().GetSandboxRuntime(), protocmp.Transform()); diff != "" { t.Errorf("WorkerAssignment.SandboxRuntime mismatch (-want +got):\n%s", diff) @@ -2726,10 +2785,10 @@ func assertAssignedRuntime(t *testing.T, actor *ateapipb.Actor, want *ateapipb.A // are the real ones. type relaxingTestScheduler struct { scheduling.Scheduler - relaxedWorker *ateapipb.Worker + relaxedWorker *ateapi.Worker } -func (s *relaxingTestScheduler) Schedule(_ context.Context, c scheduling.Constraints) (*ateapipb.Worker, error) { +func (s *relaxingTestScheduler) Schedule(_ context.Context, c scheduling.Constraints) (*ateapi.Worker, error) { if c.RequiredRuntime.Runtime() != nil { return nil, scheduling.ErrNoCapacity } @@ -2745,7 +2804,7 @@ func TestAssignWorkerAttempt_PrefersRuntimeMatchingWorkerAndFallsBack(t *testing newDefaultRT := testRuntime("amd64", "new-default") oldRestorableRT := testRuntime("amd64", "old-restorable") actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - suspended := ateapipb.ActorState_ACTOR_STATE_SUSPENDED + suspended := ateapi.ActorState_ACTOR_STATE_SUSPENDED t.Run("places on runtime-compatible worker when available", func(t *testing.T) { ctx := context.Background() @@ -2754,7 +2813,7 @@ func TestAssignWorkerAttempt_PrefersRuntimeMatchingWorkerAndFallsBack(t *testing seedRuntimeWorker(t, ctx, st, "amd-pod", "node-amd", amd64RT) actor := seedActorWithSnapshot(t, ctx, st, suspended, "", durableMemorySnapshot(t, amd64RT)) - stored, worker, err := newSchedulingWorkflow(t, ctx, st).assignWorkerAttempt(ctx, actorRef, actor, &ateapipb.ActorTemplate{}) + stored, worker, err := newSchedulingWorkflow(t, ctx, st).assignWorkerAttempt(ctx, actorRef, actor, &ateapi.ActorTemplate{}) if err != nil { t.Fatalf("assignWorkerAttempt: %v", err) } @@ -2770,7 +2829,7 @@ func TestAssignWorkerAttempt_PrefersRuntimeMatchingWorkerAndFallsBack(t *testing seedRuntimeWorker(t, ctx, st, "amd-pod", "node-amd", newDefaultRT, oldRestorableRT) actor := seedActorWithSnapshot(t, ctx, st, suspended, "", durableMemorySnapshot(t, oldRestorableRT)) - stored, _, err := newSchedulingWorkflow(t, ctx, st).assignWorkerAttempt(ctx, actorRef, actor, &ateapipb.ActorTemplate{}) + stored, _, err := newSchedulingWorkflow(t, ctx, st).assignWorkerAttempt(ctx, actorRef, actor, &ateapi.ActorTemplate{}) if err != nil { t.Fatalf("assignWorkerAttempt: %v", err) } @@ -2785,7 +2844,7 @@ func TestAssignWorkerAttempt_PrefersRuntimeMatchingWorkerAndFallsBack(t *testing seedRuntimeWorker(t, ctx, st, "arm-pod", "node-arm", arm64RT) actor := seedActorWithSnapshot(t, ctx, st, suspended, "", durableMemorySnapshot(t, amd64RT)) - stored, worker, err := newSchedulingWorkflow(t, ctx, st).assignWorkerAttempt(ctx, actorRef, actor, &ateapipb.ActorTemplate{}) + stored, worker, err := newSchedulingWorkflow(t, ctx, st).assignWorkerAttempt(ctx, actorRef, actor, &ateapi.ActorTemplate{}) if err != nil { t.Fatalf("assignWorkerAttempt: %v", err) } @@ -2800,10 +2859,10 @@ func TestAssignWorkerAttempt_PrefersRuntimeMatchingWorkerAndFallsBack(t *testing // A snapshot's files are written by one class's worker and read back // by the same, so relaxing the runtime never crosses classes, not // even for a volumes-only restore that needs no runtime at all. - for _, fidelity := range []ateapipb.SnapshotFidelity{ - ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, - ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, + for _, fidelity := range []ateapi.SnapshotFidelity{ + ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, + ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, } { t.Run(fidelity.String(), func(t *testing.T) { ctx := context.Background() @@ -2813,7 +2872,7 @@ func TestAssignWorkerAttempt_PrefersRuntimeMatchingWorkerAndFallsBack(t *testing snap.Fidelity = fidelity actor := seedActorWithSnapshot(t, ctx, st, suspended, "", snap) - _, _, err := newSchedulingWorkflow(t, ctx, st).assignWorkerAttempt(ctx, actorRef, actor, &ateapipb.ActorTemplate{}) + _, _, err := newSchedulingWorkflow(t, ctx, st).assignWorkerAttempt(ctx, actorRef, actor, &ateapi.ActorTemplate{}) if apierror.Code(err) != codes.ResourceExhausted { t.Fatalf("assignWorkerAttempt with only a microvm worker = %v, want ResourceExhausted", err) } @@ -2826,11 +2885,11 @@ func TestAssignWorkerAttempt_PrefersRuntimeMatchingWorkerAndFallsBack(t *testing st := newTestPersistence(t) seedRuntimeWorker(t, ctx, st, "node1-incompatible", "node-1", arm64RT) // A suspended actor with a local snapshot on node-1. - local := newPausedSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "local-1", "node-1") + local := newPausedSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "local-1", "node-1") local.SandboxRuntime = amd64RT actor := seedActorWithSnapshot(t, ctx, st, suspended, "node-1", local) - _, _, err := newSchedulingWorkflow(t, ctx, st).assignWorkerAttempt(ctx, actorRef, actor, &ateapipb.ActorTemplate{}) + _, _, err := newSchedulingWorkflow(t, ctx, st).assignWorkerAttempt(ctx, actorRef, actor, &ateapi.ActorTemplate{}) if got := apierror.Code(err); got != codes.ResourceExhausted { t.Fatalf("apierror.Code(err) = %v, want %v (err: %v)", got, codes.ResourceExhausted, err) } @@ -2860,7 +2919,7 @@ func TestAssignWorkerAttempt_PrefersRuntimeMatchingWorkerAndFallsBack(t *testing actor := seedActorWithSnapshot(t, ctx, st, suspended, "", durableMemorySnapshot(t, oldRestorableRT)) w := &ActorWorkflow{store: st, scheduler: &relaxingTestScheduler{Scheduler: scheduling.New(nil), relaxedWorker: worker}} - stored, _, err := w.assignWorkerAttempt(ctx, actorRef, actor, &ateapipb.ActorTemplate{}) + stored, _, err := w.assignWorkerAttempt(ctx, actorRef, actor, &ateapi.ActorTemplate{}) if err != nil { t.Fatalf("assignWorkerAttempt: %v", err) } @@ -2880,7 +2939,7 @@ func TestAssignWorkerAttempt_PrefersRuntimeMatchingWorkerAndFallsBack(t *testing actor := seedActorWithSnapshot(t, ctx, st, suspended, "", durableMemorySnapshot(t, oldRestorableRT)) w := &ActorWorkflow{store: st, scheduler: &relaxingTestScheduler{Scheduler: scheduling.New(nil), relaxedWorker: stale}} - stored, bound, err := w.assignWorkerAttempt(ctx, actorRef, actor, &ateapipb.ActorTemplate{}) + stored, bound, err := w.assignWorkerAttempt(ctx, actorRef, actor, &ateapi.ActorTemplate{}) if err != nil { t.Fatalf("assignWorkerAttempt: %v", err) } @@ -2897,22 +2956,22 @@ func TestValidateAssignedWorker_RuntimeFallback(t *testing.T) { st := newTestPersistence(t) arm64RT := testRuntime("arm64", "") seedRuntimeWorker(t, ctx, st, "arm-pod", "node-arm", arm64RT) - seedAssignment(t, st, testWorkerUID("arm-pod"), &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "id1"}, + seedAssignment(t, st, testWorkerUID("arm-pod"), &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "id1"}, ActorUid: "own-actor-uid", }) // A previous attempt bound the actor relaxed, under the worker's // default, because no worker could restore its amd64 snapshot. - resumingActor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1", Uid: "own-actor-uid"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RESUMING, + resumingActor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1", Uid: "own-actor-uid"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RESUMING, AssignedNode: "node-arm", LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{durableMemorySnapshot(t, testSandboxRuntime())}, - WorkerAssignment: &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: testWorkerUID("arm-pod")}, + Snapshots: []*ateapi.Snapshot{durableMemorySnapshot(t, testSandboxRuntime())}, + WorkerAssignment: &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: testWorkerUID("arm-pod")}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "arm-pod", @@ -2924,7 +2983,7 @@ func TestValidateAssignedWorker_RuntimeFallback(t *testing.T) { } w := &ActorWorkflow{store: st, scheduler: scheduling.New(nil)} - worker, err := w.validateAssignedWorker(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, resumingActor, &ateapipb.ActorTemplate{}) + worker, err := w.validateAssignedWorker(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, resumingActor, &ateapi.ActorTemplate{}) if err != nil { t.Fatalf("validateAssignedWorker: %v", err) } @@ -2938,24 +2997,24 @@ func TestValidateAssignedWorker_RuntimeFallback(t *testing.T) { st := newTestPersistence(t) arm64RT := testRuntime("arm64", "") seedRuntimeWorker(t, ctx, st, "arm-pod", "node-arm", arm64RT) - seedAssignment(t, st, testWorkerUID("arm-pod"), &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "id1"}, + seedAssignment(t, st, testWorkerUID("arm-pod"), &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "id1"}, ActorUid: "own-actor-uid", }) // Re-entry must accept a previously allowed ROOTFS assignment. - local := newPausedSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "local-1", "node-arm") + local := newPausedSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "local-1", "node-arm") local.SandboxRuntime = testSandboxRuntime() - local.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED - resumingActor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1", Uid: "own-actor-uid"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RESUMING, + local.DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + resumingActor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1", Uid: "own-actor-uid"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RESUMING, AssignedNode: "node-arm", LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{local}, - WorkerAssignment: &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: testWorkerUID("arm-pod")}, + Snapshots: []*ateapi.Snapshot{local}, + WorkerAssignment: &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: testWorkerUID("arm-pod")}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "arm-pod", @@ -2967,7 +3026,7 @@ func TestValidateAssignedWorker_RuntimeFallback(t *testing.T) { } w := &ActorWorkflow{store: st, scheduler: scheduling.New(nil)} - worker, err := w.validateAssignedWorker(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, resumingActor, &ateapipb.ActorTemplate{}) + worker, err := w.validateAssignedWorker(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, resumingActor, &ateapi.ActorTemplate{}) if err != nil { t.Fatalf("validateAssignedWorker: %v", err) } @@ -2981,22 +3040,22 @@ func TestValidateAssignedWorker_RuntimeFallback(t *testing.T) { // class and runtime constraint from, and when it takes no runtime constraint. func TestRequiredSnapshotRuntime(t *testing.T) { const tmplUID = "tmpl-uid" - tmpl := &ateapipb.ActorTemplate{Metadata: &ateapipb.ResourceMetadata{Uid: tmplUID}} + tmpl := &ateapi.ActorTemplate{Metadata: &ateapi.ResourceMetadata{Uid: tmplUID}} localRT := testRuntime("amd64", "paused-under") localRT.SandboxClass = "microvm" durableRT := testRuntime("amd64", "suspended-under") - memory := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY - rootfs := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS - volumes := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES - completed := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED - pending := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING - - durable := func(gen int32, fidelity ateapipb.SnapshotFidelity, capturedUnder string, status ateapipb.SnapshotStorageStatus, rt *ateapipb.ActorSandboxRuntime) *ateapipb.Snapshot { - snap := newDurableSnapshot(gen, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, fidelity, capturedUnder, "snap", "gs://bucket/snap", status) + memory := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + rootfs := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS + volumes := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES + completed := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + pending := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + + durable := func(gen int32, fidelity ateapi.SnapshotFidelity, capturedUnder string, status ateapi.SnapshotStorageStatus, rt *ateapi.ActorSandboxRuntime) *ateapi.Snapshot { + snap := newDurableSnapshot(gen, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, fidelity, capturedUnder, "snap", "gs://bucket/snap", status) snap.SandboxRuntime = rt return snap } - local := func(gen int32, fidelity ateapipb.SnapshotFidelity, capturedUnder string, rt *ateapipb.ActorSandboxRuntime) *ateapipb.Snapshot { + local := func(gen int32, fidelity ateapi.SnapshotFidelity, capturedUnder string, rt *ateapi.ActorSandboxRuntime) *ateapi.Snapshot { snap := newPausedSnapshot(t, gen, fidelity, capturedUnder, "local", "node-1") snap.SandboxRuntime = rt return snap @@ -3004,66 +3063,66 @@ func TestRequiredSnapshotRuntime(t *testing.T) { tests := []struct { name string - snapshots []*ateapipb.Snapshot - want *ateapipb.ActorSandboxRuntime + snapshots []*ateapi.Snapshot + want *ateapi.ActorSandboxRuntime wantClass string }{ {name: "no snapshot cold-boots unconstrained"}, { name: "completed MEMORY durable snapshot requires its runtime", - snapshots: []*ateapipb.Snapshot{durable(1, memory, tmplUID, completed, durableRT)}, + snapshots: []*ateapi.Snapshot{durable(1, memory, tmplUID, completed, durableRT)}, want: durableRT, wantClass: "gvisor", }, { name: "completed ROOTFS durable snapshot restores no memory state", - snapshots: []*ateapipb.Snapshot{durable(1, rootfs, tmplUID, completed, durableRT)}, + snapshots: []*ateapi.Snapshot{durable(1, rootfs, tmplUID, completed, durableRT)}, wantClass: "gvisor", }, { name: "VOLUMES durable snapshot restores no memory state", - snapshots: []*ateapipb.Snapshot{durable(1, volumes, tmplUID, completed, durableRT)}, + snapshots: []*ateapi.Snapshot{durable(1, volumes, tmplUID, completed, durableRT)}, wantClass: "gvisor", }, { name: "durable snapshot captured under a replaced template is not restored", - snapshots: []*ateapipb.Snapshot{durable(1, memory, "old-tmpl-uid", completed, durableRT)}, + snapshots: []*ateapi.Snapshot{durable(1, memory, "old-tmpl-uid", completed, durableRT)}, wantClass: "gvisor", }, { name: "durable snapshot with no template uid keeps its runtime", - snapshots: []*ateapipb.Snapshot{durable(1, memory, "", completed, durableRT)}, + snapshots: []*ateapi.Snapshot{durable(1, memory, "", completed, durableRT)}, want: durableRT, wantClass: "gvisor", }, { name: "unstamped durable snapshot imposes no constraint", - snapshots: []*ateapipb.Snapshot{durable(1, memory, tmplUID, completed, nil)}, + snapshots: []*ateapi.Snapshot{durable(1, memory, tmplUID, completed, nil)}, }, { name: "PENDING durable snapshot is not a restore source", - snapshots: []*ateapipb.Snapshot{durable(1, memory, tmplUID, pending, durableRT)}, + snapshots: []*ateapi.Snapshot{durable(1, memory, tmplUID, pending, durableRT)}, }, { name: "local checkpoint requires its runtime", - snapshots: []*ateapipb.Snapshot{local(1, memory, tmplUID, localRT)}, + snapshots: []*ateapi.Snapshot{local(1, memory, tmplUID, localRT)}, want: localRT, wantClass: "microvm", }, { name: "local checkpoint with no template uid keeps its runtime", - snapshots: []*ateapipb.Snapshot{local(1, memory, "", localRT)}, + snapshots: []*ateapi.Snapshot{local(1, memory, "", localRT)}, want: localRT, wantClass: "microvm", }, { name: "local checkpoint captured under a replaced template is not restored", - snapshots: []*ateapipb.Snapshot{local(1, memory, "old-tmpl-uid", localRT)}, + snapshots: []*ateapi.Snapshot{local(1, memory, "old-tmpl-uid", localRT)}, wantClass: "microvm", }, { name: "newer durable snapshot takes precedence over an older local checkpoint", - snapshots: []*ateapipb.Snapshot{ + snapshots: []*ateapi.Snapshot{ local(1, memory, tmplUID, localRT), durable(2, memory, tmplUID, completed, durableRT), }, @@ -3072,7 +3131,7 @@ func TestRequiredSnapshotRuntime(t *testing.T) { }, { name: "newer local checkpoint takes precedence over an older durable snapshot", - snapshots: []*ateapipb.Snapshot{ + snapshots: []*ateapi.Snapshot{ local(2, memory, tmplUID, localRT), durable(1, memory, tmplUID, completed, durableRT), }, @@ -3081,7 +3140,7 @@ func TestRequiredSnapshotRuntime(t *testing.T) { }, { name: "ROOTFS local checkpoint imposes no constraint beside a stamped durable snapshot", - snapshots: []*ateapipb.Snapshot{ + snapshots: []*ateapi.Snapshot{ local(2, rootfs, tmplUID, localRT), durable(1, memory, tmplUID, completed, durableRT), }, @@ -3089,7 +3148,7 @@ func TestRequiredSnapshotRuntime(t *testing.T) { }, { name: "VOLUMES local checkpoint imposes no constraint beside a stamped durable snapshot", - snapshots: []*ateapipb.Snapshot{ + snapshots: []*ateapi.Snapshot{ local(2, volumes, tmplUID, localRT), durable(1, memory, tmplUID, completed, durableRT), }, @@ -3098,7 +3157,7 @@ func TestRequiredSnapshotRuntime(t *testing.T) { { // Restore uses the newer local snapshot's template. name: "local checkpoint ignores an older durable snapshot's replaced template", - snapshots: []*ateapipb.Snapshot{ + snapshots: []*ateapi.Snapshot{ durable(1, memory, "old-tmpl-uid", completed, durableRT), local(2, memory, tmplUID, localRT), }, @@ -3108,7 +3167,7 @@ func TestRequiredSnapshotRuntime(t *testing.T) { } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - actor := &ateapipb.Actor{Status: &ateapipb.ActorStatus{Snapshots: tc.snapshots}} + actor := &ateapi.Actor{Status: &ateapi.ActorStatus{Snapshots: tc.snapshots}} if diff := cmp.Diff(tc.want, requiredSnapshotRuntime(snapshotToResume(actor.GetStatus()), tmpl), protocmp.Transform()); diff != "" { t.Errorf("requiredSnapshotRuntime mismatch (-want +got):\n%s", diff) } @@ -3120,21 +3179,21 @@ func TestRequiredSnapshotRuntime(t *testing.T) { } // mockVolume returns a volume served by the "mock" plugin. -func mockVolume(name, storageID string) *ateapipb.ExternalVolumeStatus { - return &ateapipb.ExternalVolumeStatus{Name: name, StorageVolumeId: storageID, VolumeType: "mock"} +func mockVolume(name, storageID string) *ateapi.ExternalVolumeStatus { + return &ateapi.ExternalVolumeStatus{Name: name, StorageVolumeId: storageID, VolumeType: "mock"} } // volumeTemplate returns a template that declares the volumes named in // declared and mounts those named in mounted. -func volumeTemplate(declared []string, mounted ...string) *ateapipb.ActorTemplate { - tmpl := &ateapipb.ActorTemplate{ - Containers: []*ateapipb.Container{{Name: "main", Image: "img"}}, +func volumeTemplate(declared []string, mounted ...string) *ateapi.ActorTemplate { + tmpl := &ateapi.ActorTemplate{ + Containers: []*ateapi.Container{{Name: "main", Image: "img"}}, } for _, name := range declared { - tmpl.Volumes = append(tmpl.Volumes, &ateapipb.Volume{Name: name, External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{StorageClassName: "sc"}}}) + tmpl.Volumes = append(tmpl.Volumes, &ateapi.Volume{Name: name, External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "sc"}}}) } for _, name := range mounted { - tmpl.Containers[0].VolumeMounts = append(tmpl.Containers[0].VolumeMounts, &ateapipb.VolumeMount{Name: name, MountPath: "/" + name}) + tmpl.Containers[0].VolumeMounts = append(tmpl.Containers[0].VolumeMounts, &ateapi.VolumeMount{Name: name, MountPath: "/" + name}) } return tmpl } @@ -3142,26 +3201,26 @@ func volumeTemplate(declared []string, mounted ...string) *ateapipb.ActorTemplat // seedVolumeAssignFixture stores one free gvisor worker on node and a // SUSPENDED actor holding volumes, and returns the stored actor plus a // started worker cache. -func seedVolumeAssignFixture(t *testing.T, ctx context.Context, persistence store.Interface, node string, volumes ...*ateapipb.ExternalVolumeStatus) (*ateapipb.Actor, *workercache.Cache) { +func seedVolumeAssignFixture(t *testing.T, ctx context.Context, persistence store.Interface, node string, volumes ...*ateapi.ExternalVolumeStatus) (*ateapi.Actor, *workercache.Cache) { t.Helper() - if _, err := persistence.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: testWorkerUID("pod-1")}, + if _, err := persistence.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: testWorkerUID("pod-1")}, WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "pod-1", WorkerPodUid: testWorkerUID("pod-1"), NodeName: node, - Status: registered(&ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Status: registered(&ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: workerSandboxClasses(testSandboxRuntime()), }), }); err != nil { t.Fatalf("CreateWorker: %v", err) } - storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: volumes}}, + storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, ExternalVolumes: &ateapi.ExternalVolumes{Volumes: volumes}}, }) actor, err := persistence.GetActor(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}) if err != nil { @@ -3198,7 +3257,7 @@ func TestResume_ChecksMountedVolumesBeforeAttach(t *testing.T) { tests := []struct { name string // last is the second mounted volume, placed after every other volume. - last *ateapipb.ExternalVolumeStatus + last *ateapi.ExternalVolumeStatus // wantErr is a substring of the expected FailedPrecondition; empty // means the attach succeeds. wantErr string @@ -3273,24 +3332,24 @@ func TestResume_ChecksMountedVolumesBeforeAttach(t *testing.T) { // when it has one, and never while a local pause checkpoint pins the actor. func TestCanRelaxRuntime(t *testing.T) { rt := testSandboxRuntime() - memory := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY - completed := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED - pending := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING - suspended := ateapipb.ActorState_ACTOR_STATE_SUSPENDED - resuming := ateapipb.ActorState_ACTOR_STATE_RESUMING + memory := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + completed := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + pending := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + suspended := ateapi.ActorState_ACTOR_STATE_SUSPENDED + resuming := ateapi.ActorState_ACTOR_STATE_RESUMING - durable := func(gen int32) *ateapipb.Snapshot { - return newDurableSnapshot(gen, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", "snap", "gs://bucket/snap", completed) + durable := func(gen int32) *ateapi.Snapshot { + return newDurableSnapshot(gen, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", "snap", "gs://bucket/snap", completed) } - local := func(gen int32) *ateapipb.Snapshot { + local := func(gen int32) *ateapi.Snapshot { return newPausedSnapshot(t, gen, memory, "", "local", "node-1") } - localDurable := func(gen int32, storageStatus ateapipb.SnapshotStorageStatus) *ateapipb.Snapshot { + localDurable := func(gen int32, storageStatus ateapi.SnapshotStorageStatus) *ateapi.Snapshot { snap := local(gen) snap.GetDurableSnapshot().Status = storageStatus return snap } - localNoDurable := func(gen int32) *ateapipb.Snapshot { + localNoDurable := func(gen int32) *ateapi.Snapshot { snap := local(gen) snap.DurableSnapshot = nil return snap @@ -3298,21 +3357,21 @@ func TestCanRelaxRuntime(t *testing.T) { tests := []struct { name string - state ateapipb.ActorState + state ateapi.ActorState node string - snapshots []*ateapipb.Snapshot - required *ateapipb.ActorSandboxRuntime + snapshots []*ateapi.Snapshot + required *ateapi.ActorSandboxRuntime want bool }{ { name: "nothing to relax without a runtime constraint", state: suspended, - snapshots: []*ateapipb.Snapshot{durable(1)}, + snapshots: []*ateapi.Snapshot{durable(1)}, }, { name: "durable snapshot may fall back", state: suspended, - snapshots: []*ateapipb.Snapshot{durable(1)}, + snapshots: []*ateapi.Snapshot{durable(1)}, required: rt, want: true, }, @@ -3320,27 +3379,27 @@ func TestCanRelaxRuntime(t *testing.T) { name: "local checkpoint stays pinned", state: suspended, node: "node-1", - snapshots: []*ateapipb.Snapshot{local(1)}, + snapshots: []*ateapi.Snapshot{local(1)}, required: rt, }, { name: "local checkpoint stays pinned beside a durable snapshot", state: suspended, node: "node-1", - snapshots: []*ateapipb.Snapshot{durable(1), local(2)}, + snapshots: []*ateapi.Snapshot{durable(1), local(2)}, required: rt, }, { name: "uploaded checkpoint detaches before relaxing a pinned actor", state: suspended, node: "node-1", - snapshots: []*ateapipb.Snapshot{localDurable(2, completed)}, + snapshots: []*ateapi.Snapshot{localDurable(2, completed)}, required: rt, }, { name: "unbound uploaded checkpoint may fall back", state: suspended, - snapshots: []*ateapipb.Snapshot{localDurable(2, completed)}, + snapshots: []*ateapi.Snapshot{localDurable(2, completed)}, required: rt, want: true, }, @@ -3348,7 +3407,7 @@ func TestCanRelaxRuntime(t *testing.T) { name: "resuming uploaded checkpoint keeps its relaxed assignment", state: resuming, node: "node-1", - snapshots: []*ateapipb.Snapshot{localDurable(2, completed)}, + snapshots: []*ateapi.Snapshot{localDurable(2, completed)}, required: rt, want: true, }, @@ -3356,41 +3415,56 @@ func TestCanRelaxRuntime(t *testing.T) { name: "resuming pending checkpoint cannot relax", state: resuming, node: "node-1", - snapshots: []*ateapipb.Snapshot{localDurable(2, pending)}, + snapshots: []*ateapi.Snapshot{localDurable(2, pending)}, required: rt, }, { name: "resuming checkpoint without a durable copy cannot relax", state: resuming, node: "node-1", - snapshots: []*ateapipb.Snapshot{localNoDurable(2)}, + snapshots: []*ateapi.Snapshot{localNoDurable(2)}, required: rt, }, { name: "older durable copy cannot authorize a resuming checkpoint", state: resuming, node: "node-1", - snapshots: []*ateapipb.Snapshot{durable(1), localNoDurable(2)}, + snapshots: []*ateapi.Snapshot{durable(1), localNoDurable(2)}, required: rt, }, { name: "pinned actor detaches before relaxing a newer durable snapshot", state: suspended, node: "node-1", - snapshots: []*ateapipb.Snapshot{local(1), durable(2)}, + snapshots: []*ateapi.Snapshot{local(1), durable(2)}, + required: rt, + }, + { + name: "pending checkpoint released from its deleted node may fall back", + state: suspended, + snapshots: []*ateapi.Snapshot{localDurable(2, pending)}, required: rt, + want: true, + }, + { + name: "resuming pending checkpoint from a deleted node keeps its relaxed assignment", + state: resuming, + node: "node-2", + snapshots: []*ateapi.Snapshot{localDurable(2, pending)}, + required: rt, + want: true, }, { name: "newer durable snapshot may fall back beside an older pending checkpoint", state: suspended, - snapshots: []*ateapipb.Snapshot{localDurable(1, pending), durable(2)}, + snapshots: []*ateapi.Snapshot{localDurable(1, pending), durable(2)}, required: rt, want: true, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - actor := &ateapipb.Actor{Status: &ateapipb.ActorStatus{ + actor := &ateapi.Actor{Status: &ateapi.ActorStatus{ State: tc.state, AssignedNode: tc.node, Snapshots: tc.snapshots, @@ -3406,7 +3480,7 @@ func TestCanRelaxRuntime(t *testing.T) { // so the worker's has to reach it. func TestWorkerAssignmentFromCopiesSPIFFEID(t *testing.T) { const id = "spiffe://cluster.local/ns/workers/sa/substrate-worker" - got := workerAssignmentFrom(&ateapipb.Worker{WorkerSpiffeId: id}, hardware.Requirement{}) + got := workerAssignmentFrom(&ateapi.Worker{WorkerSpiffeId: id}, hardware.Requirement{}) if got.GetWorkerSpiffeId() != id { t.Errorf("worker SPIFFE ID = %q, want %q", got.GetWorkerSpiffeId(), id) } @@ -3415,22 +3489,22 @@ func TestWorkerAssignmentFromCopiesSPIFFEID(t *testing.T) { func TestToAteletSandboxRuntime(t *testing.T) { tests := []struct { name string - in *ateapipb.ActorSandboxRuntime + in *ateapi.ActorSandboxRuntime want *ateletpb.ActorSandboxRuntime }{ {name: "nil"}, { name: "class only", - in: &ateapipb.ActorSandboxRuntime{SandboxClass: "gvisor"}, + in: &ateapi.ActorSandboxRuntime{SandboxClass: "gvisor"}, want: &ateletpb.ActorSandboxRuntime{SandboxClass: "gvisor"}, }, { name: "full", - in: &ateapipb.ActorSandboxRuntime{ + in: &ateapi.ActorSandboxRuntime{ SandboxClass: "gvisor", - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{ + Attributes: []*ateapi.AttributeEntry{ {Key: "architecture", Value: "amd64"}, {Key: "cpu_features", Value: "3f"}, }, diff --git a/cmd/ateapi/internal/controlapi/workflow_revert.go b/cmd/ateapi/internal/controlapi/workflow_revert.go index 55c239fe25..6c553fcd91 100644 --- a/cmd/ateapi/internal/controlapi/workflow_revert.go +++ b/cmd/ateapi/internal/controlapi/workflow_revert.go @@ -22,12 +22,12 @@ import ( "slices" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel/attribute" ) @@ -36,17 +36,17 @@ import ( // discards the node-local copy and returns the actor to its latest durable // snapshot, which is that same snapshot once atelet's upload of it is // recorded. See isRevertable. -var revertableStates = []ateapipb.ActorState{ - ateapipb.ActorState_ACTOR_STATE_RUNNING, - ateapipb.ActorState_ACTOR_STATE_CRASHED, +var revertableStates = []ateapi.ActorState{ + ateapi.ActorState_ACTOR_STATE_RUNNING, + ateapi.ActorState_ACTOR_STATE_CRASHED, } // isRevertable reports whether a revert is accepted from the actor's current // state and snapshot shape. -func isRevertable(actor *ateapipb.Actor) bool { +func isRevertable(actor *ateapi.Actor) bool { state := actor.GetStatus().GetState() return slices.Contains(revertableStates, state) || - (state == ateapipb.ActorState_ACTOR_STATE_SUSPENDED && latestSnapshotIsLocal(actor.GetStatus())) + (state == ateapi.ActorState_ACTOR_STATE_SUSPENDED && latestSnapshotIsLocal(actor.GetStatus())) } // RevertActor executes the workflow to discard an actor's current execution and @@ -57,11 +57,11 @@ func isRevertable(actor *ateapipb.Actor) bool { // Idempotent: each step keys on a persisted field rather than on the state the // actor was reverted from, so a re-entered workflow fast-forwards to wherever // the previous attempt stopped. -func (w *ActorWorkflow) RevertActor(ctx context.Context, actorRef resources.ActorRef) (_ *ateapipb.Actor, err error) { +func (w *ActorWorkflow) RevertActor(ctx context.Context, actorRef resources.ActorRef) (_ *ateapi.Actor, err error) { ctx = preview.ContextWithOptIn(ctx) start := time.Now() - var actor *ateapipb.Actor - var actorTemplate *ateapipb.ActorTemplate + var actor *ateapi.Actor + var actorTemplate *ateapi.ActorTemplate // Set just before finalize; nil until then, so earlier exits label // themselves from the record they hold. var finalAttrs []attribute.KeyValue @@ -85,7 +85,7 @@ func (w *ActorWorkflow) RevertActor(ctx context.Context, actorRef resources.Acto return nil, err } - var marked *ateapipb.Actor + var marked *ateapi.Actor if marked, err = w.ensureMarkedReverting(leaseCtx, actorRef, actor); err != nil { return nil, err } @@ -105,7 +105,7 @@ func (w *ActorWorkflow) RevertActor(ctx context.Context, actorRef resources.Acto // FinalizeReverted clears the WorkerAssignment the labels read, so snapshot // them here, as suspend and crash.go do. finalAttrs = lifecycleOpAttrs(actor, "", "") - var finalized *ateapipb.Actor + var finalized *ateapi.Actor if finalized, err = w.ensureRevertedFinalized(leaseCtx, actorRef); err != nil { return nil, err } @@ -113,7 +113,7 @@ func (w *ActorWorkflow) RevertActor(ctx context.Context, actorRef resources.Acto } // loadActorForRevert fetches the current actor record and its template. -func (w *ActorWorkflow) loadActorForRevert(ctx context.Context, actorRef resources.ActorRef) (_ *ateapipb.Actor, _ *ateapipb.ActorTemplate, err error) { +func (w *ActorWorkflow) loadActorForRevert(ctx context.Context, actorRef resources.ActorRef) (_ *ateapi.Actor, _ *ateapi.ActorTemplate, err error) { ctx, done := stepSpan(ctx, "LoadActorForRevert") defer func() { err = done(err) }() @@ -142,21 +142,21 @@ func (w *ActorWorkflow) loadActorForRevert(ctx context.Context, actorRef resourc // ensureMarkedReverting transitions the actor to REVERTING and persists the // change. Skips when a previous attempt already marked it, which is what makes // the rest of the workflow re-enterable. -func (w *ActorWorkflow) ensureMarkedReverting(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor) (_ *ateapipb.Actor, err error) { +func (w *ActorWorkflow) ensureMarkedReverting(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor) (_ *ateapi.Actor, err error) { ctx, done := stepSpan(ctx, "MarkReverting") defer func() { err = done(err) }() st := actor.GetStatus().GetState() - if st == ateapipb.ActorState_ACTOR_STATE_REVERTING { + if st == ateapi.ActorState_ACTOR_STATE_REVERTING { markSkipped(ctx, "actor already REVERTING") return actor, nil } if !isRevertable(actor) { - return nil, apierror.FailedPrecondition("Actor %s is not in a revertable state (got: %v, want one of %v, or %s with a node-local snapshot)", actorRef, st, revertableStates, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + return nil, apierror.FailedPrecondition("Actor %s is not in a revertable state (got: %v, want one of %v, or %s with a node-local snapshot)", actorRef, st, revertableStates, ateapi.ActorState_ACTOR_STATE_SUSPENDED) } - storedActor, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapipb.Actor) error { - toUpdate.Status.State = ateapipb.ActorState_ACTOR_STATE_REVERTING + storedActor, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapi.Actor) error { + toUpdate.Status.State = ateapi.ActorState_ACTOR_STATE_REVERTING return nil }) if err != nil { @@ -181,7 +181,7 @@ func (w *ActorWorkflow) ensureMarkedReverting(ctx context.Context, actorRef reso // worker. An assignment commits before the actor is updated to point at it, so // a crash in between leaves a row nothing references — and a CRASHED actor is // the likeliest holder of one. Absence is the ordinary case, not an error. -func (w *ActorWorkflow) ensureWorkerDiscarded(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor, actorTemplate *ateapipb.ActorTemplate) (err error) { +func (w *ActorWorkflow) ensureWorkerDiscarded(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor, actorTemplate *ateapi.ActorTemplate) (err error) { ctx, done := stepSpan(ctx, "DiscardWorker") defer func() { err = done(err) }() @@ -213,14 +213,14 @@ func (w *ActorWorkflow) ensureWorkerDiscarded(ctx context.Context, actorRef reso // ensureInProgressSnapshotDiscarded removes pending uploads of the discarded execution. // The actor keeps its latest completed durable snapshot. -func (w *ActorWorkflow) ensureInProgressSnapshotDiscarded(ctx context.Context, actor *ateapipb.Actor) (err error) { +func (w *ActorWorkflow) ensureInProgressSnapshotDiscarded(ctx context.Context, actor *ateapi.Actor) (err error) { ctx, done := stepSpan(ctx, "DiscardInProgressSnapshot") defer func() { err = done(err) }() var inProgress []string for _, snap := range actor.GetStatus().GetSnapshots() { storage := snap.GetDurableSnapshot() - if storage.GetStatus() == ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING && storage.GetObject().GetSnapshotUri() != "" { + if storage.GetStatus() == ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING && storage.GetObject().GetSnapshotUri() != "" { inProgress = append(inProgress, storage.GetObject().GetSnapshotUri()) } } @@ -264,7 +264,7 @@ func (w *ActorWorkflow) ensureInProgressSnapshotDiscarded(ctx context.Context, a // external snapshots the update dropped. // It re-reads the actor first so an out-of-band transition is not overwritten, // and so the version precondition guards what was actually observed. -func (w *ActorWorkflow) ensureRevertedFinalized(ctx context.Context, actorRef resources.ActorRef) (_ *ateapipb.Actor, err error) { +func (w *ActorWorkflow) ensureRevertedFinalized(ctx context.Context, actorRef resources.ActorRef) (_ *ateapi.Actor, err error) { ctx, done := stepSpan(ctx, "FinalizeReverted") defer func() { err = done(err) }() @@ -272,12 +272,12 @@ func (w *ActorWorkflow) ensureRevertedFinalized(ctx context.Context, actorRef re if err != nil { return nil, err } - if got := latestActor.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_REVERTING { - return nil, apierror.FailedPrecondition("FinalizeReverted prerequisite not met for Actor: %s (got: %v, want %s)", actorRef, got, ateapipb.ActorState_ACTOR_STATE_REVERTING) + if got := latestActor.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_REVERTING { + return nil, apierror.FailedPrecondition("FinalizeReverted prerequisite not met for Actor: %s (got: %v, want %s)", actorRef, got, ateapi.ActorState_ACTOR_STATE_REVERTING) } - storedActor, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(latestActor), func(toUpdate *ateapipb.Actor) error { - toUpdate.Status.State = ateapipb.ActorState_ACTOR_STATE_SUSPENDED + storedActor, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(latestActor), func(toUpdate *ateapi.Actor) error { + toUpdate.Status.State = ateapi.ActorState_ACTOR_STATE_SUSPENDED toUpdate.Status.WorkerAssignment = nil toUpdate.Status.AssignedNode = "" // We revert back to the latest durable snapshot, so all local snapshots diff --git a/cmd/ateapi/internal/controlapi/workflow_revert_test.go b/cmd/ateapi/internal/controlapi/workflow_revert_test.go index 5405ee2d08..40d247d296 100644 --- a/cmd/ateapi/internal/controlapi/workflow_revert_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_revert_test.go @@ -19,13 +19,13 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/objectstore/objectstoretest" "go.ate.dev/substrate/internal/objectstoreplugin/objectstoreplugintest" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" ) @@ -40,12 +40,12 @@ import ( // holds a node-local snapshot is accepted; see // TestEnsureMarkedReverting_AcceptsPaused. func TestEnsureMarkedReverting_StateMatrix(t *testing.T) { - allowed := map[ateapipb.ActorState]bool{ - ateapipb.ActorState_ACTOR_STATE_RUNNING: true, - ateapipb.ActorState_ACTOR_STATE_CRASHED: true, + allowed := map[ateapi.ActorState]bool{ + ateapi.ActorState_ACTOR_STATE_RUNNING: true, + ateapi.ActorState_ACTOR_STATE_CRASHED: true, // Re-entry: a previous attempt already marked it, so the step skips // rather than re-committing. - ateapipb.ActorState_ACTOR_STATE_REVERTING: true, + ateapi.ActorState_ACTOR_STATE_REVERTING: true, } for _, seedState := range allActorStates { @@ -63,7 +63,7 @@ func TestEnsureMarkedReverting_StateMatrix(t *testing.T) { updated, err := w.ensureMarkedReverting(ctx, actorRef, actor) assertPrerequisiteResult(t, seedState, err, allowed[seedState]) if err == nil { - if got := updated.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_REVERTING { + if got := updated.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_REVERTING { t.Errorf("state %v: ensureMarkedReverting returned actor in %v, want REVERTING", seedState, got) } } @@ -81,7 +81,7 @@ func TestEnsureMarkedReverting_AcceptsPaused(t *testing.T) { w := newTestActorWorkflow(t, st, "ns", "tmpl1") actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_SUSPENDED, withPausedShape(t, "node-1")) + seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_SUSPENDED, withPausedShape(t, "node-1")) actor, err := st.GetActor(ctx, actorRef) if err != nil { t.Fatalf("get seeded actor: %v", err) @@ -91,7 +91,7 @@ func TestEnsureMarkedReverting_AcceptsPaused(t *testing.T) { if err != nil { t.Fatalf("ensureMarkedReverting: %v", err) } - if got := updated.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_REVERTING { + if got := updated.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_REVERTING { t.Errorf("state = %v, want REVERTING", got) } } @@ -106,17 +106,17 @@ func TestEnsureMarkedReverting_AcceptsPaused(t *testing.T) { func TestRevertActor_ReturnsActorToItsSnapshot(t *testing.T) { for _, tc := range []struct { name string - seedState ateapipb.ActorState + seedState ateapi.ActorState // paused seeds the local-snapshot shape: the latest snapshot is node-local // and the actor is pinned to its node. Only meaningful with // SUSPENDED, which the revert otherwise rejects. paused bool }{ - {name: "RUNNING", seedState: ateapipb.ActorState_ACTOR_STATE_RUNNING}, - {name: "paused", seedState: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, paused: true}, - {name: "CRASHED", seedState: ateapipb.ActorState_ACTOR_STATE_CRASHED}, + {name: "RUNNING", seedState: ateapi.ActorState_ACTOR_STATE_RUNNING}, + {name: "paused", seedState: ateapi.ActorState_ACTOR_STATE_SUSPENDED, paused: true}, + {name: "CRASHED", seedState: ateapi.ActorState_ACTOR_STATE_CRASHED}, // A revert that died partway is retried, not rejected. - {name: "REVERTING", seedState: ateapipb.ActorState_ACTOR_STATE_REVERTING}, + {name: "REVERTING", seedState: ateapi.ActorState_ACTOR_STATE_REVERTING}, } { seedState := tc.seedState t.Run(tc.name, func(t *testing.T) { @@ -137,16 +137,16 @@ func TestRevertActor_ReturnsActorToItsSnapshot(t *testing.T) { // latest snapshot is the completed local one; the other origins // also carry the half-written local snapshot an interrupted suspend // leaves. - const keptURI = "gs://snapshots/team-a/actors/keep/snapshot" - tmpl := &ateapipb.ActorTemplate{SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: "gs://snapshots"}} - mustUpdateActorStatus(t, ctx, st, actor, func(s *ateapipb.ActorStatus) { - local1 := newPausedSnapshot(t, 2, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "local-1", "node-1") + const keptURI = "gs://snapshots/atespaces/team-a/actors/keep/snapshots/snapshot" + tmpl := &ateapi.ActorTemplate{SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: "gs://snapshots"}} + mustUpdateActorStatus(t, ctx, st, actor, func(s *ateapi.ActorStatus) { + local1 := newPausedSnapshot(t, 2, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "local-1", "node-1") local1.DurableSnapshot.Object.SnapshotUri = mustActorSnapshotURI(t, tmpl, actor, "local-1").String() - inProgress := newPausedSnapshot(t, 3, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "local-in-progress", "") + inProgress := newPausedSnapshot(t, 3, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "local-in-progress", "") inProgress.DurableSnapshot.Object.SnapshotUri = mustActorSnapshotURI(t, tmpl, actor, "local-in-progress").String() s.LastAssignedGeneration = 3 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "kept", keptURI, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "kept", keptURI, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), local1, inProgress, } @@ -161,7 +161,7 @@ func TestRevertActor_ReturnsActorToItsSnapshot(t *testing.T) { } gotStatus := reverted.GetStatus() - if got := gotStatus.GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := gotStatus.GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state = %v, want SUSPENDED", got) } // LastAssignedGeneration is not decreased on revert so we can keep track @@ -170,7 +170,7 @@ func TestRevertActor_ReturnsActorToItsSnapshot(t *testing.T) { if got := gotStatus.GetLastAssignedGeneration(); got != 3 { t.Errorf("last_assigned_generation = %d, want 3", got) } - gotSnap := findLatestDurableSnapshot(gotStatus, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + gotSnap := findLatestDurableSnapshot(gotStatus, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) if got := gotSnap.GetGeneration(); got != 1 { t.Errorf("retained snapshot generation = %d, want 1", got) } @@ -183,7 +183,7 @@ func TestRevertActor_ReturnsActorToItsSnapshot(t *testing.T) { if got := findLatestLocalSnapshot(gotStatus); got != nil { t.Errorf("local snapshot info = %v, want nil", got) } - if got := findLatestDurableSnapshot(gotStatus, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING); got != nil { + if got := findLatestDurableSnapshot(gotStatus, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING); got != nil { t.Errorf("in-progress durable snapshot = %v, want nil", got) } if got := len(gotStatus.GetSnapshots()); got != 1 { @@ -198,8 +198,8 @@ func TestRevertActor_ReturnsActorToItsSnapshot(t *testing.T) { // If the actor runs again and takes another snapshot, it must // allocate generation 4 rather than reusing 2 or 3. - running := mustUpdateActorStatus(t, ctx, st, reverted, func(s *ateapipb.ActorStatus) { - s.State = ateapipb.ActorState_ACTOR_STATE_RUNNING + running := mustUpdateActorStatus(t, ctx, st, reverted, func(s *ateapi.ActorStatus) { + s.State = ateapi.ActorState_ACTOR_STATE_RUNNING s.AssignedNode = "node-1" s.WorkerAssignment = wireTestAssignment() }) @@ -251,29 +251,29 @@ func TestRevertActor_UnreachableNode(t *testing.T) { wire, atelet := newWireCaptureWorkflow(t, st) w.dialer = wire.dialer ref := resources.ActorRef{Atespace: "team-a", Name: "id1"} - seedWorkflowActor(t, ctx, st, ref, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + seedWorkflowActor(t, ctx, st, ref, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_SUSPENDED) actor, err := st.GetActor(ctx, ref) if err != nil { t.Fatal(err) } - actor = mustUpdateActorStatus(t, ctx, st, actor, func(s *ateapipb.ActorStatus) { + actor = mustUpdateActorStatus(t, ctx, st, actor, func(s *ateapi.ActorStatus) { s.AssignedNode = tt.node s.LastAssignedGeneration = 2 - snap := newPausedSnapshot(t, 2, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "uploaded", tt.node) - snap.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + snap := newPausedSnapshot(t, 2, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "uploaded", tt.node) + snap.DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED if tt.pending { - snap.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + snap.DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING } - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, snap.GetFidelity(), "", "older", "gs://snapshots/team-a/actors/older/snapshot", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, snap.GetFidelity(), "", "older", "gs://snapshots/atespaces/team-a/actors/older/snapshots/snapshot", ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), snap, } if tt.assigned { - s.State = ateapipb.ActorState_ACTOR_STATE_RUNNING + s.State = ateapi.ActorState_ACTOR_STATE_RUNNING s.WorkerAssignment = wireTestAssignment() } if tt.crashed { - s.State = ateapipb.ActorState_ACTOR_STATE_CRASHED + s.State = ateapi.ActorState_ACTOR_STATE_CRASHED s.Crash = newActorCrash("ResumeActor", "interrupted execution") } }) @@ -286,8 +286,8 @@ func TestRevertActor_UnreachableNode(t *testing.T) { t.Errorf("GetActor: %v", err) return } - if _, err := st.UpdateActor(ctx, ref, store.PreconditionFrom(cur), func(a *ateapipb.Actor) error { - a.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"changed": "true"}} + if _, err := st.UpdateActor(ctx, ref, store.PreconditionFrom(cur), func(a *ateapi.Actor) error { + a.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"changed": "true"}} return nil }); err != nil { t.Errorf("UpdateActor: %v", err) @@ -304,7 +304,7 @@ func TestRevertActor_UnreachableNode(t *testing.T) { t.Fatal(err) } got := stored.GetStatus() - if got.GetState() != ateapipb.ActorState_ACTOR_STATE_REVERTING || got.GetAssignedNode() != tt.node { + if got.GetState() != ateapi.ActorState_ACTOR_STATE_REVERTING || got.GetAssignedNode() != tt.node { t.Fatalf("status = %v, want REVERTING on %s", got, tt.node) } if !proto.Equal(got.GetSnapshots()[1], want) { @@ -322,7 +322,7 @@ func TestRevertActor_UnreachableNode(t *testing.T) { } } got := reverted.GetStatus() - if got.GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED || got.GetAssignedNode() != "" || got.GetWorkerAssignment() != nil { + if got.GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED || got.GetAssignedNode() != "" || got.GetWorkerAssignment() != nil { t.Fatalf("reverted status = %v, want unbound SUSPENDED", got) } if len(got.GetSnapshots()) != 1 { @@ -342,8 +342,8 @@ func TestRevertActor_UnreachableNode(t *testing.T) { // upload replaced. The actor has no assigned node, so there is nothing to // terminate, as in TestRevertActor_ReturnsActorToItsSnapshot. func TestRevertActor_PausedSnapshotAlreadyUploaded(t *testing.T) { - memory := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY - completed := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + memory := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + completed := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED ctx := context.Background() st, cleanup := storetest.SetupTestStore(t) defer cleanup() @@ -352,23 +352,23 @@ func TestRevertActor_PausedSnapshotAlreadyUploaded(t *testing.T) { w.objectStorePlugin = objectstoreplugintest.ControlClient(objects) actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_SUSPENDED) actor, err := st.GetActor(ctx, actorRef) if err != nil { t.Fatalf("get seeded actor: %v", err) } // newTestActorWorkflow's template stores snapshots under gs://snapshots. - tmpl := &ateapipb.ActorTemplate{SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: "gs://snapshots"}} + tmpl := &ateapi.ActorTemplate{SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: "gs://snapshots"}} old := mustActorSnapshotURI(t, tmpl, actor, "old") uploaded := mustActorSnapshotURI(t, tmpl, actor, "pause-snap") objects.PutSnapshot(t, old, "manifest.json") objects.PutSnapshot(t, uploaded, "manifest.json") - mustUpdateActorStatus(t, ctx, st, actor, func(s *ateapipb.ActorStatus) { + mustUpdateActorStatus(t, ctx, st, actor, func(s *ateapi.ActorStatus) { paused := newPausedSnapshot(t, 2, memory, "", "pause-snap", "node-1") - paused.DurableSnapshot = &ateapipb.SnapshotStorage{Status: completed, Object: &ateapipb.ObjectSnapshot{SnapshotUri: uploaded.String()}} + paused.DurableSnapshot = &ateapi.SnapshotStorage{Status: completed, Object: &ateapi.ObjectSnapshot{SnapshotUri: uploaded.String()}} s.LastAssignedGeneration = 2 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", old.Name(), old.String(), completed), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", old.Name(), old.String(), completed), paused, } }) @@ -401,7 +401,7 @@ func TestRevertActor_RejectsSuspended(t *testing.T) { w := newTestActorWorkflow(t, st, "ns", "tmpl1") actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_SUSPENDED) if _, err := w.RevertActor(ctx, actorRef); apierror.Code(err) != codes.FailedPrecondition { t.Fatalf("RevertActor = %v, want FailedPrecondition", err) @@ -415,7 +415,7 @@ func TestRevertActor_RejectsSuspended(t *testing.T) { w := newTestActorWorkflow(t, st, "ns", "tmpl1") actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_CRASHED) + seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_CRASHED) if _, err := w.RevertActor(ctx, actorRef); err != nil { t.Fatalf("first RevertActor: %v", err) @@ -436,13 +436,13 @@ func TestRevertActor_MissingTemplate(t *testing.T) { w := newTestActorWorkflow(t, st, "ns", "tmpl1") actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - seedWorkflowActor(t, ctx, st, actorRef, "ns", "missing-tmpl", ateapipb.ActorState_ACTOR_STATE_CRASHED) + seedWorkflowActor(t, ctx, st, actorRef, "ns", "missing-tmpl", ateapi.ActorState_ACTOR_STATE_CRASHED) reverted, err := w.RevertActor(ctx, actorRef) if err != nil { t.Fatalf("RevertActor: %v", err) } - if got := reverted.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := reverted.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state = %v, want SUSPENDED", got) } } @@ -458,7 +458,7 @@ func TestRevertActor_NoSnapshotToRevertTo(t *testing.T) { w := newTestActorWorkflow(t, st, "ns", "tmpl1") actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_CRASHED, func(a *ateapipb.Actor) { + seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_CRASHED, func(a *ateapi.Actor) { a.Status.Crash = newActorCrash("resume", crashMessageWorkerGone) }) @@ -466,13 +466,13 @@ func TestRevertActor_NoSnapshotToRevertTo(t *testing.T) { if err != nil { t.Fatalf("RevertActor: %v", err) } - if got := reverted.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := reverted.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state = %v, want SUSPENDED", got) } if got := reverted.GetStatus().GetCrash(); got != nil { t.Errorf("Crash = %v, want cleared by the revert", got) } - gotSnap := findLatestDurableSnapshot(reverted.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + gotSnap := findLatestDurableSnapshot(reverted.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) if got := gotSnap.GetDurableSnapshot().GetObject().GetSnapshotUri(); got != "" { t.Errorf("external snapshot = %q, want none", got) } @@ -552,19 +552,19 @@ func TestEnsureInProgressSnapshotDiscarded(t *testing.T) { template := seedSubstrateTemplate(t, ctx, persistence, "sub-tmpl") w, objects := newFinalizeWorkflow(persistence) - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_REVERTING}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_REVERTING}, }) // The actor's prefix is keyed on the UID the store just assigned, // so its snapshots can only be placed now. current := mustActorSnapshotURI(t, template, actor, "current") - currentType := ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR + currentType := ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR if tt.tagOwnedSnapshot { current = mustTagSnapshotURI(t, template, "team-a", "v1-snapshot") - currentType = ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG + currentType = ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG } objects.PutSnapshot(t, current, "manifest.json") inFlight := mustActorSnapshotURI(t, template, actor, inFlightSnapshotName) @@ -578,18 +578,18 @@ func TestEnsureInProgressSnapshotDiscarded(t *testing.T) { if tt.earlierPause { objects.PutSnapshot(t, earlierPause, "manifest.json") } - actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 1 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, currentType, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", current.Name(), current.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, currentType, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", current.Name(), current.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), } if tt.earlierPause { s.LastAssignedGeneration++ - s.Snapshots = append(s.Snapshots, newDurableSnapshot(s.LastAssignedGeneration, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", earlierPause.Name(), earlierPause.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING)) + s.Snapshots = append(s.Snapshots, newDurableSnapshot(s.LastAssignedGeneration, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", earlierPause.Name(), earlierPause.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING)) } if tt.inFlight != "" { s.LastAssignedGeneration++ - s.Snapshots = append(s.Snapshots, newDurableSnapshot(s.LastAssignedGeneration, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", inFlight.Name(), inFlight.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING)) + s.Snapshots = append(s.Snapshots, newDurableSnapshot(s.LastAssignedGeneration, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", inFlight.Name(), inFlight.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING)) } }) @@ -639,15 +639,15 @@ func TestEnsureRevertedFinalized_NoObjectStore(t *testing.T) { persistence := newTestPersistence(t) w := &ActorWorkflow{store: persistence} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_REVERTING, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_REVERTING, AssignedNode: "node-1", LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "abandoned", someActorSnapshotURI(t, testStorageLocation, "team-a", "abandoned"), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "abandoned", someActorSnapshotURI(t, testStorageLocation, "team-a", "abandoned"), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), }, }, }) @@ -661,13 +661,13 @@ func TestEnsureRevertedFinalized_NoObjectStore(t *testing.T) { if err != nil { t.Fatalf("ensureRevertedFinalized: %v", err) } - if got := finalized.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := finalized.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state = %v, want SUSPENDED", got) } if got := finalized.GetStatus().GetAssignedNode(); got != "" { t.Errorf("assigned node = %q, want empty", got) } - if got := findLatestDurableSnapshot(finalized.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING); got != nil { + if got := findLatestDurableSnapshot(finalized.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING); got != nil { t.Errorf("in-progress durable snapshot = %v, want nil", got) } } diff --git a/cmd/ateapi/internal/controlapi/workflow_suspend.go b/cmd/ateapi/internal/controlapi/workflow_suspend.go index f7a281923b..b0a2b801ef 100644 --- a/cmd/ateapi/internal/controlapi/workflow_suspend.go +++ b/cmd/ateapi/internal/controlapi/workflow_suspend.go @@ -21,13 +21,13 @@ import ( "log/slog" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel/attribute" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -53,8 +53,8 @@ const ( // suspendModeFromOptions maps a SuspendActor request's options to the // workflow mode. An unset mode runs an async suspend. -func suspendModeFromOptions(opts *ateapipb.SuspendOptions) suspendMode { - if opts.GetMode() == ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS { +func suspendModeFromOptions(opts *ateapi.SuspendOptions) suspendMode { + if opts.GetMode() == ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS { return suspendSync } return suspendAsync @@ -74,11 +74,11 @@ func (m suspendMode) uploadMode() ateletpb.UploadMode { // is returned as it is, whatever the mode. Idempotent: a re-entered workflow // fast-forwards past the steps a previous attempt completed, deriving // progress from the persisted actor alone. -func (w *ActorWorkflow) SuspendActor(ctx context.Context, actorRef resources.ActorRef, mode suspendMode) (_ *ateapipb.Actor, err error) { +func (w *ActorWorkflow) SuspendActor(ctx context.Context, actorRef resources.ActorRef, mode suspendMode) (_ *ateapi.Actor, err error) { ctx = preview.ContextWithOptIn(ctx) start := time.Now() - var actor *ateapipb.Actor - var actorTemplate *ateapipb.ActorTemplate + var actor *ateapi.Actor + var actorTemplate *ateapi.ActorTemplate var wireFidelity string // ateletState is the state atelet returned from Checkpoint, which // finalize applies. @@ -109,10 +109,10 @@ func (w *ActorWorkflow) SuspendActor(ctx context.Context, actorRef resources.Act // its snapshot is: atelet uploads a node-local snapshot in the background. // These successes report no pool, and cannot: the previous attempt // released the worker, so the record names none (#957). - if actor.GetStatus().GetState() == ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if actor.GetStatus().GetState() == ateapi.ActorState_ACTOR_STATE_SUSPENDED { return actor, nil } - var marked *ateapipb.Actor + var marked *ateapi.Actor if marked, err = w.ensureMarkedSuspending(leaseCtx, actorRef, actor, actorTemplate, mode); err != nil { return nil, err } @@ -129,7 +129,7 @@ func (w *ActorWorkflow) SuspendActor(ctx context.Context, actorRef resources.Act // them here, as crash.go does for the crash counter. The fidelity label is // the one requested. finalAttrs = lifecycleOpAttrs(actor, "", wireFidelity) - var finalized *ateapipb.Actor + var finalized *ateapi.Actor if finalized, err = w.ensureSuspendedFinalized(leaseCtx, actorRef, mode, ateletState); err != nil { return nil, err } @@ -138,7 +138,7 @@ func (w *ActorWorkflow) SuspendActor(ctx context.Context, actorRef resources.Act } // loadActorForSuspend fetches the current actor record and its template. -func (w *ActorWorkflow) loadActorForSuspend(ctx context.Context, actorRef resources.ActorRef) (_ *ateapipb.Actor, _ *ateapipb.ActorTemplate, err error) { +func (w *ActorWorkflow) loadActorForSuspend(ctx context.Context, actorRef resources.ActorRef) (_ *ateapi.Actor, _ *ateapi.ActorTemplate, err error) { ctx, done := stepSpan(ctx, "LoadActorForSuspend") defer func() { err = done(err) }() @@ -159,15 +159,15 @@ func (w *ActorWorkflow) loadActorForSuspend(ctx context.Context, actorRef resour // when a previous attempt already marked the actor, in either mode; the // persisted snapshot and source version then stay authoritative for the rest // of the workflow. -func (w *ActorWorkflow) ensureMarkedSuspending(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor, actorTemplate *ateapipb.ActorTemplate, mode suspendMode) (_ *ateapipb.Actor, err error) { +func (w *ActorWorkflow) ensureMarkedSuspending(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor, actorTemplate *ateapi.ActorTemplate, mode suspendMode) (_ *ateapi.Actor, err error) { ctx, done := stepSpan(ctx, "MarkSuspending") defer func() { err = done(err) }() state := actor.GetStatus().GetState() - if state != ateapipb.ActorState_ACTOR_STATE_RUNNING && state != ateapipb.ActorState_ACTOR_STATE_SUSPENDING { - return nil, apierror.FailedPrecondition("MarkSuspending prerequisite not met for Actor: %s (got: %v, want %s)", actorRef, state, ateapipb.ActorState_ACTOR_STATE_RUNNING) + if state != ateapi.ActorState_ACTOR_STATE_RUNNING && state != ateapi.ActorState_ACTOR_STATE_SUSPENDING { + return nil, apierror.FailedPrecondition("MarkSuspending prerequisite not met for Actor: %s (got: %v, want %s)", actorRef, state, ateapi.ActorState_ACTOR_STATE_RUNNING) } - if state == ateapipb.ActorState_ACTOR_STATE_SUSPENDING { + if state == ateapi.ActorState_ACTOR_STATE_SUSPENDING { markSkipped(ctx, "actor already SUSPENDING") return actor, nil } @@ -179,8 +179,8 @@ func (w *ActorWorkflow) ensureMarkedSuspending(ctx context.Context, actorRef res if err != nil { return nil, err } - storedActor, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapipb.Actor) error { - toUpdate.Status.State = ateapipb.ActorState_ACTOR_STATE_SUSPENDING + storedActor, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapi.Actor) error { + toUpdate.Status.State = ateapi.ActorState_ACTOR_STATE_SUSPENDING // Increment last_assigned_generation for the new Suspend request and create // a snapshot for that generation with a pending durable copy. Both modes // record where the snapshot is uploaded, so the mode can change on a retry. @@ -189,12 +189,12 @@ func (w *ActorWorkflow) ensureMarkedSuspending(ctx context.Context, actorRef res snap := newDurableSnapshot( gen, - ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, + ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, actorTemplate.GetSnapshotConfig().GetPreferredFidelity(), actorTemplate.GetMetadata().GetUid(), uri.Name(), uri.String(), - ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING, + ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING, ) snap.SandboxRuntime = proto.CloneOf(toUpdate.GetStatus().GetWorkerAssignment().GetSandboxRuntime()) toUpdate.Status.Snapshots = append(toUpdate.Status.Snapshots, snap) @@ -219,7 +219,7 @@ func (w *ActorWorkflow) ensureMarkedSuspending(ctx context.Context, actorRef res // ensureMarkedSuspending minted once, and atelet answers a Checkpoint of a // snapshot it already committed without checkpointing again, so a retry after // a lost response succeeds. -func (w *ActorWorkflow) ensureAteletSuspended(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor, actorTemplate *ateapipb.ActorTemplate, mode suspendMode) (wireFidelity string, state *ateletpb.ActorSnapshotState, err error) { +func (w *ActorWorkflow) ensureAteletSuspended(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor, actorTemplate *ateapi.ActorTemplate, mode suspendMode) (wireFidelity string, state *ateletpb.ActorSnapshotState, err error) { ctx, done := stepSpan(ctx, "CallAteletSuspend") defer func() { err = done(err) }() @@ -280,7 +280,7 @@ func (w *ActorWorkflow) ensureAteletSuspended(ctx context.Context, actorRef reso // newInProgressSnapshotURI is where the snapshot an actor is currently taking is // written: under the actor's own prefix, so the objects name their owner. -func (w *ActorWorkflow) newInProgressSnapshotURI(actorTemplate *ateapipb.ActorTemplate, actor *ateapipb.Actor, snapshotName string) (resources.SnapshotURI, error) { +func (w *ActorWorkflow) newInProgressSnapshotURI(actorTemplate *ateapi.ActorTemplate, actor *ateapi.Actor, snapshotName string) (resources.SnapshotURI, error) { location, err := w.snapshotLocation(actorTemplate) if err != nil { return resources.SnapshotURI{}, err @@ -298,7 +298,7 @@ func (w *ActorWorkflow) newInProgressSnapshotURI(actorTemplate *ateapipb.ActorTe // runs it again. spanName distinguishes the suspend and revert steps in // traces; op labels the volume metrics. // TODO replace re-execution with a proper check on the volumes' attach state. -func (w *ActorWorkflow) ensureVolumesDetached(ctx context.Context, actor *ateapipb.Actor, actorTemplate *ateapipb.ActorTemplate, spanName, op string) (err error) { +func (w *ActorWorkflow) ensureVolumesDetached(ctx context.Context, actor *ateapi.Actor, actorTemplate *ateapi.ActorTemplate, spanName, op string) (err error) { ctx, done := stepSpan(ctx, spanName) defer func() { err = done(err) }() @@ -324,7 +324,7 @@ func (w *ActorWorkflow) ensureVolumesDetached(ctx context.Context, actor *ateapi // FailedPrecondition. // ateletState is the state atelet returned from Checkpoint, applied in the // same update. A state that conflicts with the record crashes the actor. -func (w *ActorWorkflow) ensureSuspendedFinalized(ctx context.Context, actorRef resources.ActorRef, mode suspendMode, ateletState *ateletpb.ActorSnapshotState) (_ *ateapipb.Actor, err error) { +func (w *ActorWorkflow) ensureSuspendedFinalized(ctx context.Context, actorRef resources.ActorRef, mode suspendMode, ateletState *ateletpb.ActorSnapshotState) (_ *ateapi.Actor, err error) { ctx, done := stepSpan(ctx, "FinalizeSuspended") defer func() { err = done(err) }() @@ -350,8 +350,8 @@ func (w *ActorWorkflow) ensureSuspendedFinalized(ctx context.Context, actorRef r if err != nil { return nil, err } - if state := latestActor.GetStatus().GetState(); state != ateapipb.ActorState_ACTOR_STATE_SUSPENDING { - return nil, apierror.FailedPrecondition("FinalizeSuspended prerequisite not met for Actor: %s (got: %v, want %s)", actorRef, state, ateapipb.ActorState_ACTOR_STATE_SUSPENDING) + if state := latestActor.GetStatus().GetState(); state != ateapi.ActorState_ACTOR_STATE_SUSPENDING { + return nil, apierror.FailedPrecondition("FinalizeSuspended prerequisite not met for Actor: %s (got: %v, want %s)", actorRef, state, ateapi.ActorState_ACTOR_STATE_SUSPENDING) } if mode == suspendAsync { // A local snapshot on an unknown node can never be found by the scheduler. @@ -398,15 +398,15 @@ func (w *ActorWorkflow) ensureSuspendedFinalized(ctx context.Context, actorRef r // The precondition pins the version checked above, so an out-of-band write // since then fails the update instead of being overwritten. t = time.Now() - storedActor, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(latestActor), func(toUpdate *ateapipb.Actor) error { - toUpdate.Status.State = ateapipb.ActorState_ACTOR_STATE_SUSPENDED + storedActor, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(latestActor), func(toUpdate *ateapi.Actor) error { + toUpdate.Status.State = ateapi.ActorState_ACTOR_STATE_SUSPENDED // The precondition makes toUpdate the version applied was built from. toUpdate.Status.Snapshots = applied.GetSnapshots() snap := snapshotAtLatestGeneration(toUpdate.Status) if mode == suspendSync { - snap.GetDurableSnapshot().Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + snap.GetDurableSnapshot().Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED } - durable := snap.GetDurableSnapshot().GetStatus() == ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + durable := snap.GetDurableSnapshot().GetStatus() == ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED // Keep the actor on the node that holds its snapshot. atelet holds an // async suspend's snapshot until it detaches it, which it does only // once the snapshot is durable. @@ -438,7 +438,7 @@ func (w *ActorWorkflow) ensureSuspendedFinalized(ctx context.Context, actorRef r } // ateletKeptLocal reports whether atelet retained this checkpoint. -func ateletKeptLocal(state *ateletpb.ActorSnapshotState, snap *ateapipb.Snapshot) bool { +func ateletKeptLocal(state *ateletpb.ActorSnapshotState, snap *ateapi.Snapshot) bool { local := state.GetLatestLocal().GetSnapshot() uri := snap.GetDurableSnapshot().GetObject().GetSnapshotUri() return local != nil && uri != "" && @@ -452,8 +452,8 @@ func ateletKeptLocal(state *ateletpb.ActorSnapshotState, snap *ateapipb.Snapshot // snapshot's objects in storage until the actor is deleted, which removes its // whole prefix. An upload atelet reports can make a newer snapshot COMPLETED // outside any workflow, so the next one can drop more than one. -func (w *ActorWorkflow) releaseDroppedSnapshots(ctx context.Context, before, after *ateapipb.Actor) { - completed := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED +func (w *ActorWorkflow) releaseDroppedSnapshots(ctx context.Context, before, after *ateapi.Actor) { + completed := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED kept := map[string]bool{} for _, snap := range after.GetStatus().GetSnapshots() { kept[snap.GetDurableSnapshot().GetObject().GetSnapshotUri()] = true @@ -477,7 +477,7 @@ func (w *ActorWorkflow) releaseDroppedSnapshots(ctx context.Context, before, aft // it was before that workflow committed. // An actor that borrowed its current snapshot from a tag releases nothing — // the snapshot lives under the tag's prefix, and the tag outlives the actor. -func (w *ActorWorkflow) releaseReplacedSnapshot(ctx context.Context, actor *ateapipb.Actor, previous string) (err error) { +func (w *ActorWorkflow) releaseReplacedSnapshot(ctx context.Context, actor *ateapi.Actor, previous string) (err error) { ctx, done := stepSpan(ctx, "ReleaseReplacedSnapshot") defer func() { err = done(err) }() @@ -500,6 +500,6 @@ func (w *ActorWorkflow) releaseReplacedSnapshot(ctx context.Context, actor *atea return w.cleanupSnapshot(ctx, uri.Prefix()) } -func actorSnapshotOwner(actor *ateapipb.Actor) resources.SnapshotOwner { +func actorSnapshotOwner(actor *ateapi.Actor) resources.SnapshotOwner { return resources.ActorSnapshotOwner(actor.GetMetadata().GetAtespace(), actor.GetMetadata().GetUid()) } diff --git a/cmd/ateapi/internal/controlapi/workflow_suspend_async_test.go b/cmd/ateapi/internal/controlapi/workflow_suspend_async_test.go index 3ec08cf586..ca62090ba6 100644 --- a/cmd/ateapi/internal/controlapi/workflow_suspend_async_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_suspend_async_test.go @@ -19,13 +19,13 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/cmd/ateapi/internal/workercache" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/testing/protocmp" ) @@ -46,15 +46,15 @@ func TestSuspendActorAsync_Finalized_WorkerGone(t *testing.T) { actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} records := crashRecords(t) - storetest.MustCreateActor(t, ctx, st, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + storetest.MustCreateActor(t, ctx, st, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, WorkerAssignment: wireTestAssignment(), LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newInProgressSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "local-snap-1"), + Snapshots: []*ateapi.Snapshot{ + newInProgressSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "local-snap-1"), }, }, }) @@ -68,7 +68,7 @@ func TestSuspendActorAsync_Finalized_WorkerGone(t *testing.T) { } got := mustReadActor(t, ctx, st, actorRef) - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("state = %v, want CRASHED (node name unknown, cannot resume safely)", got.GetStatus().GetState()) } if msg, want := got.GetStatus().GetCrash().GetMessage(), "suspend failed: "+crashMessageLocalSnapshotNodeUnknown; msg != want { @@ -109,21 +109,21 @@ func TestSuspendActorAsync_Finalized_AlreadyCrashed(t *testing.T) { actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} records := crashRecords(t) - storetest.MustCreateActor(t, ctx, st, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + storetest.MustCreateActor(t, ctx, st, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, WorkerAssignment: wireTestAssignment(), LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newInProgressSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "local-snap-1"), + Snapshots: []*ateapi.Snapshot{ + newInProgressSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "local-snap-1"), }, }, }) originalCrash := newActorCrash(ateattr.OperationSuspend, "original crash reason") - updateDuringCheckpoint(t, atelet, st, actorRef, func(s *ateapipb.ActorStatus) { - s.State = ateapipb.ActorState_ACTOR_STATE_CRASHED + updateDuringCheckpoint(t, atelet, st, actorRef, func(s *ateapi.ActorStatus) { + s.State = ateapi.ActorState_ACTOR_STATE_CRASHED s.Crash = originalCrash s.WorkerAssignment = nil }) @@ -132,7 +132,7 @@ func TestSuspendActorAsync_Finalized_AlreadyCrashed(t *testing.T) { t.Fatalf("Async SuspendActor error = %v, want FailedPrecondition for a CRASHED actor", err) } got := mustReadActor(t, ctx, st, actorRef) - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("state = %v, want CRASHED", got.GetStatus().GetState()) } if msg, want := got.GetStatus().GetCrash().GetMessage(), originalCrash.GetMessage(); msg != want { @@ -159,11 +159,11 @@ func TestSuspendActorAsync_Finalized_KeepsCrashFromWorkerDelete(t *testing.T) { seedSuspendTemplate(t, ctx, st, nil) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - created := storetest.MustCreateActor(t, ctx, st, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + created := storetest.MustCreateActor(t, ctx, st, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, AssignedNode: "node-1", WorkerAssignment: wireTestAssignment(), }, @@ -181,44 +181,44 @@ func TestSuspendActorAsync_Finalized_KeepsCrashFromWorkerDelete(t *testing.T) { func TestSuspendActorAsync_Finalized_RecordsFidelity(t *testing.T) { tests := []struct { name string - preferred ateapipb.SnapshotFidelity - want ateapipb.SnapshotFidelity + preferred ateapi.SnapshotFidelity + want ateapi.SnapshotFidelity }{ - {"VOLUMES", ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES}, - {"ROOTFS", ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS}, - {"MEMORY", ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}, + {"VOLUMES", ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES}, + {"ROOTFS", ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS}, + {"MEMORY", ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}, // The store defaults an unset preferred_fidelity to MEMORY. - {"UNSPECIFIED defaults to MEMORY", ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}, + {"UNSPECIFIED defaults to MEMORY", ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() st := newTestPersistence(t) - seedSuspendTemplate(t, ctx, st, &ateapipb.SnapshotConfig{PreferredFidelity: tc.preferred}) + seedSuspendTemplate(t, ctx, st, &ateapi.SnapshotConfig{PreferredFidelity: tc.preferred}) w, _ := newWireCaptureWorkflow(t, st) // Without a watch running, finalization must notify the scheduler itself. w.workerCache = workercache.New(nil, 0) - var observed *ateapipb.Worker - w.workerCache.AddHandler(func(worker *ateapipb.Worker) { observed = worker }) + var observed *ateapi.Worker + w.workerCache.AddHandler(func(worker *ateapi.Worker) { observed = worker }) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - wantRuntime := &ateapipb.ActorSandboxRuntime{ + wantRuntime := &ateapi.ActorSandboxRuntime{ SandboxClass: "gvisor", - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{ + Attributes: []*ateapi.AttributeEntry{ {Key: "architecture", Value: "amd64"}, }, }, } assignment := wireTestAssignment() assignment.SandboxRuntime = wantRuntime - created := storetest.MustCreateActor(t, ctx, st, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + created := storetest.MustCreateActor(t, ctx, st, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, AssignedNode: "node-1", WorkerAssignment: assignment, }, @@ -230,7 +230,7 @@ func TestSuspendActorAsync_Finalized_RecordsFidelity(t *testing.T) { t.Fatalf("SuspendActor: %v", err) } - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("state = %v, want SUSPENDED", got.GetStatus().GetState()) } if !latestSnapshotIsLocal(got.GetStatus()) { @@ -240,7 +240,7 @@ func TestSuspendActorAsync_Finalized_RecordsFidelity(t *testing.T) { if localSnap.GetFidelity() != tc.want { t.Errorf("local Snapshot.Fidelity = %v, want %v", localSnap.GetFidelity(), tc.want) } - if got := localSnap.GetDurableSnapshot().GetStatus(); got != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING { + if got := localSnap.GetDurableSnapshot().GetStatus(); got != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING { t.Errorf("local DurableSnapshot.Status = %v, want PENDING", got) } if got := localSnap.GetDurableSnapshot().GetObject().GetSnapshotUri(); got == "" { @@ -284,17 +284,17 @@ func TestSuspendActorAsync_Finalized_MissingSnapshotClearsAssignment(t *testing. tests := []struct { name string // clobber rewrites the record while atelet checkpoints. - clobber func(s *ateapipb.ActorStatus) + clobber func(s *ateapi.ActorStatus) wantCrashMessage string }{ { name: "no snapshot at the latest generation", - clobber: func(s *ateapipb.ActorStatus) { s.Snapshots = nil }, + clobber: func(s *ateapi.ActorStatus) { s.Snapshots = nil }, wantCrashMessage: "suspend failed: " + crashMessageLocalSnapshotMissing, }, { name: "no durable copy of the latest snapshot", - clobber: func(s *ateapipb.ActorStatus) { + clobber: func(s *ateapi.ActorStatus) { for _, snap := range s.Snapshots { snap.DurableSnapshot = nil } @@ -311,16 +311,16 @@ func TestSuspendActorAsync_Finalized_MissingSnapshotClearsAssignment(t *testing. actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} records := crashRecords(t) - created := storetest.MustCreateActor(t, ctx, st, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + created := storetest.MustCreateActor(t, ctx, st, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, AssignedNode: "node-1", WorkerAssignment: wireTestAssignment(), LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newInProgressSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "local-snap-1"), + Snapshots: []*ateapi.Snapshot{ + newInProgressSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "local-snap-1"), }, }, }) @@ -331,7 +331,7 @@ func TestSuspendActorAsync_Finalized_MissingSnapshotClearsAssignment(t *testing. t.Fatalf("Async SuspendActor error = %v, want FailedPrecondition for the actor it crashed", err) } got := mustReadActor(t, ctx, st, actorRef) - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("state = %v, want CRASHED", got.GetStatus().GetState()) } if msg := got.GetStatus().GetCrash().GetMessage(); msg != tt.wantCrashMessage { @@ -371,18 +371,18 @@ func TestSuspendActorAsync_AteletPaused_DialFailureLeavesActorRetryable(t *testi persistence := newTestPersistence(t) seedSuspendTemplate(t, ctx, persistence, nil) - var snapshots []*ateapipb.Snapshot + var snapshots []*ateapi.Snapshot if tt.prevSnapshot != "" { - snapshots = append(snapshots, newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "prev-snapshot", tt.prevSnapshot, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)) + snapshots = append(snapshots, newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "prev-snapshot", tt.prevSnapshot, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)) } - snapshots = append(snapshots, newInProgressSnapshot(t, 2, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "actor-1-never-written")) + snapshots = append(snapshots, newInProgressSnapshot(t, 2, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "actor-1-never-written")) - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, - WorkerAssignment: &ateapipb.WorkerAssignment{ + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, + WorkerAssignment: &ateapi.WorkerAssignment{ WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "pod-gone", @@ -399,13 +399,13 @@ func TestSuspendActorAsync_AteletPaused_DialFailureLeavesActorRetryable(t *testi assertStoppedAtDial(t, err) stored := mustReadActor(t, ctx, persistence, resources.ActorRef{Atespace: "team-a", Name: "actor-1"}) - if stored.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDING { + if stored.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDING { t.Errorf("state = %v, want unchanged SUSPENDING", stored.GetStatus().GetState()) } if gotSnap := snapshotAtLatestGeneration(stored.GetStatus()); gotSnap.GetUuid() != "actor-1-never-written" { t.Errorf("in-progress local snapshot uuid = %q, want preserved for debugging", gotSnap.GetUuid()) } - gotSnap := findLatestDurableSnapshot(stored.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + gotSnap := findLatestDurableSnapshot(stored.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) if got := gotSnap.GetDurableSnapshot().GetObject().GetSnapshotUri(); got != tt.prevSnapshot { t.Errorf("SnapshotUri = %q, want %q", got, tt.prevSnapshot) } @@ -423,7 +423,7 @@ func TestSuspendActorAsync_CrashesWhenPausingActorMissingWorkerPod(t *testing.T) defer cleanup() w := newTestActorWorkflow(t, st, "ns", "tmpl1") - seedWorkflowActor(t, ctx, st, resources.ActorRef{Atespace: "team-a", Name: "id1"}, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_SUSPENDING, withPauseInProgress(t)) + seedWorkflowActor(t, ctx, st, resources.ActorRef{Atespace: "team-a", Name: "id1"}, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_SUSPENDING, withPauseInProgress(t)) _, err := w.SuspendActor(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, suspendAsync) if got := apierror.Code(err); got != codes.FailedPrecondition { @@ -434,8 +434,8 @@ func TestSuspendActorAsync_CrashesWhenPausingActorMissingWorkerPod(t *testing.T) if err != nil { t.Fatalf("GetActor failed: %v", err) } - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { - t.Errorf("stored state = %v, want %v", got.GetStatus().GetState(), ateapipb.ActorState_ACTOR_STATE_CRASHED) + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { + t.Errorf("stored state = %v, want %v", got.GetStatus().GetState(), ateapi.ActorState_ACTOR_STATE_CRASHED) } if msg, want := got.GetStatus().GetCrash().GetMessage(), "suspend failed: "+crashMessageWorkerAssignmentMissing; msg != want { t.Errorf("crash message = %q, want %q", msg, want) @@ -447,33 +447,33 @@ func TestSuspendActorAsync_CrashesWhenPausingActorMissingWorkerPod(t *testing.T) // label the suspend's lifecycle-op metric with it. func TestSuspendActorAsync_AteletPaused_ForwardsPreferredFidelity(t *testing.T) { tests := []struct { - preferred ateapipb.SnapshotFidelity + preferred ateapi.SnapshotFidelity want ateletpb.SnapshotFidelity }{ - {ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}, - {ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES}, + {ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}, + {ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES}, // The store defaults an unset preferred_fidelity to MEMORY. - {ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED, ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}, + {ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED, ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}, } for _, tc := range tests { t.Run(tc.preferred.String(), func(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{PreferredFidelity: tc.preferred}) + seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{PreferredFidelity: tc.preferred}) w, atelet := newWireCaptureWorkflow(t, persistence) inst, reader := newTestInstruments(t) w.instruments = inst actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, AssignedNode: "node-1", WorkerAssignment: wireTestAssignment(), LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ + Snapshots: []*ateapi.Snapshot{ newInProgressSnapshot(t, 1, tc.preferred, "local-snap-1"), }, }, diff --git a/cmd/ateapi/internal/controlapi/workflow_suspend_test.go b/cmd/ateapi/internal/controlapi/workflow_suspend_test.go index f31ae34279..7eb8474e4a 100644 --- a/cmd/ateapi/internal/controlapi/workflow_suspend_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_suspend_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/cmd/ateapi/internal/workercache" @@ -30,7 +31,6 @@ import ( "go.ate.dev/substrate/internal/installdefaults" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" @@ -45,25 +45,25 @@ func TestSuspendActor_CheckpointError(t *testing.T) { err error cancel bool wantCode codes.Code - wantState ateapipb.ActorState + wantState ateapi.ActorState }{ - {"snapshot conflict", apierror.Aborted("checkpoint rejected"), false, codes.Aborted, ateapipb.ActorState_ACTOR_STATE_SUSPENDING}, - {"failed precondition", apierror.FailedPrecondition("checkpoint rejected"), false, codes.Internal, ateapipb.ActorState_ACTOR_STATE_CRASHED}, - {"caller cancellation", apierror.Aborted("checkpoint rejected"), true, codes.Canceled, ateapipb.ActorState_ACTOR_STATE_SUSPENDING}, + {"snapshot conflict", apierror.Aborted("checkpoint rejected"), false, codes.Aborted, ateapi.ActorState_ACTOR_STATE_SUSPENDING}, + {"failed precondition", apierror.FailedPrecondition("checkpoint rejected"), false, codes.Internal, ateapi.ActorState_ACTOR_STATE_CRASHED}, + {"caller cancellation", apierror.Aborted("checkpoint rejected"), true, codes.Canceled, ateapi.ActorState_ACTOR_STATE_SUSPENDING}, } for _, tt := range tests { for _, mode := range suspendModes { t.Run(tt.name+"/"+mode.name, func(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{PreferredFidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}) + seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{PreferredFidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}) w, atelet := newWireCaptureWorkflow(t, persistence) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, AssignedNode: wireTestAssignment().GetNodeName(), WorkerAssignment: wireTestAssignment(), }, @@ -96,7 +96,7 @@ func TestSuspendActor_CheckpointError(t *testing.T) { if err != nil { t.Fatalf("GetWorker: %v", err) } - if tt.wantState == ateapipb.ActorState_ACTOR_STATE_CRASHED { + if tt.wantState == ateapi.ActorState_ACTOR_STATE_CRASHED { if st.GetCrash() == nil || st.GetWorkerAssignment() != nil || worker.GetStatus().GetAllocated().GetActors() != 0 { t.Errorf("checkpoint failure did not crash the actor and release its worker: actor %v, worker %v", st, worker.GetStatus()) } @@ -109,7 +109,7 @@ func TestSuspendActor_CheckpointError(t *testing.T) { t.Errorf("worker allocated actors = %d, want 1", got) } pending := snapshotAtLatestGeneration(st) - if pending.GetUuid() == "" || pending.GetDurableSnapshot().GetStatus() != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING { + if pending.GetUuid() == "" || pending.GetDurableSnapshot().GetStatus() != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING { t.Fatalf("snapshot = %v, want a persisted pending snapshot", pending) } first := atelet.checkpointRequest().GetSnapshot() @@ -129,7 +129,7 @@ func TestSuspendActor_CheckpointError(t *testing.T) { if diff := cmp.Diff(first, atelet.checkpointRequest().GetSnapshot(), protocmp.Transform()); diff != "" { t.Errorf("retry changed the snapshot (-first +retry):\n%s", diff) } - if finished.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED || finished.GetStatus().GetWorkerAssignment() != nil { + if finished.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED || finished.GetStatus().GetWorkerAssignment() != nil { t.Errorf("retry did not suspend the actor and clear its assignment: %v", finished.GetStatus()) } latest := snapshotAtLatestGeneration(finished.GetStatus()) @@ -144,12 +144,12 @@ func TestSuspendActor_CheckpointError(t *testing.T) { func TestSuspendActor_MarkedSuspending_SnapshotURI(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{StorageLocation: "gs://bucket/root/"}) - wantRuntime := &ateapipb.ActorSandboxRuntime{ + seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{StorageLocation: "gs://bucket/root/"}) + wantRuntime := &ateapi.ActorSandboxRuntime{ SandboxClass: "gvisor", - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{ + Attributes: []*ateapi.AttributeEntry{ {Key: "architecture", Value: "amd64"}, }, }, @@ -157,11 +157,11 @@ func TestSuspendActor_MarkedSuspending_SnapshotURI(t *testing.T) { assignment := wireTestAssignment() assignment.SandboxRuntime = wantRuntime actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: assignment, }, }) @@ -170,7 +170,7 @@ func TestSuspendActor_MarkedSuspending_SnapshotURI(t *testing.T) { assertStoppedAtDial(t, err) marked := mustReadActor(t, ctx, persistence, actorRef) - inProgressSnap := findLatestDurableSnapshot(marked.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) + inProgressSnap := findLatestDurableSnapshot(marked.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) uri := mustParseSnapshotURI(t, inProgressSnap.GetDurableSnapshot().GetObject().GetSnapshotUri()) if !resources.IsValidResourceName(uri.Name()) { t.Errorf("in-progress snapshot name = %q, want a valid resource name", uri.Name()) @@ -194,15 +194,15 @@ func TestSuspendActor_MarkedSuspending_SnapshotURI(t *testing.T) { // the same shape, so the retry's mode may differ from the first attempt's. func TestSuspendActor_MarkedSuspending_ReentryKeepsPersistedSnapshotLocation(t *testing.T) { const firstAttempt = "gs://bucket/root/atespaces/team-a/actors/actor-uid/snapshots/first-attempt" - pending := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING - completed := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + pending := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + completed := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED tests := []struct { name string mode suspendMode wantUploadMode ateletpb.UploadMode wantLocality string - wantDurable ateapipb.SnapshotStorageStatus + wantDurable ateapi.SnapshotStorageStatus wantNode string }{ {"sync", suspendSync, ateletpb.UploadMode_UPLOAD_MODE_IMMEDIATE, "", completed, ""}, @@ -212,19 +212,19 @@ func TestSuspendActor_MarkedSuspending_ReentryKeepsPersistedSnapshotLocation(t * t.Run(tt.name, func(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation}) + seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}) w, atelet := newWireCaptureWorkflow(t, persistence) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, AssignedNode: "node-1", WorkerAssignment: wireTestAssignment(), LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "first-attempt", firstAttempt, pending), + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "first-attempt", firstAttempt, pending), }, }, }) @@ -265,21 +265,21 @@ func TestSuspendActor_MarkedSuspending_ReentryKeepsPersistedSnapshotLocation(t * // locality, and assigned node included, is left exactly as seeded. func TestSuspendActorWorkflow_SuspendedReturnsAsIs(t *testing.T) { durableURI := someActorSnapshotURI(t, "gs://snapshots", "team-a", "durable-snap") - withDurable := func(a *ateapipb.Actor) { + withDurable := func(a *ateapi.Actor) { a.Status.LastAssignedGeneration = 1 - a.Status.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "durable-snap", durableURI, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + a.Status.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "durable-snap", durableURI, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), } } tests := []struct { name string - seedOpts []func(*ateapipb.Actor) + seedOpts []func(*ateapi.Actor) }{ {name: "newly created, no snapshot"}, - {name: "durable snapshot", seedOpts: []func(*ateapipb.Actor){withDurable}}, - {name: "paused, upload pending", seedOpts: []func(*ateapipb.Actor){withPausedShape(t, "node-1")}}, - {name: "paused, uploaded", seedOpts: []func(*ateapipb.Actor){withUploadedPausedShape(t, "node-1")}}, + {name: "durable snapshot", seedOpts: []func(*ateapi.Actor){withDurable}}, + {name: "paused, upload pending", seedOpts: []func(*ateapi.Actor){withPausedShape(t, "node-1")}}, + {name: "paused, uploaded", seedOpts: []func(*ateapi.Actor){withUploadedPausedShape(t, "node-1")}}, } for _, tc := range tests { for _, mode := range suspendModes { @@ -290,7 +290,7 @@ func TestSuspendActorWorkflow_SuspendedReturnsAsIs(t *testing.T) { w := newTestActorWorkflow(t, st, "ns", "tmpl1") actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_SUSPENDED, tc.seedOpts...) + seedWorkflowActor(t, ctx, st, actorRef, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_SUSPENDED, tc.seedOpts...) seeded := mustReadActor(t, ctx, st, actorRef) returned, err := w.SuspendActor(ctx, actorRef, mode.suspendMode) @@ -319,30 +319,30 @@ func TestSuspendActor_MarkedSuspending_StateMatrix(t *testing.T) { t.Run(mode.name, func(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{StorageLocation: "gs://snapshots"}) + seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{StorageLocation: "gs://snapshots"}) w := newMarkOnlyWorkflow(persistence) for _, seedState := range allActorStates { actorRef := resources.ActorRef{Atespace: "team-a", Name: fmt.Sprintf("id%d", seedState)} - seedWorkflowActor(t, ctx, persistence, actorRef, "ns", "tmpl1", seedState, func(a *ateapipb.Actor) { + seedWorkflowActor(t, ctx, persistence, actorRef, "ns", "tmpl1", seedState, func(a *ateapi.Actor) { a.Status.WorkerAssignment = wireTestAssignment() }) _, err := w.SuspendActor(ctx, actorRef, mode.suspendMode) stored := mustReadActor(t, ctx, persistence, actorRef) switch seedState { - case ateapipb.ActorState_ACTOR_STATE_RUNNING, ateapipb.ActorState_ACTOR_STATE_SUSPENDING: + case ateapi.ActorState_ACTOR_STATE_RUNNING, ateapi.ActorState_ACTOR_STATE_SUSPENDING: assertStoppedAtDial(t, err) - if got := stored.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDING { + if got := stored.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDING { t.Errorf("state %v: stored state = %v, want SUSPENDING", seedState, got) } - if seedState == ateapipb.ActorState_ACTOR_STATE_RUNNING { + if seedState == ateapi.ActorState_ACTOR_STATE_RUNNING { latest := snapshotAtLatestGeneration(stored.GetStatus()) - if latest.GetDurableSnapshot().GetStatus() != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING || latest.GetLocality() != "" { + if latest.GetDurableSnapshot().GetStatus() != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING || latest.GetLocality() != "" { t.Errorf("state %v: latest snapshot = %v, want a PENDING durable copy and no locality", seedState, latest) } } - case ateapipb.ActorState_ACTOR_STATE_SUSPENDED: + case ateapi.ActorState_ACTOR_STATE_SUSPENDED: if err != nil { t.Errorf("state %v: SuspendActor = %v, want it returned as it is", seedState, err) } @@ -372,7 +372,7 @@ func TestSuspendActor_CrashesWhenSuspendingActorMissingWorkerPod(t *testing.T) { defer cleanup() w := newTestActorWorkflow(t, st, "ns", "tmpl1") - seedWorkflowActor(t, ctx, st, resources.ActorRef{Atespace: "team-a", Name: "id1"}, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_SUSPENDING) + seedWorkflowActor(t, ctx, st, resources.ActorRef{Atespace: "team-a", Name: "id1"}, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_SUSPENDING) _, err := w.SuspendActor(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}, suspendSync) if got := apierror.Code(err); got != codes.FailedPrecondition { @@ -383,8 +383,8 @@ func TestSuspendActor_CrashesWhenSuspendingActorMissingWorkerPod(t *testing.T) { if err != nil { t.Fatalf("GetActor failed: %v", err) } - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { - t.Errorf("stored state = %v, want %v", got.GetStatus().GetState(), ateapipb.ActorState_ACTOR_STATE_CRASHED) + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { + t.Errorf("stored state = %v, want %v", got.GetStatus().GetState(), ateapi.ActorState_ACTOR_STATE_CRASHED) } if msg, want := got.GetStatus().GetCrash().GetMessage(), "suspend failed: "+crashMessageWorkerAssignmentMissing; msg != want { t.Errorf("crash message = %q, want %q", msg, want) @@ -428,19 +428,19 @@ func TestSuspendActor_AteletSuspended_DialFailureLeavesActorRetryable(t *testing t.Run(tt.name, func(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation}) - var snapshots []*ateapipb.Snapshot + seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}) + var snapshots []*ateapi.Snapshot if tt.prevSnapshot != "" { - snapshots = append(snapshots, newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "prev-snapshot", tt.prevSnapshot, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)) + snapshots = append(snapshots, newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "prev-snapshot", tt.prevSnapshot, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)) } - snapshots = append(snapshots, newDurableSnapshot(2, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "never-written", neverWritten, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING)) + snapshots = append(snapshots, newDurableSnapshot(2, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "never-written", neverWritten, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING)) - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, - WorkerAssignment: &ateapipb.WorkerAssignment{ + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, + WorkerAssignment: &ateapi.WorkerAssignment{ WorkerNamespace: "worker-ns", WorkerPool: "pool", WorkerPod: "pod-gone", @@ -463,13 +463,13 @@ func TestSuspendActor_AteletSuspended_DialFailureLeavesActorRetryable(t *testing if err != nil { t.Fatalf("GetActor: %v", err) } - if stored.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDING { + if stored.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDING { t.Errorf("state = %v, want unchanged SUSPENDING", stored.GetStatus().GetState()) } - if gotSnap := findLatestDurableSnapshot(stored.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING); gotSnap.GetDurableSnapshot().GetObject().GetSnapshotUri() != neverWritten { + if gotSnap := findLatestDurableSnapshot(stored.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING); gotSnap.GetDurableSnapshot().GetObject().GetSnapshotUri() != neverWritten { t.Errorf("in-progress durable snapshot URI = %q, want preserved for debugging", gotSnap.GetDurableSnapshot().GetObject().GetSnapshotUri()) } - gotSnap := findLatestDurableSnapshot(stored.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + gotSnap := findLatestDurableSnapshot(stored.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) if got := gotSnap.GetDurableSnapshot().GetObject().GetSnapshotUri(); got != tt.prevSnapshot { t.Errorf("SnapshotUri = %q, want %q", got, tt.prevSnapshot) } @@ -483,7 +483,7 @@ func TestSuspendActor_AteletSuspended_DialFailureLeavesActorRetryable(t *testing func TestSuspendActor_AteletSuspended_WireRequest(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{PreferredFidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}) + seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{PreferredFidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY}) w, atelet := newWireCaptureWorkflow(t, persistence) inst, reader := newTestInstruments(t) w.instruments = inst @@ -491,16 +491,16 @@ func TestSuspendActor_AteletSuspended_WireRequest(t *testing.T) { actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} snapshotName := "2026-01-01t00-00-00z-abc" snapshotURI := someActorSnapshotURI(t, testStorageLocation, "team-a", snapshotName) - storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, AssignedNode: "node-1", WorkerAssignment: wireTestAssignment(), LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-uid-1", snapshotName, snapshotURI, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "tmpl-uid-1", snapshotName, snapshotURI, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), }, }, }) @@ -565,31 +565,31 @@ func TestSuspendActor_Finalized_ReleasesReplacedSnapshot(t *testing.T) { w, _, objects := newWireFinalizeWorkflow(t, persistence) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, AssignedNode: "node-1", WorkerAssignment: wireTestAssignment(), }, }) previous := mustActorSnapshotURI(t, template, actor, "old") - prevType := ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR + prevType := ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR if tt.tagOwnedSnapshot { previous = mustTagSnapshotURI(t, template, "team-a", "v1-snapshot") - prevType = ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG + prevType = ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG } fresh := mustActorSnapshotURI(t, template, actor, snapshotName) objects.PutSnapshot(t, previous, "manifest.json") objects.PutSnapshot(t, fresh, "manifest.json") - mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 2 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, prevType, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", previous.Name(), previous.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), - newDurableSnapshot(2, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", fresh.Name(), fresh.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, prevType, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", previous.Name(), previous.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + newDurableSnapshot(2, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", fresh.Name(), fresh.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), } }) @@ -599,7 +599,7 @@ func TestSuspendActor_Finalized_ReleasesReplacedSnapshot(t *testing.T) { } // Whichever way the previous snapshot went, the actor now owns the // one it just wrote and is no longer borrowing. - gotSnap := findLatestDurableSnapshot(stored.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + gotSnap := findLatestDurableSnapshot(stored.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) if got := gotSnap.GetDurableSnapshot().GetObject().GetSnapshotUri(); got != fresh.String() { t.Errorf("external snapshot = %q, want the one this suspend wrote, %q", got, fresh) } @@ -620,9 +620,9 @@ func TestSuspendActor_Finalized_ReleasesReplacedSnapshot(t *testing.T) { // report. func TestSuspendActor_Finalized_PauseReleasesReplacedSnapshot(t *testing.T) { const node = "node-1" - memory := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY - completed := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED - pending := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + memory := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + completed := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + pending := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING for _, tc := range []struct { name string // reported records the upload before the suspend, as atelet's report @@ -639,11 +639,11 @@ func TestSuspendActor_Finalized_PauseReleasesReplacedSnapshot(t *testing.T) { w, atelet, objects := newWireFinalizeWorkflow(t, persistence) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, AssignedNode: node, WorkerAssignment: wireTestAssignment(), }, @@ -657,18 +657,18 @@ func TestSuspendActor_Finalized_PauseReleasesReplacedSnapshot(t *testing.T) { pausing := mustActorSnapshotURI(t, template, actor, "snap-3") objects.PutSnapshot(t, old, "manifest.json") objects.PutSnapshot(t, paused, "manifest.json") - mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { previousStatus := pending if tc.reported { previousStatus = completed } - previous := newDurableSnapshot(2, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", paused.Name(), paused.String(), previousStatus) + previous := newDurableSnapshot(2, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", paused.Name(), paused.String(), previousStatus) previous.Locality = node s.LastAssignedGeneration = 3 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", old.Name(), old.String(), completed), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", old.Name(), old.String(), completed), previous, - newDurableSnapshot(3, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", pausing.Name(), pausing.String(), pending), + newDurableSnapshot(3, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", pausing.Name(), pausing.String(), pending), } }) atelet.checkpointState = &ateletpb.ActorSnapshotState{LatestDurable: &ateletpb.SnapshotReport{Snapshot: &ateletpb.Snapshot{ @@ -714,10 +714,10 @@ func TestSnapshotLocationChange_LeavesNothingBehind(t *testing.T) { w, objects := newFinalizeWorkflow(persistence) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDING}, }) previous, err := resources.NewActorSnapshotURI(oldLocation, actorRef.Atespace, actor.GetMetadata().GetUid(), "old") if err != nil { @@ -729,11 +729,11 @@ func TestSnapshotLocationChange_LeavesNothingBehind(t *testing.T) { } objects.PutSnapshot(t, previous, "manifest.json") objects.PutSnapshot(t, fresh, "manifest.json") - mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 2 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", previous.Name(), previous.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), - newDurableSnapshot(2, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", fresh.Name(), fresh.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", previous.Name(), previous.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + newDurableSnapshot(2, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", fresh.Name(), fresh.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), } }) @@ -779,11 +779,11 @@ func TestSuspendActor_Finalized_CommitsDespiteObjectStoreFailure(t *testing.T) { const snapshotName = "2026-01-01t00-00-00z-new" actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, AssignedNode: "node-1", WorkerAssignment: wireTestAssignment(), }, @@ -794,11 +794,11 @@ func TestSuspendActor_Finalized_CommitsDespiteObjectStoreFailure(t *testing.T) { objects.PutSnapshot(t, previous, "manifest.json") objects.PutSnapshot(t, fresh, "manifest.json") - mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 2 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", previous.Name(), previous.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), - newDurableSnapshot(2, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", fresh.Name(), fresh.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", previous.Name(), previous.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + newDurableSnapshot(2, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", fresh.Name(), fresh.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), } }) @@ -807,14 +807,14 @@ func TestSuspendActor_Finalized_CommitsDespiteObjectStoreFailure(t *testing.T) { if err != nil { t.Fatalf("SuspendActor: %v", err) } - if got := stored.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := stored.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state = %v, want SUSPENDED", got) } - gotSnap := findLatestDurableSnapshot(stored.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + gotSnap := findLatestDurableSnapshot(stored.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) if got := gotSnap.GetDurableSnapshot().GetObject().GetSnapshotUri(); got != fresh.String() { t.Errorf("actor snapshot uri = %q, want the one this suspend wrote, %q", got, fresh) } - if got := findLatestDurableSnapshot(stored.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING); got != nil { + if got := findLatestDurableSnapshot(stored.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING); got != nil { t.Errorf("in-progress durable snapshot = %v, want cleared", got) } if len(objects.Snapshot(t, previous)) == 0 { @@ -838,11 +838,11 @@ func TestSuspendActor_Finalized_KeepsReplacedSnapshotOnConflict(t *testing.T) { w, atelet, objects := newWireFinalizeWorkflow(t, &conflictingUpdateStore{Interface: persistence}) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, AssignedNode: "node-1", WorkerAssignment: wireTestAssignment(), }, @@ -852,11 +852,11 @@ func TestSuspendActor_Finalized_KeepsReplacedSnapshotOnConflict(t *testing.T) { fresh := mustActorSnapshotURI(t, template, actor, "2026-01-01t00-00-00z-new") objects.PutSnapshot(t, previous, "manifest.json") objects.PutSnapshot(t, fresh, "manifest.json") - mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 2 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", previous.Name(), previous.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), - newDurableSnapshot(2, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", fresh.Name(), fresh.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", previous.Name(), previous.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + newDurableSnapshot(2, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", fresh.Name(), fresh.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), } }) @@ -879,7 +879,7 @@ type conflictingUpdateStore struct { store.Interface } -func (conflictingUpdateStore) UpdateActor(context.Context, resources.ActorRef, store.Precondition, func(*ateapipb.Actor) error) (*ateapipb.Actor, error) { +func (conflictingUpdateStore) UpdateActor(context.Context, resources.ActorRef, store.Precondition, func(*ateapi.Actor) error) (*ateapi.Actor, error) { return nil, store.ErrVersionConflict } @@ -890,19 +890,19 @@ func (conflictingUpdateStore) UpdateActor(context.Context, resources.ActorRef, s func TestSuspendActor_Finalized_KeepsCrashFromWorkerDelete(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation}) + seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - created := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + created := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, AssignedNode: "node-1", WorkerAssignment: wireTestAssignment(), LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "snapshot-1", someActorSnapshotURI(t, testStorageLocation, "team-a", "snapshot-1"), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "snapshot-1", someActorSnapshotURI(t, testStorageLocation, "team-a", "snapshot-1"), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), }, }, }) @@ -942,22 +942,22 @@ func TestSuspendActor_Finalized_ReleasesOnlyOwnWorker(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation}) + seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}) w, _ := newWireCaptureWorkflow(t, persistence) // Without a watch running, finalization must notify the scheduler itself. w.workerCache = workercache.New(nil, 0) - var observed *ateapipb.Worker - w.workerCache.AddHandler(func(worker *ateapipb.Worker) { observed = worker }) - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "shared"}, + var observed *ateapi.Worker + w.workerCache.AddHandler(func(worker *ateapi.Worker) { observed = worker }) + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "shared"}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, AssignedNode: "node-1", WorkerAssignment: wireTestAssignment(), LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "snapshot-1", someActorSnapshotURI(t, testStorageLocation, "team-a", "snapshot-1"), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "snapshot-1", someActorSnapshotURI(t, testStorageLocation, "team-a", "snapshot-1"), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), }, }, } @@ -967,8 +967,8 @@ func TestSuspendActor_Finalized_ReleasesOnlyOwnWorker(t *testing.T) { if tt.assignmentAtespace != "team-a" || tt.mismatchedUID { uid = "other-actor-uid-b" } - seedWireWorker(t, ctx, persistence, &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: tt.assignmentAtespace, Name: "shared"}, + seedWireWorker(t, ctx, persistence, &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: tt.assignmentAtespace, Name: "shared"}, ActorUid: uid, }) @@ -1008,26 +1008,26 @@ func TestSuspendActor_Finalized_ReleasesOnlyOwnWorker(t *testing.T) { func TestSuspendActor_Finalized_MissingDurableSnapshotClearsAssignment(t *testing.T) { ctx := context.Background() st := newTestPersistence(t) - seedSuspendTemplate(t, ctx, st, &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation}) + seedSuspendTemplate(t, ctx, st, &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}) w, atelet := newWireCaptureWorkflow(t, st) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} records := crashRecords(t) - created := storetest.MustCreateActor(t, ctx, st, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + created := storetest.MustCreateActor(t, ctx, st, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, AssignedNode: "node-1", WorkerAssignment: wireTestAssignment(), LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "snapshot-1", someActorSnapshotURI(t, testStorageLocation, "team-a", "snapshot-1"), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + Snapshots: []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "snapshot-1", someActorSnapshotURI(t, testStorageLocation, "team-a", "snapshot-1"), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), }, }, }) seedWireWorker(t, ctx, st, assignmentOf(created)) - updateDuringCheckpoint(t, atelet, st, actorRef, func(s *ateapipb.ActorStatus) { + updateDuringCheckpoint(t, atelet, st, actorRef, func(s *ateapi.ActorStatus) { s.Snapshots = nil }) @@ -1038,7 +1038,7 @@ func TestSuspendActor_Finalized_MissingDurableSnapshotClearsAssignment(t *testin if err != nil { t.Fatalf("GetActor: %v", err) } - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("state = %v, want CRASHED", got.GetStatus().GetState()) } if msg, want := got.GetStatus().GetCrash().GetMessage(), "suspend failed: "+crashMessageDurableSnapshotMissing; msg != want { @@ -1066,13 +1066,13 @@ var suspendModes = []struct { func TestSuspendModeFromOptions(t *testing.T) { tests := []struct { name string - opts *ateapipb.SuspendOptions + opts *ateapi.SuspendOptions want suspendMode }{ {"no options", nil, suspendAsync}, - {"mode unspecified", &ateapipb.SuspendOptions{}, suspendAsync}, - {"synchronous", &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, suspendSync}, - {"asynchronous", &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, suspendAsync}, + {"mode unspecified", &ateapi.SuspendOptions{}, suspendAsync}, + {"synchronous", &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, suspendSync}, + {"asynchronous", &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, suspendAsync}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1088,7 +1088,7 @@ func TestSuspendModeFromOptions(t *testing.T) { type suspendOutcome struct { code codes.Code atelet ateletCall - state ateapipb.ActorState + state ateapi.ActorState assignedNode string // workerHeld is whether the worker wireTestAssignment names still holds // the actor's assignment. @@ -1110,10 +1110,10 @@ type ateletCall struct { // snapshotOutcome is the part of a stored snapshot the matrix pins. type snapshotOutcome struct { generation int32 - fidelity ateapipb.SnapshotFidelity + fidelity ateapi.SnapshotFidelity locality string // durable is the durable copy's status, UNSPECIFIED when there is none. - durable ateapipb.SnapshotStorageStatus + durable ateapi.SnapshotStorageStatus } // TestSuspendAndPause_CharacteristicMatrix pins, for each actor shape either @@ -1122,16 +1122,16 @@ type snapshotOutcome struct { // actor's worker was released. func TestSuspendAndPause_CharacteristicMatrix(t *testing.T) { const node = "node-1" - volumes := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES - durable := func(gen int32, status ateapipb.SnapshotStorageStatus) *ateapipb.Snapshot { + volumes := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES + durable := func(gen int32, status ateapi.SnapshotStorageStatus) *ateapi.Snapshot { name := fmt.Sprintf("snap-%d", gen) - return newDurableSnapshot(gen, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, volumes, "", name, someActorSnapshotURI(t, testStorageLocation, "team-a", name), status) + return newDurableSnapshot(gen, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, volumes, "", name, someActorSnapshotURI(t, testStorageLocation, "team-a", name), status) } - local := func(gen int32, locality string) *ateapipb.Snapshot { + local := func(gen int32, locality string) *ateapi.Snapshot { return newPausedSnapshot(t, gen, volumes, "", fmt.Sprintf("snap-%d", gen), locality) } - completed := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED - pending := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + completed := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + pending := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING ateletVolumes := ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES immediate := ateletpb.UploadMode_UPLOAD_MODE_IMMEDIATE @@ -1143,79 +1143,79 @@ func TestSuspendAndPause_CharacteristicMatrix(t *testing.T) { want.code = codes.FailedPrecondition return want } - suspended := ateapipb.ActorState_ACTOR_STATE_SUSPENDED + suspended := ateapi.ActorState_ACTOR_STATE_SUSPENDED tests := []struct { name string // atespace defaults to team-a. atespace string - status *ateapipb.ActorStatus + status *ateapi.ActorStatus sync, async suspendOutcome }{ { name: "RUNNING", - status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING, AssignedNode: node, WorkerAssignment: wireTestAssignment()}, + status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING, AssignedNode: node, WorkerAssignment: wireTestAssignment()}, sync: suspendOutcome{code: codes.OK, atelet: checkpointSync, state: suspended, generation: 1, snapshots: []snapshotOutcome{{1, volumes, "", completed}}}, async: suspendOutcome{code: codes.OK, atelet: checkpointAsync, state: suspended, assignedNode: node, generation: 1, snapshots: []snapshotOutcome{{1, volumes, node, pending}}}, }, { name: "RUNNING resumed from pause", - status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, AssignedNode: node, WorkerAssignment: wireTestAssignment(), - LastAssignedGeneration: 1, Snapshots: []*ateapipb.Snapshot{local(1, node)}, + status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, AssignedNode: node, WorkerAssignment: wireTestAssignment(), + LastAssignedGeneration: 1, Snapshots: []*ateapi.Snapshot{local(1, node)}, }, sync: suspendOutcome{code: codes.OK, atelet: checkpointSync, state: suspended, generation: 2, snapshots: []snapshotOutcome{{2, volumes, "", completed}}}, async: suspendOutcome{code: codes.OK, atelet: checkpointAsync, state: suspended, assignedNode: node, generation: 2, snapshots: []snapshotOutcome{{2, volumes, node, pending}}}, }, { name: "RUNNING resumed from a durable snapshot", - status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, AssignedNode: node, WorkerAssignment: wireTestAssignment(), - LastAssignedGeneration: 1, Snapshots: []*ateapipb.Snapshot{durable(1, completed)}, + status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, AssignedNode: node, WorkerAssignment: wireTestAssignment(), + LastAssignedGeneration: 1, Snapshots: []*ateapi.Snapshot{durable(1, completed)}, }, sync: suspendOutcome{code: codes.OK, atelet: checkpointSync, state: suspended, generation: 2, snapshots: []snapshotOutcome{{2, volumes, "", completed}}}, async: suspendOutcome{code: codes.OK, atelet: checkpointAsync, state: suspended, assignedNode: node, generation: 2, snapshots: []snapshotOutcome{{1, volumes, "", completed}, {2, volumes, node, pending}}}, }, { name: "SUSPENDED with a durable snapshot", - status: &ateapipb.ActorStatus{State: suspended, LastAssignedGeneration: 1, Snapshots: []*ateapipb.Snapshot{durable(1, completed)}}, + status: &ateapi.ActorStatus{State: suspended, LastAssignedGeneration: 1, Snapshots: []*ateapi.Snapshot{durable(1, completed)}}, sync: suspendOutcome{code: codes.OK, state: suspended, generation: 1, snapshots: []snapshotOutcome{{1, volumes, "", completed}}}, async: suspendOutcome{code: codes.OK, state: suspended, generation: 1, snapshots: []snapshotOutcome{{1, volumes, "", completed}}}, }, { // Neither mode promotes the node-local snapshot. name: "paused", - status: &ateapipb.ActorStatus{State: suspended, AssignedNode: node, LastAssignedGeneration: 1, Snapshots: []*ateapipb.Snapshot{local(1, node)}}, + status: &ateapi.ActorStatus{State: suspended, AssignedNode: node, LastAssignedGeneration: 1, Snapshots: []*ateapi.Snapshot{local(1, node)}}, sync: suspendOutcome{code: codes.OK, state: suspended, assignedNode: node, generation: 1, snapshots: []snapshotOutcome{{1, volumes, node, pending}}}, async: suspendOutcome{code: codes.OK, state: suspended, assignedNode: node, generation: 1, snapshots: []snapshotOutcome{{1, volumes, node, pending}}}, }, { // Both modes mark this shape, and a retry finishes in its own mode. name: "suspend in progress", - status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, AssignedNode: node, WorkerAssignment: wireTestAssignment(), - LastAssignedGeneration: 1, Snapshots: []*ateapipb.Snapshot{durable(1, pending)}, + status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDING, AssignedNode: node, WorkerAssignment: wireTestAssignment(), + LastAssignedGeneration: 1, Snapshots: []*ateapi.Snapshot{durable(1, pending)}, }, sync: suspendOutcome{code: codes.OK, atelet: checkpointSync, state: suspended, generation: 1, snapshots: []snapshotOutcome{{1, volumes, "", completed}}}, async: suspendOutcome{code: codes.OK, atelet: checkpointAsync, state: suspended, assignedNode: node, generation: 1, snapshots: []snapshotOutcome{{1, volumes, node, pending}}}, }, { name: "RESUMING", - status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RESUMING}, - sync: rejected(suspendOutcome{state: ateapipb.ActorState_ACTOR_STATE_RESUMING}), - async: rejected(suspendOutcome{state: ateapipb.ActorState_ACTOR_STATE_RESUMING}), + status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RESUMING}, + sync: rejected(suspendOutcome{state: ateapi.ActorState_ACTOR_STATE_RESUMING}), + async: rejected(suspendOutcome{state: ateapi.ActorState_ACTOR_STATE_RESUMING}), }, { name: "CRASHED", - status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_CRASHED}, - sync: rejected(suspendOutcome{state: ateapipb.ActorState_ACTOR_STATE_CRASHED}), - async: rejected(suspendOutcome{state: ateapipb.ActorState_ACTOR_STATE_CRASHED}), + status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_CRASHED}, + sync: rejected(suspendOutcome{state: ateapi.ActorState_ACTOR_STATE_CRASHED}), + async: rejected(suspendOutcome{state: ateapi.ActorState_ACTOR_STATE_CRASHED}), }, { name: "DELETING", - status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_DELETING}, - sync: rejected(suspendOutcome{state: ateapipb.ActorState_ACTOR_STATE_DELETING}), - async: rejected(suspendOutcome{state: ateapipb.ActorState_ACTOR_STATE_DELETING}), + status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_DELETING}, + sync: rejected(suspendOutcome{state: ateapi.ActorState_ACTOR_STATE_DELETING}), + async: rejected(suspendOutcome{state: ateapi.ActorState_ACTOR_STATE_DELETING}), }, } @@ -1235,14 +1235,14 @@ func TestSuspendAndPause_CharacteristicMatrix(t *testing.T) { // wireTestAssignment names. ctx := context.Background() persistence := newTestPersistence(t) - tmpl := seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation, PreferredFidelity: volumes}) + tmpl := seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{StorageLocation: testStorageLocation, PreferredFidelity: volumes}) actorRef := resources.ActorRef{Atespace: atespace, Name: fmt.Sprintf("row%d-%s", i, mode.name)} - created := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + created := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), Status: proto.CloneOf(tc.status), }) - var assignment *ateapipb.ActorAssignment + var assignment *ateapi.ActorAssignment if tc.status.GetWorkerAssignment() != nil { assignment = assignmentOf(created) } @@ -1263,7 +1263,7 @@ func TestSuspendAndPause_CharacteristicMatrix(t *testing.T) { if diff := cmp.Diff(want, got, cmp.AllowUnexported(suspendOutcome{}, ateletCall{}, snapshotOutcome{})); diff != "" { t.Errorf("outcome mismatch (-want +got):\n%s (err: %v)", diff, err) } - if got.state == ateapipb.ActorState_ACTOR_STATE_SUSPENDED && stored.GetStatus().GetWorkerAssignment() != nil { + if got.state == ateapi.ActorState_ACTOR_STATE_SUSPENDED && stored.GetStatus().GetWorkerAssignment() != nil { t.Errorf("WorkerAssignment = %v, want cleared on SUSPENDED", stored.GetStatus().GetWorkerAssignment()) } assertRequestNamesLatestSnapshot(t, atelet, tmpl, stored) @@ -1281,14 +1281,14 @@ func TestSuspendAndPause_FinalizeWithoutAssignment(t *testing.T) { t.Run(mode.name, func(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation}) + seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}) w, atelet := newWireCaptureWorkflow(t, persistence) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, AssignedNode: "node-1", WorkerAssignment: wireTestAssignment(), }, @@ -1297,8 +1297,8 @@ func TestSuspendAndPause_FinalizeWithoutAssignment(t *testing.T) { // crash recorded and the assignment cleared, landing after the // atelet call and before finalize re-reads the actor. originalCrash := newActorCrash(ateattr.OperationDelete, "original crash reason") - updateDuringCheckpoint(t, atelet, persistence, actorRef, func(s *ateapipb.ActorStatus) { - s.State = ateapipb.ActorState_ACTOR_STATE_CRASHED + updateDuringCheckpoint(t, atelet, persistence, actorRef, func(s *ateapi.ActorStatus) { + s.State = ateapi.ActorState_ACTOR_STATE_CRASHED s.Crash = originalCrash s.WorkerAssignment = nil }) @@ -1311,7 +1311,7 @@ func TestSuspendAndPause_FinalizeWithoutAssignment(t *testing.T) { t.Errorf("%s: returned actor = %v, want nil", mode.name, returned) } stored := mustReadActor(t, ctx, persistence, actorRef) - if got := stored.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got := stored.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("%s: stored state = %v, want CRASHED", mode.name, got) } if got, want := stored.GetStatus().GetCrash().GetMessage(), originalCrash.GetMessage(); got != want { @@ -1329,14 +1329,14 @@ func TestSuspendAndPause_InvalidStorageLocationRejected(t *testing.T) { t.Run(mode.name, func(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{StorageLocation: "not-a-uri"}) + seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{StorageLocation: "not-a-uri"}) w := newMarkOnlyWorkflow(persistence) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, AssignedNode: "node-1", WorkerAssignment: wireTestAssignment(), }, @@ -1346,7 +1346,7 @@ func TestSuspendAndPause_InvalidStorageLocationRejected(t *testing.T) { t.Fatalf("%s: expected error for invalid storage location, got nil", mode.name) } stored := mustReadActor(t, ctx, persistence, actorRef) - if got := stored.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := stored.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("%s: stored state = %v, want RUNNING untouched", mode.name, got) } if got := stored.GetStatus().GetLastAssignedGeneration(); got != 0 { @@ -1378,7 +1378,7 @@ func describeAteletCall(atelet *capturingAtelet) ateletCall { // describeSnapshots summarizes each stored snapshot as its generation, // fidelity, locality, and durable copy's status. -func describeSnapshots(status *ateapipb.ActorStatus) []snapshotOutcome { +func describeSnapshots(status *ateapi.ActorStatus) []snapshotOutcome { var out []snapshotOutcome for _, snap := range status.GetSnapshots() { out = append(out, snapshotOutcome{ @@ -1394,7 +1394,7 @@ func describeSnapshots(status *ateapipb.ActorStatus) []snapshotOutcome { // assertRequestNamesLatestSnapshot verifies the suspend RPC atelet received, // if any, names the snapshot at the stored actor's latest generation and its // object storage URI. -func assertRequestNamesLatestSnapshot(t *testing.T, atelet *capturingAtelet, tmpl *ateapipb.ActorTemplate, stored *ateapipb.Actor) { +func assertRequestNamesLatestSnapshot(t *testing.T, atelet *capturingAtelet, tmpl *ateapi.ActorTemplate, stored *ateapi.Actor) { t.Helper() var snap *ateletpb.Snapshot if req := atelet.checkpointRequest(); req != nil { @@ -1422,12 +1422,12 @@ func assertRequestNamesLatestSnapshot(t *testing.T, atelet *capturingAtelet, tmp // that conflicts with the record crashes the actor. func TestSuspendActor_AppliesCheckpointState(t *testing.T) { const node = "node-1" - memory := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY - pending := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING - completed := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED - durable := func(gen int32, status ateapipb.SnapshotStorageStatus) *ateapipb.Snapshot { + memory := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + pending := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + completed := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + durable := func(gen int32, status ateapi.SnapshotStorageStatus) *ateapi.Snapshot { name := fmt.Sprintf("snap-%d", gen) - return newDurableSnapshot(gen, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", name, someActorSnapshotURI(t, testStorageLocation, "team-a", name), status) + return newDurableSnapshot(gen, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, memory, "", name, someActorSnapshotURI(t, testStorageLocation, "team-a", name), status) } report := func(gen int32, uri string, fidelity ateletpb.SnapshotFidelity) *ateletpb.SnapshotReport { return &ateletpb.SnapshotReport{Snapshot: &ateletpb.Snapshot{ @@ -1445,7 +1445,7 @@ func TestSuspendActor_AppliesCheckpointState(t *testing.T) { name string mode suspendMode // status is the RUNNING actor's status before the suspend. - status *ateapipb.ActorStatus + status *ateapi.ActorStatus // state builds what Checkpoint returns, from the request it got. state func(req *ateletpb.CheckpointRequest) *ateletpb.ActorSnapshotState wantSnapshots []snapshotOutcome @@ -1460,7 +1460,7 @@ func TestSuspendActor_AppliesCheckpointState(t *testing.T) { // again. The case pins that finalize applies the state before it prunes. name: "async: an older upload atelet finished is kept as COMPLETED", mode: suspendAsync, - status: &ateapipb.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapipb.Snapshot{durable(1, pending)}}, + status: &ateapi.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapi.Snapshot{durable(1, pending)}}, state: func(req *ateletpb.CheckpointRequest) *ateletpb.ActorSnapshotState { return &ateletpb.ActorSnapshotState{ LatestLocal: &ateletpb.SnapshotReport{Snapshot: req.GetSnapshot()}, @@ -1474,7 +1474,7 @@ func TestSuspendActor_AppliesCheckpointState(t *testing.T) { // in the background, and the next async suspend records that. name: "async: the previous pause's upload atelet finished is recorded as COMPLETED", mode: suspendAsync, - status: &ateapipb.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapipb.Snapshot{newPausedSnapshot(t, 1, memory, "", "snap-1", node)}}, + status: &ateapi.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapi.Snapshot{newPausedSnapshot(t, 1, memory, "", "snap-1", node)}}, state: func(req *ateletpb.CheckpointRequest) *ateletpb.ActorSnapshotState { return &ateletpb.ActorSnapshotState{ LatestLocal: &ateletpb.SnapshotReport{Snapshot: req.GetSnapshot()}, @@ -1485,7 +1485,7 @@ func TestSuspendActor_AppliesCheckpointState(t *testing.T) { }, { name: "async: without a state, the PENDING upload is pruned", mode: suspendAsync, - status: &ateapipb.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapipb.Snapshot{durable(1, pending)}}, + status: &ateapi.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapi.Snapshot{durable(1, pending)}}, state: func(*ateletpb.CheckpointRequest) *ateletpb.ActorSnapshotState { return nil }, @@ -1498,7 +1498,7 @@ func TestSuspendActor_AppliesCheckpointState(t *testing.T) { // on any node. name: "async: a snapshot atelet already detached is recorded without locality", mode: suspendAsync, - status: &ateapipb.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapipb.Snapshot{durable(1, completed)}}, + status: &ateapi.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapi.Snapshot{durable(1, completed)}}, state: func(req *ateletpb.CheckpointRequest) *ateletpb.ActorSnapshotState { return &ateletpb.ActorSnapshotState{ LatestDurable: &ateletpb.SnapshotReport{Snapshot: req.GetSnapshot()}, @@ -1511,7 +1511,7 @@ func TestSuspendActor_AppliesCheckpointState(t *testing.T) { // the retry is async. An older snapshot's upload is still running. name: "async: a durable snapshot atelet kept no copy of is recorded without locality", mode: suspendAsync, - status: &ateapipb.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapipb.Snapshot{durable(1, pending)}}, + status: &ateapi.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapi.Snapshot{durable(1, pending)}}, state: func(req *ateletpb.CheckpointRequest) *ateletpb.ActorSnapshotState { return &ateletpb.ActorSnapshotState{ Uploading: report(1, uriOf(1), ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY), @@ -1528,7 +1528,7 @@ func TestSuspendActor_AppliesCheckpointState(t *testing.T) { snap.Fidelity = ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS return &ateletpb.ActorSnapshotState{LatestDurable: &ateletpb.SnapshotReport{Snapshot: snap}} }, - wantSnapshots: []snapshotOutcome{{generation: 1, fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, durable: completed}}, + wantSnapshots: []snapshotOutcome{{generation: 1, fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, durable: completed}}, }, { name: "sync: a state that conflicts with the record crashes the actor", mode: suspendSync, @@ -1542,7 +1542,7 @@ func TestSuspendActor_AppliesCheckpointState(t *testing.T) { }, { name: "async: a state that conflicts with the record crashes the actor", mode: suspendAsync, - status: &ateapipb.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapipb.Snapshot{durable(1, pending)}}, + status: &ateapi.ActorStatus{LastAssignedGeneration: 1, Snapshots: []*ateapi.Snapshot{durable(1, pending)}}, state: func(req *ateletpb.CheckpointRequest) *ateletpb.ActorSnapshotState { return &ateletpb.ActorSnapshotState{ LatestLocal: &ateletpb.SnapshotReport{Snapshot: req.GetSnapshot()}, @@ -1555,17 +1555,17 @@ func TestSuspendActor_AppliesCheckpointState(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation, PreferredFidelity: memory}) + seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{StorageLocation: testStorageLocation, PreferredFidelity: memory}) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} status := proto.CloneOf(tt.status) if status == nil { - status = &ateapipb.ActorStatus{} + status = &ateapi.ActorStatus{} } - status.State = ateapipb.ActorState_ACTOR_STATE_RUNNING + status.State = ateapi.ActorState_ACTOR_STATE_RUNNING status.AssignedNode = node status.WorkerAssignment = wireTestAssignment() - created := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + created := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), Status: status, }) @@ -1585,7 +1585,7 @@ func TestSuspendActor_AppliesCheckpointState(t *testing.T) { if got := apierror.Code(err); got != tt.wantCode { t.Fatalf("suspend = %v, want code %v", err, tt.wantCode) } - if got := stored.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got := stored.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("state = %v, want CRASHED", got) } if got, want := stored.GetStatus().GetCrash().GetMessage(), "suspend failed: "+crashMessageSnapshotStateConflict; got != want { @@ -1596,7 +1596,7 @@ func TestSuspendActor_AppliesCheckpointState(t *testing.T) { if err != nil { t.Fatalf("suspend: %v", err) } - if got := stored.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := stored.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state = %v, want SUSPENDED", got) } wantNode := node @@ -1615,8 +1615,8 @@ func TestSuspendActor_AppliesCheckpointState(t *testing.T) { func TestSuspendActor_Finalized_RecordsLocalCopyWhenKept(t *testing.T) { const node = "node-1" - memory := ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY - completed := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + memory := ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + completed := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED localReport := func(snap *ateletpb.Snapshot) *ateletpb.ActorSnapshotState { return &ateletpb.ActorSnapshotState{LatestLocal: &ateletpb.SnapshotReport{Snapshot: snap}} } @@ -1662,13 +1662,13 @@ func TestSuspendActor_Finalized_RecordsLocalCopyWhenKept(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - seedSuspendTemplate(t, ctx, persistence, &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation, PreferredFidelity: memory}) + seedSuspendTemplate(t, ctx, persistence, &ateapi.SnapshotConfig{StorageLocation: testStorageLocation, PreferredFidelity: memory}) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - created := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + created := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: suspendTestTemplateRef(), - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, AssignedNode: node, WorkerAssignment: wireTestAssignment(), }, @@ -1687,7 +1687,7 @@ func TestSuspendActor_Finalized_RecordsLocalCopyWhenKept(t *testing.T) { t.Fatalf("suspend: %v", err) } stored := mustReadActor(t, ctx, persistence, actorRef) - if got := stored.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := stored.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state = %v, want SUSPENDED", got) } if got := stored.GetStatus().GetAssignedNode(); got != tt.wantLocality { diff --git a/cmd/ateapi/internal/controlapi/workflow_tag.go b/cmd/ateapi/internal/controlapi/workflow_tag.go index 012092ae06..25e50e2c8e 100644 --- a/cmd/ateapi/internal/controlapi/workflow_tag.go +++ b/cmd/ateapi/internal/controlapi/workflow_tag.go @@ -19,12 +19,12 @@ import ( "errors" "fmt" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" @@ -53,7 +53,7 @@ import ( // dies after it leaves a pending tag and every later create under that name is // AlreadyExists. To retry, delete the tag, which collects whatever the failed // attempt stranded, and create it again. -func (w *ActorWorkflow) TagActorSnapshot(ctx context.Context, tag *ateapipb.Tag) (*ateapipb.Tag, error) { +func (w *ActorWorkflow) TagActorSnapshot(ctx context.Context, tag *ateapi.Tag) (*ateapi.Tag, error) { ctx = preview.ContextWithOptIn(ctx) actorRef := resources.ActorRefFromObjectRef(tag.GetSourceActor()) @@ -126,7 +126,7 @@ func (w *ActorWorkflow) TagActorSnapshot(ctx context.Context, tag *ateapipb.Tag) // Note that this destroys the external snapshot: an Actor created from the tag // and never suspended is still borrowing it and becomes unrecoverable. Do not // delete a tag while clones of it exist. -func (w *ActorWorkflow) DeleteTag(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions) (*ateapipb.Tag, error) { +func (w *ActorWorkflow) DeleteTag(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions) (*ateapi.Tag, error) { ctx = preview.ContextWithOptIn(ctx) // Serializes against a create of the same tag, whose copy would otherwise // keep writing into the prefix this is collecting. @@ -149,12 +149,12 @@ func (w *ActorWorkflow) DeleteTag(ctx context.Context, tagRef resources.TagRef, // ensureTagMarkedForDeletion sets the tag's delete_time, checking precondition, // and returns the stored copy. Skips when a previous attempt already marked the // tag. -func (w *ActorWorkflow) ensureTagMarkedForDeletion(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions) (_ *ateapipb.Tag, err error) { +func (w *ActorWorkflow) ensureTagMarkedForDeletion(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions) (_ *ateapi.Tag, err error) { ctx, done := stepSpan(ctx, "MarkTagForDeletion") defer func() { err = done(err) }() - var alreadyDeleting *ateapipb.Tag - marked, err := w.store.MarkTagForDeletion(ctx, tagRef, precondition, func(toUpdate *ateapipb.Tag) error { + var alreadyDeleting *ateapi.Tag + marked, err := w.store.MarkTagForDeletion(ctx, tagRef, precondition, func(toUpdate *ateapi.Tag) error { if toUpdate.GetMetadata().GetDeleteTime() != nil { alreadyDeleting = toUpdate return errAlreadyMarked @@ -185,7 +185,7 @@ func (w *ActorWorkflow) ensureTagMarkedForDeletion(ctx context.Context, tagRef r // cleanly. It collects the in-progress snapshot of a pending tag too, and // skips a tag whose create died before recording its snapshot: nothing is // copied until the URI is recorded, so such a tag stranded nothing. -func (w *ActorWorkflow) ensureTagSnapshotReleased(ctx context.Context, tag *ateapipb.Tag) (err error) { +func (w *ActorWorkflow) ensureTagSnapshotReleased(ctx context.Context, tag *ateapi.Tag) (err error) { ctx, done := stepSpan(ctx, "ReleaseTagSnapshot") defer func() { err = done(err) }() @@ -194,7 +194,7 @@ func (w *ActorWorkflow) ensureTagSnapshotReleased(ctx context.Context, tag *atea return nil } tagRef := resources.TagRefFromTag(tag) - snapshotURI := tagDurableSnapshotURI(tag, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_UNSPECIFIED) + snapshotURI := tagDurableSnapshotURI(tag, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_UNSPECIFIED) if snapshotURI == "" { markSkipped(ctx, "the tag records no snapshot") return nil @@ -210,7 +210,7 @@ func (w *ActorWorkflow) ensureTagSnapshotReleased(ctx context.Context, tag *atea } // finalizeTagDeleted drops the row, once nothing it names is left behind. -func (w *ActorWorkflow) finalizeTagDeleted(ctx context.Context, tag *ateapipb.Tag) (_ *ateapipb.Tag, err error) { +func (w *ActorWorkflow) finalizeTagDeleted(ctx context.Context, tag *ateapi.Tag) (_ *ateapi.Tag, err error) { ctx, done := stepSpan(ctx, "FinalizeTagDeleted") defer func() { err = done(err) }() @@ -234,7 +234,7 @@ func (w *ActorWorkflow) finalizeTagDeleted(ctx context.Context, tag *ateapipb.Ta // loadActorForTag fetches the actor to tag and its template, and checks that // the actor is suspended. -func (w *ActorWorkflow) loadActorForTag(ctx context.Context, actorRef resources.ActorRef) (_ *ateapipb.Actor, _ *ateapipb.ActorTemplate, err error) { +func (w *ActorWorkflow) loadActorForTag(ctx context.Context, actorRef resources.ActorRef) (_ *ateapi.Actor, _ *ateapi.ActorTemplate, err error) { ctx, done := stepSpan(ctx, "LoadActorForTag") defer func() { err = done(err) }() @@ -244,8 +244,8 @@ func (w *ActorWorkflow) loadActorForTag(ctx context.Context, actorRef resources. } // Only a suspended actor's snapshot is complete. A running or // suspending actor's is either stale or still being written. - if got := actor.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { - return nil, nil, apierror.FailedPrecondition("Actor %s must be %s to be tagged (got: %v)", actorRef, ateapipb.ActorState_ACTOR_STATE_SUSPENDED, got) + if got := actor.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { + return nil, nil, apierror.FailedPrecondition("Actor %s must be %s to be tagged (got: %v)", actorRef, ateapi.ActorState_ACTOR_STATE_SUSPENDED, got) } actorTemplate, err := resolveActorTemplate(ctx, w.store, actor) if err != nil { @@ -258,7 +258,7 @@ func (w *ActorWorkflow) loadActorForTag(ctx context.Context, actorRef resources. // uploaded: a name already taken, or a storage location the copy cannot use. // The tag lease is held, so no other create or delete of the name races the // lookup. -func (w *ActorWorkflow) checkTagCreatable(ctx context.Context, tagRef resources.TagRef, actorTemplate *ateapipb.ActorTemplate) (err error) { +func (w *ActorWorkflow) checkTagCreatable(ctx context.Context, tagRef resources.TagRef, actorTemplate *ateapi.ActorTemplate) (err error) { ctx, done := stepSpan(ctx, "CheckTagCreatable") defer func() { err = done(err) }() @@ -288,12 +288,12 @@ func (w *ActorWorkflow) checkTagCreatable(ctx context.Context, tagRef resources. // // A failed upload does not crash the actor: the tag fails and the actor is // left as it was. -func (w *ActorWorkflow) ensureTagSourceSnapshotDurable(ctx context.Context, actorRef resources.ActorRef, actor *ateapipb.Actor) (_ *ateapipb.Actor, err error) { +func (w *ActorWorkflow) ensureTagSourceSnapshotDurable(ctx context.Context, actorRef resources.ActorRef, actor *ateapi.Actor) (_ *ateapi.Actor, err error) { ctx, done := stepSpan(ctx, "PromoteTagSourceSnapshot") defer func() { err = done(err) }() - snap := latestSnapshot(actor.GetStatus(), func(*ateapipb.Snapshot) bool { return true }) - if snap.GetDurableSnapshot().GetStatus() == ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { + snap := latestSnapshot(actor.GetStatus(), func(*ateapi.Snapshot) bool { return true }) + if snap.GetDurableSnapshot().GetStatus() == ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { markSkipped(ctx, "the actor's latest snapshot is already durable") return actor, nil } @@ -351,7 +351,7 @@ func (w *ActorWorkflow) ensureTagSourceSnapshotDurable(ctx context.Context, acto if err := applyAteletResponseState(ctx, applied, resp.GetState()); err != nil { return nil, apierror.Internal("atelet on node %q reported a state for Actor %s that conflicts with its record: %w", snap.GetLocality(), actorRef, err) } - stored, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapipb.Actor) error { + stored, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapi.Actor) error { // The precondition makes toUpdate the version applied was built from. toUpdate.Status.Snapshots = applied.GetSnapshots() return nil @@ -386,8 +386,8 @@ func promoteSnapshotError(ctx context.Context, err error) error { // sourceSnapshotForTag returns the actor's latest COMPLETED external snapshot, // the one a tag copies. -func sourceSnapshotForTag(actorRef resources.ActorRef, actor *ateapipb.Actor) (*ateapipb.Snapshot, error) { - snap := findLatestDurableSnapshot(actor.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) +func sourceSnapshotForTag(actorRef resources.ActorRef, actor *ateapi.Actor) (*ateapi.Snapshot, error) { + snap := findLatestDurableSnapshot(actor.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) if snap == nil { return nil, apierror.FailedPrecondition("Actor %s holds no external snapshot to tag", actorRef) } @@ -411,15 +411,15 @@ func sourceSnapshotForTag(actorRef resources.ActorRef, actor *ateapipb.Actor) (* // deciding whether the objects under it still belong to the snapshot being // tagged, and the row may not even be this actor's; deleting the tag collects // them and frees the name, so a retry is a delete followed by a create. -func (w *ActorWorkflow) ensureTagReserved(ctx context.Context, tagRef resources.TagRef, actor *ateapipb.Actor, snapshot *ateapipb.Snapshot, tag *ateapipb.Tag) (_ *ateapipb.Tag, err error) { +func (w *ActorWorkflow) ensureTagReserved(ctx context.Context, tagRef resources.TagRef, actor *ateapi.Actor, snapshot *ateapi.Snapshot, tag *ateapi.Tag) (_ *ateapi.Tag, err error) { ctx, done := stepSpan(ctx, "ReserveTag") defer func() { err = done(err) }() - tagToCreate := &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: tagRef.Atespace, Name: tagRef.Name}, + tagToCreate := &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: tagRef.Atespace, Name: tagRef.Name}, Scope: tag.GetScope(), SourceActor: resources.ActorRefFromActor(actor).ToObjectRef(), - Status: &ateapipb.TagStatus{ + Status: &ateapi.TagStatus{ // The tag records the template the snapshot's guest state was built under, not // the one the actor currently points at. A suspended actor can be repointed, // and a tag that claimed the new template would hand clones the old template's @@ -445,7 +445,7 @@ func (w *ActorWorkflow) ensureTagReserved(ctx context.Context, tagRef resources. // a copy of snapshot under the tag's own prefix, keyed on the UID the store // assigned when the tag was reserved. It lands before anything is copied, so a // tag whose create fails later still names the objects it stranded. -func (w *ActorWorkflow) ensureTagSnapshotRecorded(ctx context.Context, tag *ateapipb.Tag, actorTemplate *ateapipb.ActorTemplate, snapshot *ateapipb.Snapshot) (_ *ateapipb.Tag, _ resources.SnapshotURI, err error) { +func (w *ActorWorkflow) ensureTagSnapshotRecorded(ctx context.Context, tag *ateapi.Tag, actorTemplate *ateapi.ActorTemplate, snapshot *ateapi.Snapshot) (_ *ateapi.Tag, _ resources.SnapshotURI, err error) { ctx, done := stepSpan(ctx, "RecordTagSnapshot") defer func() { err = done(err) }() @@ -460,15 +460,15 @@ func (w *ActorWorkflow) ensureTagSnapshotRecorded(ctx context.Context, tag *atea } pending := newDurableSnapshot( 1, - ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, + ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, snapshot.GetFidelity(), "", dst.Name(), dst.String(), - ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING, + ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING, ) pending.SandboxRuntime = proto.CloneOf(snapshot.GetSandboxRuntime()) - stored, err := w.store.UpdateTag(ctx, tagRef, store.PreconditionFrom(tag), func(toUpdate *ateapipb.Tag) error { + stored, err := w.store.UpdateTag(ctx, tagRef, store.PreconditionFrom(tag), func(toUpdate *ateapi.Tag) error { toUpdate.Status.Snapshot = pending return nil }) @@ -487,7 +487,7 @@ func (w *ActorWorkflow) ensureTagSnapshotRecorded(ctx context.Context, tag *atea // ensureTagSnapshotCopied copies the actor's external snapshot to the tag's own // prefix. The prefix is empty by construction, so the copy never blends with // another attempt's objects. -func (w *ActorWorkflow) ensureTagSnapshotCopied(ctx context.Context, tag *ateapipb.Tag, snapshot *ateapipb.Snapshot, dst resources.SnapshotURI) (err error) { +func (w *ActorWorkflow) ensureTagSnapshotCopied(ctx context.Context, tag *ateapi.Tag, snapshot *ateapi.Snapshot, dst resources.SnapshotURI) (err error) { ctx, done := stepSpan(ctx, "CopyTagSnapshot") defer func() { err = done(err) }() @@ -510,7 +510,7 @@ func (w *ActorWorkflow) ensureTagSnapshotCopied(ctx context.Context, tag *ateapi // ensureTagFinalized publishes the copy by marking status.snapshot COMPLETED. // Until this lands the tag is pending and unusable; deleting it collects any // partial copy. -func (w *ActorWorkflow) ensureTagFinalized(ctx context.Context, tag *ateapipb.Tag, snapshot *ateapipb.Snapshot, dst resources.SnapshotURI) (_ *ateapipb.Tag, err error) { +func (w *ActorWorkflow) ensureTagFinalized(ctx context.Context, tag *ateapi.Tag, snapshot *ateapi.Snapshot, dst resources.SnapshotURI) (_ *ateapi.Tag, err error) { ctx, done := stepSpan(ctx, "FinalizeTag") defer func() { err = done(err) }() @@ -518,15 +518,15 @@ func (w *ActorWorkflow) ensureTagFinalized(ctx context.Context, tag *ateapipb.Ta // The copy is byte-identical to the source, so it carries the same content. finalSnapshot := newDurableSnapshot( 1, - ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, + ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, snapshot.GetFidelity(), "", dst.Name(), dst.String(), - ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, + ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, ) finalSnapshot.SandboxRuntime = proto.CloneOf(snapshot.GetSandboxRuntime()) - stored, err := w.store.UpdateTag(ctx, tagRef, store.PreconditionFrom(tag), func(toUpdate *ateapipb.Tag) error { + stored, err := w.store.UpdateTag(ctx, tagRef, store.PreconditionFrom(tag), func(toUpdate *ateapi.Tag) error { toUpdate.Status.Snapshot = finalSnapshot return nil }) diff --git a/cmd/ateapi/internal/controlapi/workflow_tag_test.go b/cmd/ateapi/internal/controlapi/workflow_tag_test.go index b53da8cd92..b1e14ec14c 100644 --- a/cmd/ateapi/internal/controlapi/workflow_tag_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_tag_test.go @@ -23,13 +23,13 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/objectstore/objectstoretest" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" @@ -39,29 +39,29 @@ import ( // seedTagSource stores a suspended actor whose external snapshot is made of // objectNames, the state a tag can be taken from. It returns the actor and the // URI of that snapshot. -func seedTagSource(t *testing.T, ctx context.Context, persistence store.Interface, objects *objectstoretest.Fake, template *ateapipb.ActorTemplate, name string, objectNames ...string) (*ateapipb.Actor, resources.SnapshotURI) { +func seedTagSource(t *testing.T, ctx context.Context, persistence store.Interface, objects *objectstoretest.Fake, template *ateapi.ActorTemplate, name string, objectNames ...string) (*ateapi.Actor, resources.SnapshotURI) { t.Helper() - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: template.GetMetadata().GetName()}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: template.GetMetadata().GetName()}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) uri := mustActorSnapshotURI(t, template, actor, name+"-snapshot") objects.PutSnapshot(t, uri, objectNames...) - actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 1 - snap := newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, template.GetMetadata().GetUid(), uri.Name(), uri.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + snap := newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, template.GetMetadata().GetUid(), uri.Name(), uri.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) snap.SandboxRuntime = testSandboxRuntime() - s.Snapshots = []*ateapipb.Snapshot{snap} + s.Snapshots = []*ateapi.Snapshot{snap} }) return actor, uri } // tagToCreate is the part of a Tag a client owns on create. -func tagToCreate(sourceActor resources.ActorRef, name string) *ateapipb.Tag { - return &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Name: name}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, +func tagToCreate(sourceActor resources.ActorRef, name string) *ateapi.Tag { + return &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Name: name}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, SourceActor: sourceActor.ToObjectRef(), } } @@ -94,7 +94,7 @@ func TestTagActorSnapshot(t *testing.T) { t.Fatalf("TagActorSnapshot: %v", err) } - tagSnapshot := tagDurableSnapshotURI(tag, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + tagSnapshot := tagDurableSnapshotURI(tag, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) if tagSnapshot == "" || tagSnapshot == actorSnapshot.String() { t.Fatalf("tag snapshot uri = %q, want a copy of its own rather than the actor's %q", tagSnapshot, actorSnapshot) } @@ -107,7 +107,7 @@ func TestTagActorSnapshot(t *testing.T) { if got, want := tag.GetStatus().GetActorTemplateUid(), template.GetMetadata().GetUid(); got != want { t.Errorf("actor template uid = %q, want %q", got, want) } - if got, want := tag.GetStatus().GetSnapshot().GetFidelity(), ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY; got != want { + if got, want := tag.GetStatus().GetSnapshot().GetFidelity(), ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY; got != want { t.Errorf("fidelity = %v, want the source's %v", got, want) } if diff := cmp.Diff(testSandboxRuntime(), tag.GetStatus().GetSnapshot().GetSandboxRuntime(), protocmp.Transform()); diff != "" { @@ -137,8 +137,8 @@ func TestTagActorSnapshot_ActorRepointedToAnotherTemplate(t *testing.T) { // Repoint the suspended actor, the way UpdateActor does. The snapshot on // disk still came from tmpl-a, and the UID recorded alongside it only // moves when a later suspend commits a new snapshot. - if _, err := persistence.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapipb.Actor) error { - toUpdate.ActorTemplate = &ateapipb.ObjectRef{Atespace: "team-a", Name: "tmpl-b"} + if _, err := persistence.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapi.Actor) error { + toUpdate.ActorTemplate = &ateapi.ObjectRef{Atespace: "team-a", Name: "tmpl-b"} return nil }); err != nil { t.Fatalf("repointing actor %s: %v", actorRef, err) @@ -163,7 +163,7 @@ func TestTagActorSnapshot_ActorRepointedToAnotherTemplate(t *testing.T) { func TestTagActorSnapshot_Preconditions(t *testing.T) { tests := []struct { name string - state ateapipb.ActorState + state ateapi.ActorState withSnapshot bool // builtOnTemplate records the template the seeded snapshot was taken // under, as every real path to holding one does. Only the case that @@ -173,19 +173,19 @@ func TestTagActorSnapshot_Preconditions(t *testing.T) { }{ { name: "the actor is not suspended", - state: ateapipb.ActorState_ACTOR_STATE_RUNNING, + state: ateapi.ActorState_ACTOR_STATE_RUNNING, withSnapshot: true, builtOnTemplate: true, wantCode: codes.FailedPrecondition, }, { name: "the actor holds no external snapshot", - state: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + state: ateapi.ActorState_ACTOR_STATE_SUSPENDED, wantCode: codes.FailedPrecondition, }, { name: "the actor records no template its snapshot was built under", - state: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + state: ateapi.ActorState_ACTOR_STATE_SUSPENDED, withSnapshot: true, wantCode: codes.Internal, }, @@ -199,22 +199,22 @@ func TestTagActorSnapshot_Preconditions(t *testing.T) { w, objects := newFinalizeWorkflow(persistence) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{State: tt.state}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{State: tt.state}, }) if tt.withSnapshot { uri := mustActorSnapshotURI(t, template, actor, "actor-1-snapshot") objects.PutSnapshot(t, uri, "manifest.json") - mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { var tmplUID string if tt.builtOnTemplate { tmplUID = template.GetMetadata().GetUid() } s.LastAssignedGeneration = 1 - s.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmplUID, uri.Name(), uri.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + s.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmplUID, uri.Name(), uri.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), } }) } @@ -266,18 +266,18 @@ func TestTagActorSnapshot_TagsNewestExternalSnapshot(t *testing.T) { w, objects := newFinalizeWorkflow(persistence) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) uri := mustActorSnapshotURI(t, template, actor, "actor-1-snapshot") objects.PutSnapshot(t, uri, "manifest.json") - mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { - snap := newDurableSnapshot(tt.extGen, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, template.GetMetadata().GetUid(), uri.Name(), uri.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { + snap := newDurableSnapshot(tt.extGen, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, template.GetMetadata().GetUid(), uri.Name(), uri.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) snap.Locality = tt.locality s.LastAssignedGeneration = tt.lastAssigned - s.Snapshots = []*ateapipb.Snapshot{snap} + s.Snapshots = []*ateapi.Snapshot{snap} }) if _, err := w.TagActorSnapshot(ctx, tagToCreate(actorRef, "v1")); err != nil { @@ -295,7 +295,7 @@ func TestTagActorSnapshot_TagsNewestExternalSnapshot(t *testing.T) { // upload. func TestTagActorSnapshot_PromotesLocalSnapshot(t *testing.T) { // reported is the state atelet answers with once it made snap durable. - reported := func(snap *ateapipb.Snapshot) *ateletpb.ActorSnapshotState { + reported := func(snap *ateapi.Snapshot) *ateletpb.ActorSnapshotState { report := &ateletpb.SnapshotReport{Snapshot: &ateletpb.Snapshot{ SnapshotUuid: snap.GetUuid(), Generation: snap.GetGeneration(), @@ -323,7 +323,7 @@ func TestTagActorSnapshot_PromotesLocalSnapshot(t *testing.T) { noTemplateUID bool // promoteState builds the state PromoteSnapshot answers with from the // local snapshot. - promoteState func(paused *ateapipb.Snapshot) *ateletpb.ActorSnapshotState + promoteState func(paused *ateapi.Snapshot) *ateletpb.ActorSnapshotState promoteErr error wantPromote bool wantCode codes.Code @@ -396,13 +396,13 @@ func TestTagActorSnapshot_PromotesLocalSnapshot(t *testing.T) { }, { name: "atelet reports no durable snapshot", - promoteState: func(*ateapipb.Snapshot) *ateletpb.ActorSnapshotState { return &ateletpb.ActorSnapshotState{} }, + promoteState: func(*ateapi.Snapshot) *ateletpb.ActorSnapshotState { return &ateletpb.ActorSnapshotState{} }, wantPromote: true, wantCode: codes.Internal, }, { name: "atelet reports another snapshot at the generation", - promoteState: func(paused *ateapipb.Snapshot) *ateletpb.ActorSnapshotState { + promoteState: func(paused *ateapi.Snapshot) *ateletpb.ActorSnapshotState { state := reported(paused) state.LatestDurable.Snapshot.SnapshotUuid = "another-snapshot" return state @@ -412,7 +412,7 @@ func TestTagActorSnapshot_PromotesLocalSnapshot(t *testing.T) { }, { name: "atelet reports the snapshot at another generation", - promoteState: func(paused *ateapipb.Snapshot) *ateletpb.ActorSnapshotState { + promoteState: func(paused *ateapi.Snapshot) *ateletpb.ActorSnapshotState { state := reported(paused) state.LatestDurable.Snapshot.Generation = 1 return state @@ -422,7 +422,7 @@ func TestTagActorSnapshot_PromotesLocalSnapshot(t *testing.T) { }, { name: "atelet reports the snapshot uploaded to another URI", - promoteState: func(paused *ateapipb.Snapshot) *ateletpb.ActorSnapshotState { + promoteState: func(paused *ateapi.Snapshot) *ateletpb.ActorSnapshotState { state := reported(paused) state.LatestDurable.Snapshot.Object.SnapshotUri += "-elsewhere" return state @@ -432,7 +432,7 @@ func TestTagActorSnapshot_PromotesLocalSnapshot(t *testing.T) { }, { name: "atelet reports the snapshot without a fidelity", - promoteState: func(paused *ateapipb.Snapshot) *ateletpb.ActorSnapshotState { + promoteState: func(paused *ateapi.Snapshot) *ateletpb.ActorSnapshotState { state := reported(paused) state.LatestDurable.Snapshot.Fidelity = ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED return state @@ -451,49 +451,49 @@ func TestTagActorSnapshot_PromotesLocalSnapshot(t *testing.T) { tmplUID := template.GetMetadata().GetUid() actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} - actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, AssignedNode: "node-1"}, + actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "team-a", Name: "sub-tmpl"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, AssignedNode: "node-1"}, }) pausedURI := mustActorSnapshotURI(t, template, actor, "paused") objects.PutSnapshot(t, pausedURI, "manifest.json", "memory.zst") - pausedStatus := ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + pausedStatus := ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING if tt.uploaded { - pausedStatus = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + pausedStatus = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED } - paused := newDurableSnapshot(2, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmplUID, pausedURI.Name(), pausedURI.String(), pausedStatus) + paused := newDurableSnapshot(2, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmplUID, pausedURI.Name(), pausedURI.String(), pausedStatus) if !tt.nodeLost { paused.Locality = "node-1" } if tt.noTemplateUID { paused.ActorTemplateUid = "" } - actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { + actor = mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.LastAssignedGeneration = 2 if tt.olderDurable { olderURI := mustActorSnapshotURI(t, template, actor, "older") objects.PutSnapshot(t, olderURI, "manifest.json") - s.Snapshots = append(s.Snapshots, newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmplUID, olderURI.Name(), olderURI.String(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)) + s.Snapshots = append(s.Snapshots, newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmplUID, olderURI.Name(), olderURI.String(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)) } s.Snapshots = append(s.Snapshots, proto.CloneOf(paused)) }) tagRef := resources.TagRef{Atespace: "team-a", Name: "v1"} - var takenBy *ateapipb.Tag + var takenBy *ateapi.Tag if tt.nameTaken { var err error - takenBy, err = persistence.CreateTag(ctx, &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: tagRef.Atespace, Name: tagRef.Name}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, + takenBy, err = persistence.CreateTag(ctx, &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: tagRef.Atespace, Name: tagRef.Name}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, SourceActor: actorRef.ToObjectRef(), - Status: &ateapipb.TagStatus{ActorTemplateUid: tmplUID}, + Status: &ateapi.TagStatus{ActorTemplateUid: tmplUID}, }) if err != nil { t.Fatalf("CreateTag: %v", err) } } if tt.badLocation { - _, err := persistence.UpdateActorTemplate(ctx, resources.ActorTemplateRefFromActorTemplate(template), store.PreconditionFrom(template), func(tmpl *ateapipb.ActorTemplate) error { + _, err := persistence.UpdateActorTemplate(ctx, resources.ActorTemplateRefFromActorTemplate(template), store.PreconditionFrom(template), func(tmpl *ateapi.ActorTemplate) error { tmpl.SnapshotConfig.StorageLocation = "gs://ate-snapshots/team-a/?query" return nil }) @@ -525,7 +525,7 @@ func TestTagActorSnapshot_PromotesLocalSnapshot(t *testing.T) { Snapshot: &ateletpb.Snapshot{ SnapshotUuid: pausedURI.Name(), Generation: 2, - Fidelity: fidelityToAtelet(ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY), + Fidelity: fidelityToAtelet(ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY), Object: &ateletpb.ObjectStorage{SnapshotUri: pausedURI.String()}, }, } @@ -554,7 +554,7 @@ func TestTagActorSnapshot_PromotesLocalSnapshot(t *testing.T) { return } - tagSnapshot := tagDurableSnapshotURI(tag, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + tagSnapshot := tagDurableSnapshotURI(tag, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) if tt.nodeLost { // Nothing to upload from: the actor is left as it was, and the // tag copied the older durable snapshot. @@ -569,7 +569,7 @@ func TestTagActorSnapshot_PromotesLocalSnapshot(t *testing.T) { // The local snapshot is now durable and stays on its node. wantPaused := proto.CloneOf(paused) - wantPaused.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + wantPaused.DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED if diff := cmp.Diff(wantPaused, findSnapshotByGeneration(stored.GetStatus().GetSnapshots(), 2), protocmp.Transform()); diff != "" { t.Errorf("the actor's latest snapshot mismatch (-want +got):\n%s", diff) } @@ -612,7 +612,7 @@ func TestTagActorSnapshot_RecreateAfterCopyFailure(t *testing.T) { if err != nil { t.Fatalf("GetTag after the external store failure: %v", err) } - if got := tagDurableSnapshotURI(pending, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED); got != "" { + if got := tagDurableSnapshotURI(pending, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED); got != "" { t.Errorf("snapshot uri after the failure = %q, want unset: the copy never finished", got) } strandedURI := mustReservedTagSnapshotURI(t, pending) @@ -651,7 +651,7 @@ func TestTagActorSnapshot_RecreateAfterCopyFailure(t *testing.T) { if err != nil { t.Fatalf("TagActorSnapshot after the delete: %v", err) } - recreated := tagDurableSnapshotURI(tag, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + recreated := tagDurableSnapshotURI(tag, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) if recreated == "" || recreated == stranded { t.Fatalf("snapshot uri after the delete = %q, want a fresh prefix rather than the stranded %q", recreated, stranded) } @@ -676,7 +676,7 @@ type recordTagErrorStore struct { err error } -func (s *recordTagErrorStore) UpdateTag(ctx context.Context, tagRef resources.TagRef, precondition store.Precondition, mutate func(*ateapipb.Tag) error) (*ateapipb.Tag, error) { +func (s *recordTagErrorStore) UpdateTag(ctx context.Context, tagRef resources.TagRef, precondition store.Precondition, mutate func(*ateapi.Tag) error) (*ateapi.Tag, error) { if s.err != nil { return nil, s.err } @@ -732,7 +732,7 @@ func TestTagActorSnapshot_RecreateAfterRecordFailure(t *testing.T) { if err != nil { t.Fatalf("TagActorSnapshot after the delete: %v", err) } - if got, want := tagDurableSnapshotURI(tag, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), mustTagSnapshotURI(t, template, "team-a", tag.GetMetadata().GetUid()).String(); got != want { + if got, want := tagDurableSnapshotURI(tag, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), mustTagSnapshotURI(t, template, "team-a", tag.GetMetadata().GetUid()).String(); got != want { t.Errorf("recreated tag snapshot uri = %q, want UID-based URI %q", got, want) } } @@ -782,7 +782,7 @@ func TestTagActorSnapshot_RacesDelete(t *testing.T) { // Nothing was collected out from under the copy, and the row in the store it // is still there. - if got := tagDurableSnapshotURI(tag, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED); got != pendingURI { + if got := tagDurableSnapshotURI(tag, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED); got != pendingURI { t.Errorf("snapshot uri = %q, want the prefix the create reserved, %q", got, pendingURI) } if diff := cmp.Diff([]string{"manifest.json", "memory.zst"}, objects.Snapshot(t, mustParseSnapshotURI(t, pendingURI))); diff != "" { @@ -924,8 +924,8 @@ func TestDeleteTag_ReleasesPendingSnapshot(t *testing.T) { objects.PutSnapshot(t, uri, "manifest.json") // Cleanup must work without the source actor or its template. - mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapipb.ActorStatus) { - s.State = ateapipb.ActorState_ACTOR_STATE_DELETING + mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { + s.State = ateapi.ActorState_ACTOR_STATE_DELETING }) if _, err := persistence.DeleteActor(ctx, resources.ActorRefFromActor(actor), store.DeletePreconditions{}); err != nil { t.Fatalf("DeleteActor: %v", err) @@ -965,9 +965,9 @@ func TestDeleteTag_NotFound(t *testing.T) { } } -func mustReservedTagSnapshotURI(t *testing.T, tag *ateapipb.Tag) resources.SnapshotURI { +func mustReservedTagSnapshotURI(t *testing.T, tag *ateapi.Tag) resources.SnapshotURI { t.Helper() - uri, err := resources.ParseSnapshotURI(tagDurableSnapshotURI(tag, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_UNSPECIFIED)) + uri, err := resources.ParseSnapshotURI(tagDurableSnapshotURI(tag, ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_UNSPECIFIED)) if err != nil { t.Fatalf("ParseSnapshotURI: %v", err) } diff --git a/cmd/ateapi/internal/controlapi/workflow_template_delete.go b/cmd/ateapi/internal/controlapi/workflow_template_delete.go index e8d4e087c5..efe92ad50e 100644 --- a/cmd/ateapi/internal/controlapi/workflow_template_delete.go +++ b/cmd/ateapi/internal/controlapi/workflow_template_delete.go @@ -19,18 +19,18 @@ import ( "errors" "fmt" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" ) // DeleteActorTemplate executes the workflow to delete an ActorTemplate. The // golden actor and tag go first and the row last, so a failed attempt leaves // the row for a retry to rediscover them by. -func (w *ActorWorkflow) DeleteActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions) (*ateapipb.ActorTemplate, error) { +func (w *ActorWorkflow) DeleteActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions) (*ateapi.ActorTemplate, error) { ctx = preview.ContextWithOptIn(ctx) // Serializes against the reconciler, which creates the golden actor and // tag under the same lease. @@ -59,12 +59,12 @@ func (w *ActorWorkflow) DeleteActorTemplate(ctx context.Context, templateRef res // ensureTemplateMarkedForDeletion sets the template's delete_time, checking // precondition, and returns the stored copy. Skips when a previous attempt // already marked the template. -func (w *ActorWorkflow) ensureTemplateMarkedForDeletion(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions) (_ *ateapipb.ActorTemplate, err error) { +func (w *ActorWorkflow) ensureTemplateMarkedForDeletion(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions) (_ *ateapi.ActorTemplate, err error) { ctx, done := stepSpan(ctx, "MarkTemplateForDeletion") defer func() { err = done(err) }() - var alreadyDeleting *ateapipb.ActorTemplate - marked, err := w.store.MarkActorTemplateForDeletion(ctx, templateRef, precondition, func(toUpdate *ateapipb.ActorTemplate) error { + var alreadyDeleting *ateapi.ActorTemplate + marked, err := w.store.MarkActorTemplateForDeletion(ctx, templateRef, precondition, func(toUpdate *ateapi.ActorTemplate) error { if toUpdate.GetMetadata().GetDeleteTime() != nil { alreadyDeleting = toUpdate return errAlreadyMarked @@ -125,7 +125,7 @@ func (w *ActorWorkflow) ensureGoldenTagDeleted(ctx context.Context, goldenTagRef // finalizeTemplateDeleted removes the template from the store and returns the // deleted record. -func (w *ActorWorkflow) finalizeTemplateDeleted(ctx context.Context, tmpl *ateapipb.ActorTemplate) (_ *ateapipb.ActorTemplate, err error) { +func (w *ActorWorkflow) finalizeTemplateDeleted(ctx context.Context, tmpl *ateapi.ActorTemplate) (_ *ateapi.ActorTemplate, err error) { ctx, done := stepSpan(ctx, "FinalizeTemplateDeleted") defer func() { err = done(err) }() diff --git a/cmd/ateapi/internal/controlapi/workflow_test.go b/cmd/ateapi/internal/controlapi/workflow_test.go index ef88cf37ff..d8e50ce33b 100644 --- a/cmd/ateapi/internal/controlapi/workflow_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_test.go @@ -18,13 +18,13 @@ import ( "context" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/actorevent" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" ) @@ -39,57 +39,57 @@ func TestActorStateChangeRecords(t *testing.T) { tests := []struct { name string - seedState ateapipb.ActorState - seedOpts []func(*ateapipb.Actor) + seedState ateapi.ActorState + seedOpts []func(*ateapi.Actor) // transition runs the workflow step that commits the new state. - transition func(t *testing.T, w *ActorWorkflow, ref resources.ActorRef, actor *ateapipb.Actor, tmpl *ateapipb.ActorTemplate) + transition func(t *testing.T, w *ActorWorkflow, ref resources.ActorRef, actor *ateapi.Actor, tmpl *ateapi.ActorTemplate) wantOp string wantState string - wantStored ateapipb.ActorState + wantStored ateapi.ActorState }{ { name: "suspend marks the actor suspending", - seedState: ateapipb.ActorState_ACTOR_STATE_RUNNING, - transition: func(t *testing.T, w *ActorWorkflow, ref resources.ActorRef, actor *ateapipb.Actor, _ *ateapipb.ActorTemplate) { + seedState: ateapi.ActorState_ACTOR_STATE_RUNNING, + transition: func(t *testing.T, w *ActorWorkflow, ref resources.ActorRef, actor *ateapi.Actor, _ *ateapi.ActorTemplate) { markOnly(t, w, ref, actor, suspendSync) }, wantOp: ateattr.OperationSuspend, wantState: ateattr.ActorStateSuspending, - wantStored: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + wantStored: ateapi.ActorState_ACTOR_STATE_SUSPENDING, }, { name: "pause marks the actor suspending", - seedState: ateapipb.ActorState_ACTOR_STATE_RUNNING, - transition: func(t *testing.T, w *ActorWorkflow, ref resources.ActorRef, actor *ateapipb.Actor, _ *ateapipb.ActorTemplate) { + seedState: ateapi.ActorState_ACTOR_STATE_RUNNING, + transition: func(t *testing.T, w *ActorWorkflow, ref resources.ActorRef, actor *ateapi.Actor, _ *ateapi.ActorTemplate) { markOnly(t, w, ref, actor, suspendAsync) }, wantOp: ateattr.OperationSuspend, wantState: ateattr.ActorStateSuspending, - wantStored: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, + wantStored: ateapi.ActorState_ACTOR_STATE_SUSPENDING, }, { name: "finalize pause marks the actor suspended", - seedState: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, - seedOpts: []func(*ateapipb.Actor){ + seedState: ateapi.ActorState_ACTOR_STATE_SUSPENDING, + seedOpts: []func(*ateapi.Actor){ withPauseInProgress(t), - func(a *ateapipb.Actor) { + func(a *ateapi.Actor) { a.Status.AssignedNode = "node-1" a.Status.WorkerAssignment = wireTestAssignment() }, }, - transition: func(t *testing.T, w *ActorWorkflow, ref resources.ActorRef, _ *ateapipb.Actor, _ *ateapipb.ActorTemplate) { + transition: func(t *testing.T, w *ActorWorkflow, ref resources.ActorRef, _ *ateapi.Actor, _ *ateapi.ActorTemplate) { if _, err := w.SuspendActor(context.Background(), ref, suspendAsync); err != nil { t.Fatalf("SuspendActor: %v", err) } }, wantOp: ateattr.OperationSuspend, wantState: ateattr.ActorStateSuspended, - wantStored: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + wantStored: ateapi.ActorState_ACTOR_STATE_SUSPENDED, }, { name: "delete marks the actor deleting", - seedState: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, - transition: func(t *testing.T, w *ActorWorkflow, ref resources.ActorRef, _ *ateapipb.Actor, _ *ateapipb.ActorTemplate) { + seedState: ateapi.ActorState_ACTOR_STATE_SUSPENDED, + transition: func(t *testing.T, w *ActorWorkflow, ref resources.ActorRef, _ *ateapi.Actor, _ *ateapi.ActorTemplate) { if _, err := w.ensureMarkedDeleting(context.Background(), ref, store.DeletePreconditions{}); err != nil { t.Fatalf("ensureMarkedDeleting: %v", err) } @@ -100,7 +100,7 @@ func TestActorStateChangeRecords(t *testing.T) { }, wantOp: ateattr.OperationDelete, wantState: ateattr.ActorStateDeleting, - wantStored: ateapipb.ActorState_ACTOR_STATE_DELETING, + wantStored: ateapi.ActorState_ACTOR_STATE_DELETING, }, } @@ -112,9 +112,9 @@ func TestActorStateChangeRecords(t *testing.T) { persistence := newTestPersistence(t) storetest.MustCreateAtespace(t, ctx, persistence, tmplAtespace) - if _, err := persistence.CreateActorTemplate(ctx, &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: tmplAtespace, Name: tmplName}, - SnapshotConfig: &ateapipb.SnapshotConfig{ + if _, err := persistence.CreateActorTemplate(ctx, &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: tmplAtespace, Name: tmplName}, + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: testStorageLocation, }, }); err != nil { @@ -177,10 +177,10 @@ func TestActorStateChangeRecords(t *testing.T) { // markOnly runs a suspend (sync or async) on a RUNNING actor only as far as its // mark step: the actor gets a worker to checkpoint on, but the atelet dial // fails, so the SUSPENDING mark is the only transition the workflow commits. -func markOnly(t *testing.T, w *ActorWorkflow, ref resources.ActorRef, actor *ateapipb.Actor, mode suspendMode) { +func markOnly(t *testing.T, w *ActorWorkflow, ref resources.ActorRef, actor *ateapi.Actor, mode suspendMode) { t.Helper() ctx := context.Background() - if _, err := w.store.UpdateActor(ctx, ref, store.PreconditionFrom(actor), func(toUpdate *ateapipb.Actor) error { + if _, err := w.store.UpdateActor(ctx, ref, store.PreconditionFrom(actor), func(toUpdate *ateapi.Actor) error { toUpdate.Status.WorkerAssignment = wireTestAssignment() return nil }); err != nil { @@ -200,10 +200,10 @@ func TestActorCreatedRecord(t *testing.T) { persistence := newTestPersistence(t) storetest.MustCreateAtespace(t, ctx, persistence, "ns") - storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "id1"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns", Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "ns", Name: "tmpl1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) stored, err := persistence.GetActor(ctx, resources.ActorRef{Atespace: "team-a", Name: "id1"}) if err != nil { @@ -235,15 +235,15 @@ func TestActorDeletedRecord(t *testing.T) { persistence := newTestPersistence(t) storetest.MustCreateAtespace(t, ctx, persistence, "ns") - if _, err := persistence.CreateActorTemplate(ctx, &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ns", Name: "tmpl1"}, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation}, + if _, err := persistence.CreateActorTemplate(ctx, &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ns", Name: "tmpl1"}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}, }); err != nil { t.Fatalf("create template: %v", err) } actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - seedWorkflowActor(t, ctx, persistence, actorRef, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_DELETING) + seedWorkflowActor(t, ctx, persistence, actorRef, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_DELETING) actor, err := persistence.MarkActorForDeletion(ctx, actorRef, store.DeletePreconditions{}, nil) if err != nil { t.Fatalf("mark actor: %v", err) @@ -281,25 +281,25 @@ func TestActorStateChangeRecordSkippedOnConflict(t *testing.T) { persistence := newTestPersistence(t) storetest.MustCreateAtespace(t, ctx, persistence, "ns") - if _, err := persistence.CreateActorTemplate(ctx, &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ns", Name: "tmpl1"}, - SnapshotConfig: &ateapipb.SnapshotConfig{StorageLocation: testStorageLocation}, + if _, err := persistence.CreateActorTemplate(ctx, &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ns", Name: "tmpl1"}, + SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}, }); err != nil { t.Fatalf("create template: %v", err) } actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} - seedWorkflowActor(t, ctx, persistence, actorRef, "ns", "tmpl1", ateapipb.ActorState_ACTOR_STATE_RUNNING) + seedWorkflowActor(t, ctx, persistence, actorRef, "ns", "tmpl1", ateapi.ActorState_ACTOR_STATE_RUNNING) stale, err := persistence.GetActor(ctx, actorRef) if err != nil { t.Fatalf("get actor: %v", err) } // Bump the stored version so the workflow's precondition is stale. - if _, err := persistence.UpdateActor(ctx, actorRef, store.PreconditionFrom(stale), func(toUpdate *ateapipb.Actor) error { + if _, err := persistence.UpdateActor(ctx, actorRef, store.PreconditionFrom(stale), func(toUpdate *ateapi.Actor) error { toUpdate.Status.LastAssignedGeneration = 1 - toUpdate.Status.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "someone-else", someActorSnapshotURI(t, testStorageLocation, "team-a", "someone-else"), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), + toUpdate.Status.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "someone-else", someActorSnapshotURI(t, testStorageLocation, "team-a", "someone-else"), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING), } return nil }); err != nil { diff --git a/cmd/ateapi/internal/controlapi/workflow_testutil_test.go b/cmd/ateapi/internal/controlapi/workflow_testutil_test.go index 25b6c95a03..3ac600bba7 100644 --- a/cmd/ateapi/internal/controlapi/workflow_testutil_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_testutil_test.go @@ -22,6 +22,7 @@ import ( "time" "github.com/google/uuid" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" @@ -29,7 +30,6 @@ import ( "go.ate.dev/substrate/internal/objectstore/objectstoretest" "go.ate.dev/substrate/internal/objectstoreplugin/objectstoreplugintest" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" @@ -51,9 +51,9 @@ func testWorkerUID(podName string) string { func newTestActorWorkflow(t *testing.T, st store.Interface, tmplAtespace, tmplName string) *ActorWorkflow { t.Helper() storetest.MustCreateAtespace(t, context.Background(), st, tmplAtespace) - if _, err := st.CreateActorTemplate(context.Background(), &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: tmplAtespace, Name: tmplName}, - SnapshotConfig: &ateapipb.SnapshotConfig{ + if _, err := st.CreateActorTemplate(context.Background(), &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: tmplAtespace, Name: tmplName}, + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: "gs://snapshots", }, }); err != nil && !errors.Is(err, store.ErrAlreadyExists) { @@ -83,7 +83,7 @@ func newWireFinalizeWorkflow(t *testing.T, persistence store.Interface) (*ActorW // mustActorSnapshotURI builds the URI of a snapshot the actor took under // template's storage location, the way the suspend workflow does. -func mustActorSnapshotURI(t *testing.T, template *ateapipb.ActorTemplate, actor *ateapipb.Actor, name string) resources.SnapshotURI { +func mustActorSnapshotURI(t *testing.T, template *ateapi.ActorTemplate, actor *ateapi.Actor, name string) resources.SnapshotURI { t.Helper() atespace, uid := actor.GetMetadata().GetAtespace(), actor.GetMetadata().GetUid() uri, err := resources.NewActorSnapshotURI(template.GetSnapshotConfig().GetStorageLocation(), atespace, uid, name) @@ -117,7 +117,7 @@ func someActorSnapshotURI(t *testing.T, location, atespace, name string) string // mustTagSnapshotURI builds the URI of the one snapshot a tag owns, the way the // tag workflow does. -func mustTagSnapshotURI(t *testing.T, template *ateapipb.ActorTemplate, atespace, name string) resources.SnapshotURI { +func mustTagSnapshotURI(t *testing.T, template *ateapi.ActorTemplate, atespace, name string) resources.SnapshotURI { t.Helper() uri, err := resources.NewTagSnapshotURI(template.GetSnapshotConfig().GetStorageLocation(), atespace, name) if err != nil { @@ -129,10 +129,10 @@ func mustTagSnapshotURI(t *testing.T, template *ateapipb.ActorTemplate, atespace // mustUpdateActorStatus mutates a stored actor's status. Tests reach for it to // record snapshot URIs: an actor's prefix is keyed on the UID the store // assigns, so its URIs cannot be written until the row exists. -func mustUpdateActorStatus(t *testing.T, ctx context.Context, persistence store.Interface, actor *ateapipb.Actor, mutate func(*ateapipb.ActorStatus)) *ateapipb.Actor { +func mustUpdateActorStatus(t *testing.T, ctx context.Context, persistence store.Interface, actor *ateapi.Actor, mutate func(*ateapi.ActorStatus)) *ateapi.Actor { t.Helper() actorRef := resources.ActorRefFromActor(actor) - updated, err := persistence.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapipb.Actor) error { + updated, err := persistence.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapi.Actor) error { mutate(toUpdate.Status) return nil }) @@ -145,13 +145,13 @@ func mustUpdateActorStatus(t *testing.T, ctx context.Context, persistence store. // seedWorkflowActor stores an actor with the given state, bound to the given // template (pass the same tmplAtespace/tmplName as newTestActorWorkflow). // opts mutate the actor before it is stored. -func seedWorkflowActor(t *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef, tmplAtespace, tmplName string, actorState ateapipb.ActorState, opts ...func(*ateapipb.Actor)) { +func seedWorkflowActor(t *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef, tmplAtespace, tmplName string, actorState ateapi.ActorState, opts ...func(*ateapi.Actor)) { t.Helper() - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorRef.Name, Atespace: actorRef.Atespace}, - Status: &ateapipb.ActorStatus{State: actorState}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: tmplAtespace, Name: tmplName}, + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorRef.Name, Atespace: actorRef.Atespace}, + Status: &ateapi.ActorStatus{State: actorState}, + ActorTemplate: &ateapi.ObjectRef{Atespace: tmplAtespace, Name: tmplName}, } for _, opt := range opts { opt(actor) @@ -163,41 +163,41 @@ func seedWorkflowActor(t *testing.T, ctx context.Context, st store.Interface, ac // node-local snapshot at the latest generation with a PENDING durable copy, // pinned to node. Pair it with ACTOR_STATE_SUSPENDED to seed an asynchronously // suspended actor. -func withPausedShape(t *testing.T, node string) func(*ateapipb.Actor) { +func withPausedShape(t *testing.T, node string) func(*ateapi.Actor) { t.Helper() - snap := newPausedSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "pause-snap", node) - return func(a *ateapipb.Actor) { + snap := newPausedSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "pause-snap", node) + return func(a *ateapi.Actor) { a.Status.AssignedNode = node a.Status.LastAssignedGeneration = 1 - a.Status.Snapshots = []*ateapipb.Snapshot{proto.CloneOf(snap)} + a.Status.Snapshots = []*ateapi.Snapshot{proto.CloneOf(snap)} } } // withUploadedPausedShape seeds an asynchronously suspended actor whose // snapshot atelet has since uploaded: the local-snapshot shape, with its // durable copy COMPLETED. -func withUploadedPausedShape(t *testing.T, node string) func(*ateapipb.Actor) { +func withUploadedPausedShape(t *testing.T, node string) func(*ateapi.Actor) { t.Helper() paused := withPausedShape(t, node) - return func(a *ateapipb.Actor) { + return func(a *ateapi.Actor) { paused(a) - a.Status.Snapshots[0].DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + a.Status.Snapshots[0].DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED } } // newInProgressSnapshot builds the snapshot a suspend of either mode marks at // generation gen: a PENDING durable copy at a URI named uuid, and no locality // yet. -func newInProgressSnapshot(t *testing.T, gen int32, fidelity ateapipb.SnapshotFidelity, uuid string) *ateapipb.Snapshot { +func newInProgressSnapshot(t *testing.T, gen int32, fidelity ateapi.SnapshotFidelity, uuid string) *ateapi.Snapshot { t.Helper() - return newDurableSnapshot(gen, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, fidelity, "", uuid, someActorSnapshotURI(t, testStorageLocation, "team-a", uuid), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) + return newDurableSnapshot(gen, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, fidelity, "", uuid, someActorSnapshotURI(t, testStorageLocation, "team-a", uuid), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) } // newPausedSnapshot builds the snapshot an asynchronous suspend leaves on node // locality at generation gen: a node-local checkpoint whose PENDING durable // copy atelet uploads in the background. With no locality it is the in-progress // mark. -func newPausedSnapshot(t *testing.T, gen int32, fidelity ateapipb.SnapshotFidelity, templateUID, uuid, locality string) *ateapipb.Snapshot { +func newPausedSnapshot(t *testing.T, gen int32, fidelity ateapi.SnapshotFidelity, templateUID, uuid, locality string) *ateapi.Snapshot { t.Helper() snap := newInProgressSnapshot(t, gen, fidelity, uuid) snap.ActorTemplateUid = templateUID @@ -209,33 +209,33 @@ func newPausedSnapshot(t *testing.T, gen int32, fidelity ateapipb.SnapshotFideli // marking the actor SUSPENDING and finalizing it: a snapshot at the latest // generation with a PENDING durable copy and no locality yet. Pair it with // ACTOR_STATE_SUSPENDING. -func withPauseInProgress(t *testing.T) func(*ateapipb.Actor) { - snap := newInProgressSnapshot(t, 1, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "pause-snap") - return func(a *ateapipb.Actor) { +func withPauseInProgress(t *testing.T) func(*ateapi.Actor) { + snap := newInProgressSnapshot(t, 1, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "pause-snap") + return func(a *ateapi.Actor) { a.Status.LastAssignedGeneration = 1 - a.Status.Snapshots = []*ateapipb.Snapshot{proto.CloneOf(snap)} + a.Status.Snapshots = []*ateapi.Snapshot{proto.CloneOf(snap)} } } // allActorStates enumerates every ActorState value, for exhaustive // CheckPrerequisite table tests. It is derived from the generated enum map so // states added to the proto are covered automatically. -var allActorStates = func() []ateapipb.ActorState { - nums := make([]int32, 0, len(ateapipb.ActorState_name)) - for n := range ateapipb.ActorState_name { +var allActorStates = func() []ateapi.ActorState { + nums := make([]int32, 0, len(ateapi.ActorState_name)) + for n := range ateapi.ActorState_name { nums = append(nums, n) } slices.Sort(nums) - states := make([]ateapipb.ActorState, 0, len(nums)) + states := make([]ateapi.ActorState, 0, len(nums)) for _, n := range nums { - states = append(states, ateapipb.ActorState(n)) + states = append(states, ateapi.ActorState(n)) } return states }() // assertPrerequisiteResult verifies a CheckPrerequisite outcome for one // state: nil when allowed, FailedPrecondition otherwise. -func assertPrerequisiteResult(t *testing.T, st ateapipb.ActorState, err error, wantAllowed bool) { +func assertPrerequisiteResult(t *testing.T, st ateapi.ActorState, err error, wantAllowed bool) { t.Helper() if wantAllowed { if err != nil { @@ -253,26 +253,26 @@ func assertPrerequisiteResult(t *testing.T, st ateapipb.ActorState, err error, w } // suspendTestTemplateRef names the template seedSuspendTemplate stores. -func suspendTestTemplateRef() *ateapipb.ObjectRef { - return &ateapipb.ObjectRef{Atespace: "ns", Name: "tmpl1"} +func suspendTestTemplateRef() *ateapi.ObjectRef { + return &ateapi.ObjectRef{Atespace: "ns", Name: "tmpl1"} } // seedSuspendTemplate stores the ActorTemplate the suspend workflow tests run // their actors from, with the given snapshot config, and returns it as stored. -func seedSuspendTemplate(t *testing.T, ctx context.Context, st store.Interface, snapshotConfig *ateapipb.SnapshotConfig) *ateapipb.ActorTemplate { +func seedSuspendTemplate(t *testing.T, ctx context.Context, st store.Interface, snapshotConfig *ateapi.SnapshotConfig) *ateapi.ActorTemplate { t.Helper() ref := suspendTestTemplateRef() storetest.MustCreateAtespace(t, ctx, st, ref.GetAtespace()) if snapshotConfig.GetStorageLocation() == "" { if snapshotConfig == nil { - snapshotConfig = &ateapipb.SnapshotConfig{} + snapshotConfig = &ateapi.SnapshotConfig{} } else { snapshotConfig = proto.CloneOf(snapshotConfig) } snapshotConfig.StorageLocation = testStorageLocation } - created, err := st.CreateActorTemplate(ctx, &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, + created, err := st.CreateActorTemplate(ctx, &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: ref.GetAtespace(), Name: ref.GetName()}, SnapshotConfig: snapshotConfig, }) if err != nil { @@ -293,14 +293,14 @@ const registeredEpoch = 1 // registers, which the scheduler requires: a registered epoch and, unless // status names them, sandbox classes with a default runtime no snapshot // requires. -func registered(status *ateapipb.WorkerStatus) *ateapipb.WorkerStatus { +func registered(status *ateapi.WorkerStatus) *ateapi.WorkerStatus { status.RegisteredEpoch = max(status.RegisteredEpoch, registeredEpoch) if len(status.SandboxClasses) == 0 { - status.SandboxClasses = workerSandboxClasses(&ateapipb.ActorSandboxRuntime{ + status.SandboxClasses = workerSandboxClasses(&ateapi.ActorSandboxRuntime{ SandboxClass: "gvisor", - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{{Key: "architecture", Value: "fixture"}}, + Attributes: []*ateapi.AttributeEntry{{Key: "architecture", Value: "fixture"}}, }, }) } @@ -310,17 +310,17 @@ func registered(status *ateapipb.WorkerStatus) *ateapipb.WorkerStatus { // seedWireWorker stores the Worker wireTestAssignment names and places // assignment on it (none when nil), so a finalize step has a real assignment // to release. -func seedWireWorker(t *testing.T, ctx context.Context, st store.Interface, assignment *ateapipb.ActorAssignment) { +func seedWireWorker(t *testing.T, ctx context.Context, st store.Interface, assignment *ateapi.ActorAssignment) { t.Helper() wa := wireTestAssignment() - if _, err := st.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: wa.GetWorker().GetName()}, + if _, err := st.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: wa.GetWorker().GetName()}, WorkerNamespace: wa.GetWorkerNamespace(), WorkerPool: wa.GetWorkerPool(), WorkerPod: wa.GetWorkerPod(), WorkerPodUid: wa.GetWorkerPodUid(), NodeName: wa.GetNodeName(), - Status: &ateapipb.WorkerStatus{}, + Status: &ateapi.WorkerStatus{}, }); err != nil { t.Fatalf("CreateWorker: %v", err) } @@ -328,9 +328,9 @@ func seedWireWorker(t *testing.T, ctx context.Context, st store.Interface, assig } // assignmentOf is the worker assignment that places actor on a worker. -func assignmentOf(actor *ateapipb.Actor) *ateapipb.ActorAssignment { - return &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: actor.GetMetadata().GetAtespace(), Name: actor.GetMetadata().GetName()}, +func assignmentOf(actor *ateapi.Actor) *ateapi.ActorAssignment { + return &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: actor.GetMetadata().GetAtespace(), Name: actor.GetMetadata().GetName()}, ActorUid: actor.GetMetadata().GetUid(), } } @@ -364,14 +364,14 @@ func assertLifecycleFidelity(t *testing.T, reader *sdkmetric.ManualReader, want // updateDuringCheckpoint makes atelet's Checkpoint mutate the stored actor // before it returns, standing in for a writer that lands between a workflow's // atelet call and its finalize step. -func updateDuringCheckpoint(t *testing.T, atelet *capturingAtelet, st store.Interface, actorRef resources.ActorRef, mutate func(*ateapipb.ActorStatus)) { +func updateDuringCheckpoint(t *testing.T, atelet *capturingAtelet, st store.Interface, actorRef resources.ActorRef, mutate func(*ateapi.ActorStatus)) { atelet.onCheckpoint = func(ctx context.Context) error { actor, err := st.GetActor(ctx, actorRef) if err != nil { t.Errorf("GetActor during Checkpoint: %v", err) return err } - if _, err := st.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapipb.Actor) error { + if _, err := st.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapi.Actor) error { mutate(toUpdate.Status) return nil }); err != nil { @@ -383,7 +383,7 @@ func updateDuringCheckpoint(t *testing.T, atelet *capturingAtelet, st store.Inte } // mustReadActor reads the stored actor. -func mustReadActor(t *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef) *ateapipb.Actor { +func mustReadActor(t *testing.T, ctx context.Context, st store.Interface, actorRef resources.ActorRef) *ateapi.Actor { t.Helper() actor, err := st.GetActor(ctx, actorRef) if err != nil { @@ -406,7 +406,7 @@ func (s workerDeletedDuringReleaseStore) AcquireLease(ctx context.Context, _ str return store.NewLease(ctx, func() {}), nil } -func (s workerDeletedDuringReleaseStore) ReleaseActorFromWorker(ctx context.Context, workerName, actorUID string) (*ateapipb.Worker, error) { +func (s workerDeletedDuringReleaseStore) ReleaseActorFromWorker(ctx context.Context, workerName, actorUID string) (*ateapi.Worker, error) { worker, err := s.Interface.GetWorker(ctx, workerName) if err != nil { return nil, err @@ -438,8 +438,8 @@ func assertConcurrentCrashKept(t *testing.T, ctx context.Context, st store.Inter if err != nil { t.Fatalf("GetActor: %v", err) } - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { - t.Errorf("state = %v, want %v", got.GetStatus().GetState(), ateapipb.ActorState_ACTOR_STATE_CRASHED) + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { + t.Errorf("state = %v, want %v", got.GetStatus().GetState(), ateapi.ActorState_ACTOR_STATE_CRASHED) } if msg := got.GetStatus().GetCrash().GetMessage(); msg != wantCrash { t.Errorf("crash message = %q, want %q", msg, wantCrash) diff --git a/cmd/ateapi/internal/controlapi/workflow_worker_crash.go b/cmd/ateapi/internal/controlapi/workflow_worker_crash.go index 6b426c0576..0742683633 100644 --- a/cmd/ateapi/internal/controlapi/workflow_worker_crash.go +++ b/cmd/ateapi/internal/controlapi/workflow_worker_crash.go @@ -19,18 +19,18 @@ import ( "errors" "fmt" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // CrashActorReportedByWorker crashes a RUNNING actor whose sandbox the worker // hosting it saw die. It holds the actor's lease, so an operation in flight // keeps the actor and fails on its own if the sandbox is gone. -func (w *ActorWorkflow) CrashActorReportedByWorker(ctx context.Context, actorRef resources.ActorRef, actorUID, workerName, message string) (*ateapipb.Actor, error) { +func (w *ActorWorkflow) CrashActorReportedByWorker(ctx context.Context, actorRef resources.ActorRef, actorUID, workerName, message string) (*ateapi.Actor, error) { ctx = preview.ContextWithOptIn(ctx) leaseCtx, lease, err := w.acquireActorLease(ctx, actorRef) if err != nil { @@ -49,7 +49,7 @@ func (w *ActorWorkflow) CrashActorReportedByWorker(ctx context.Context, actorRef if actor.GetMetadata().GetUid() != actorUID || actor.GetStatus().GetWorkerAssignment().GetWorker().GetName() != workerName { return nil, apierror.NotFound("Actor %s not found", actorRef) } - if state := actor.GetStatus().GetState(); state != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if state := actor.GetStatus().GetState(); state != ateapi.ActorState_ACTOR_STATE_RUNNING { return nil, apierror.FailedPrecondition("actor %s is %s, not RUNNING", actorRef, state) } if err := crashActor(leaseCtx, w.store, actorRef, ateattr.OperationUnknown, message); err != nil { diff --git a/cmd/ateapi/internal/controlapi/workflow_worker_crash_test.go b/cmd/ateapi/internal/controlapi/workflow_worker_crash_test.go index af7e1aa218..2fb29a09bb 100644 --- a/cmd/ateapi/internal/controlapi/workflow_worker_crash_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_worker_crash_test.go @@ -21,11 +21,11 @@ import ( "google.golang.org/grpc/codes" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) func TestCrashActorReportedByWorker(t *testing.T) { @@ -34,7 +34,7 @@ func TestCrashActorReportedByWorker(t *testing.T) { tests := []struct { name string // mutate edits the seeded RUNNING actor before the report. - mutate func(*ateapipb.Actor) + mutate func(*ateapi.Actor) // uid and worker the report names; empty means the real ones. uid, worker string wantCode codes.Code @@ -44,7 +44,7 @@ func TestCrashActorReportedByWorker(t *testing.T) { {name: "hosted by another worker", worker: "other-worker", wantCode: codes.NotFound}, { name: "operation in flight", - mutate: func(a *ateapipb.Actor) { a.Status.State = ateapipb.ActorState_ACTOR_STATE_SUSPENDING }, + mutate: func(a *ateapi.Actor) { a.Status.State = ateapi.ActorState_ACTOR_STATE_SUSPENDING }, wantCode: codes.FailedPrecondition, }, } @@ -60,7 +60,7 @@ func TestCrashActorReportedByWorker(t *testing.T) { t.Fatal(err) } if tc.mutate != nil { - if actor, err = st.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(a *ateapipb.Actor) error { + if actor, err = st.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(a *ateapi.Actor) error { tc.mutate(a) return nil }); err != nil { @@ -85,7 +85,7 @@ func TestCrashActorReportedByWorker(t *testing.T) { if err != nil { t.Fatal(err) } - if after.GetStatus().GetState() == ateapipb.ActorState_ACTOR_STATE_CRASHED { + if after.GetStatus().GetState() == ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("actor crashed by a refused report") } return diff --git a/cmd/ateapi/internal/controlapi/workflow_worker_delete.go b/cmd/ateapi/internal/controlapi/workflow_worker_delete.go index 9513e68bee..3e706c5968 100644 --- a/cmd/ateapi/internal/controlapi/workflow_worker_delete.go +++ b/cmd/ateapi/internal/controlapi/workflow_worker_delete.go @@ -21,13 +21,13 @@ import ( "log/slog" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -70,7 +70,7 @@ func (w *WorkerWorkflow) giveUpOnNode(nodeName string) { // record in place, and a retry fast-forwards past whatever the previous attempt // already did. An absent Worker is NOT_FOUND rather than success; idempotency // belongs to the caller, which knows whether that is the state it wanted. -func (w *WorkerWorkflow) DeleteWorker(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapipb.Worker, error) { +func (w *WorkerWorkflow) DeleteWorker(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.Worker, error) { ctx = preview.ContextWithOptIn(ctx) worker, err := w.ensureMarkedForDeletion(ctx, name, precondition) if err != nil { @@ -90,12 +90,12 @@ func (w *WorkerWorkflow) DeleteWorker(ctx context.Context, name string, precondi // ensureMarkedForDeletion sets the Worker's delete_time, checking // precondition, and drains it, returning the stored copy. Skips when a // previous attempt already marked the Worker. -func (w *WorkerWorkflow) ensureMarkedForDeletion(ctx context.Context, name string, precondition store.DeletePreconditions) (_ *ateapipb.Worker, err error) { +func (w *WorkerWorkflow) ensureMarkedForDeletion(ctx context.Context, name string, precondition store.DeletePreconditions) (_ *ateapi.Worker, err error) { ctx, done := stepSpan(ctx, "MarkWorkerForDeletion") defer func() { err = done(err) }() - var alreadyDeleting *ateapipb.Worker - marked, err := w.store.MarkWorkerForDeletion(ctx, name, precondition, func(toUpdate *ateapipb.Worker) error { + var alreadyDeleting *ateapi.Worker + marked, err := w.store.MarkWorkerForDeletion(ctx, name, precondition, func(toUpdate *ateapi.Worker) error { if toUpdate.GetMetadata().GetDeleteTime() != nil { alreadyDeleting = toUpdate return errAlreadyMarked @@ -105,9 +105,9 @@ func (w *WorkerWorkflow) ensureMarkedForDeletion(ctx context.Context, name strin // The delete would cascade that assignment away and leave the Actor // pointing at a Worker that is gone. if toUpdate.Status == nil { - toUpdate.Status = &ateapipb.WorkerStatus{} + toUpdate.Status = &ateapi.WorkerStatus{} } - toUpdate.Status.State = ateapipb.WorkerState_WORKER_STATE_DRAINING + toUpdate.Status.State = ateapi.WorkerState_WORKER_STATE_DRAINING return nil }) if errors.Is(err, errAlreadyMarked) { @@ -136,7 +136,7 @@ func (w *WorkerWorkflow) ensureMarkedForDeletion(ctx context.Context, name strin // where this left off. An Actor with an operation in progress is skipped // instead, so the others are still released, and the call then fails as // ABORTED for the caller to retry once that operation is done. -func (w *WorkerWorkflow) ensureBoundActorsReleased(ctx context.Context, worker *ateapipb.Worker) (err error) { +func (w *WorkerWorkflow) ensureBoundActorsReleased(ctx context.Context, worker *ateapi.Worker) (err error) { ctx, done := stepSpan(ctx, "ReleaseBoundActors") defer func() { err = done(err) }() @@ -188,7 +188,7 @@ func (w *WorkerWorkflow) ensureBoundActorsReleased(ctx context.Context, worker * // the reclaim below runs, nor lose a checkpoint it is still uploading. An Actor // whose lease is held is left for a retry (errActorBusy). A write that still // races this one fails the version check as ABORTED. -func (w *WorkerWorkflow) releaseBoundActor(ctx context.Context, worker *ateapipb.Worker, assignment *ateapipb.ActorAssignment) error { +func (w *WorkerWorkflow) releaseBoundActor(ctx context.Context, worker *ateapi.Worker, assignment *ateapi.ActorAssignment) error { if assignment.GetActor() == nil { markSkipped(ctx, "assignment names no actor") return nil @@ -224,7 +224,7 @@ func (w *WorkerWorkflow) releaseBoundActor(ctx context.Context, worker *ateapipb return nil } // If the actor is suspended, it's already been released. - if actor.GetStatus().GetState() == ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if actor.GetStatus().GetState() == ateapi.ActorState_ACTOR_STATE_SUSPENDED { markSkipped(ctx, "actor suspended cleanly before the pod went away") return nil } @@ -244,11 +244,11 @@ func (w *WorkerWorkflow) releaseBoundActor(ctx context.Context, worker *ateapipb // untouched. The Actor's assignment row in the worker is left for the caller to // release. // A concurrent write to the Actor fails this as ABORTED. -func (w *WorkerWorkflow) crashBoundActor(ctx context.Context, worker *ateapipb.Worker, actorRef resources.ActorRef, actor *ateapipb.Actor, logMsg, crashMsg string) error { +func (w *WorkerWorkflow) crashBoundActor(ctx context.Context, worker *ateapi.Worker, actorRef resources.ActorRef, actor *ateapi.Actor, logMsg, crashMsg string) error { // DELETING is final. A CRASHED actor can be reverted and resumed, and the // delete may already have collected its volumes and snapshots. The delete's // retry clears the actor's pointers. - if actor.GetStatus().GetState() == ateapipb.ActorState_ACTOR_STATE_DELETING { + if actor.GetStatus().GetState() == ateapi.ActorState_ACTOR_STATE_DELETING { markSkipped(ctx, "actor is DELETING") return nil } @@ -256,15 +256,15 @@ func (w *WorkerWorkflow) crashBoundActor(ctx context.Context, worker *ateapipb.W name := worker.GetMetadata().GetName() opName := ateattr.OperationUnknown switch actor.GetStatus().GetState() { - case ateapipb.ActorState_ACTOR_STATE_RESUMING: + case ateapi.ActorState_ACTOR_STATE_RESUMING: opName = ateattr.OperationResume - case ateapipb.ActorState_ACTOR_STATE_SUSPENDING: + case ateapi.ActorState_ACTOR_STATE_SUSPENDING: opName = ateattr.OperationSuspend - case ateapipb.ActorState_ACTOR_STATE_REVERTING: + case ateapi.ActorState_ACTOR_STATE_REVERTING: opName = ateattr.OperationRevert } - wasAlreadyCrashed := actor.GetStatus().GetState() == ateapipb.ActorState_ACTOR_STATE_CRASHED + wasAlreadyCrashed := actor.GetStatus().GetState() == ateapi.ActorState_ACTOR_STATE_CRASHED // Snapshot crash attributes before pod and pool pointers are cleared on actor. sandboxClass := actor.GetStatus().GetWorkerAssignment().GetSandboxRuntime().GetSandboxClass() @@ -273,8 +273,8 @@ func (w *WorkerWorkflow) crashBoundActor(ctx context.Context, worker *ateapipb.W slog.LogAttrs(ctx, slog.LevelInfo, logMsg, append(ateattr.ActorLogAttrs(resources.ActorAttributionFromActor(actor)), slog.String("worker", name))...) - _, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapipb.Actor) error { - toUpdate.Status.State = ateapipb.ActorState_ACTOR_STATE_CRASHED + _, err := w.store.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor), func(toUpdate *ateapi.Actor) error { + toUpdate.Status.State = ateapi.ActorState_ACTOR_STATE_CRASHED if !wasAlreadyCrashed { toUpdate.Status.Crash = newActorCrash(opName, crashMsg) } @@ -312,7 +312,7 @@ func (w *WorkerWorkflow) crashBoundActor(ctx context.Context, worker *ateapipb.W // on its assigned node. Each Terminate gets w.reclaimTimeout so a hung unmount, // such as against a dead NFS server, cannot run out the delete's own deadline // and fail the release after it. -func (w *WorkerWorkflow) reclaimActorStateOnNode(ctx context.Context, worker *ateapipb.Worker, actor *ateapipb.Actor) { +func (w *WorkerWorkflow) reclaimActorStateOnNode(ctx context.Context, worker *ateapi.Worker, actor *ateapi.Actor) { ctx, done := stepSpan(ctx, "ReclaimActorStateOnNode") defer func() { _ = done(nil) }() @@ -370,7 +370,7 @@ func (w *WorkerWorkflow) reclaimActorStateOnNode(ctx context.Context, worker *at // finalizeDeleted removes the worker from the store and returns the deleted // record. -func (w *WorkerWorkflow) finalizeDeleted(ctx context.Context, worker *ateapipb.Worker) (_ *ateapipb.Worker, err error) { +func (w *WorkerWorkflow) finalizeDeleted(ctx context.Context, worker *ateapi.Worker) (_ *ateapi.Worker, err error) { ctx, done := stepSpan(ctx, "FinalizeDeleted") defer func() { err = done(err) }() diff --git a/cmd/ateapi/internal/controlapi/workflow_worker_delete_test.go b/cmd/ateapi/internal/controlapi/workflow_worker_delete_test.go index 0f29a746af..aeed776291 100644 --- a/cmd/ateapi/internal/controlapi/workflow_worker_delete_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_worker_delete_test.go @@ -23,13 +23,13 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" @@ -52,21 +52,21 @@ var apiActorRef = resources.ActorRef{Atespace: "team-a", Name: "actor-1"} // shape the delete's release step acts on. Its coordinates line up with // validWorker and newAPIAssignment, so the two seeds agree about who is bound // to whom. -func seedAPIActor(t *testing.T, ctx context.Context, persistence store.Interface, state ateapipb.ActorState, opts ...func(*ateapipb.Actor)) *ateapipb.Actor { +func seedAPIActor(t *testing.T, ctx context.Context, persistence store.Interface, state ateapi.ActorState, opts ...func(*ateapi.Actor)) *ateapi.Actor { t.Helper() - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: apiActorRef.Atespace, Name: apiActorRef.Name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ate-system", Name: "tmpl"}, - Status: &ateapipb.ActorStatus{ + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: apiActorRef.Atespace, Name: apiActorRef.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "ate-system", Name: "tmpl"}, + Status: &ateapi.ActorStatus{ State: state, - WorkerAssignment: &ateapipb.WorkerAssignment{ + WorkerAssignment: &ateapi.WorkerAssignment{ Worker: workerRef(apiWorkerName), WorkerNamespace: "ate-system", WorkerPool: "pool-1", WorkerPod: "worker-pod-1", WorkerPodUid: apiWorkerName, WorkerPodIps: []string{"10.1.2.3"}, - SandboxRuntime: &ateapipb.ActorSandboxRuntime{SandboxClass: "gvisor"}, + SandboxRuntime: &ateapi.ActorSandboxRuntime{SandboxClass: "gvisor"}, }, }, } @@ -90,7 +90,7 @@ func TestDeleteWorkerWorkflow_DrainsBeforeSweeping(t *testing.T) { ctx := context.Background() _, persistence := newWorkerDeleteWorkflow(t) seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - actor := seedAPIActor(t, ctx, persistence, ateapipb.ActorState_ACTOR_STATE_RUNNING) + actor := seedAPIActor(t, ctx, persistence, ateapi.ActorState_ACTOR_STATE_RUNNING) assignAPIWorker(t, ctx, persistence, apiWorkerName, actor.GetMetadata().GetUid()) wf := NewWorkerWorkflow(failingUpdateActorStore{Interface: persistence, err: errors.New("release failed")}, newNodeAteletDialer(t, &capturingTerminator{})) @@ -102,7 +102,7 @@ func TestDeleteWorkerWorkflow_DrainsBeforeSweeping(t *testing.T) { if err != nil { t.Fatalf("GetWorker() failed: %v", err) } - if got.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_DRAINING { + if got.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_DRAINING { t.Errorf("worker state during the sweep = %v, want DRAINING so nothing new binds", got.GetStatus().GetState()) } @@ -112,11 +112,11 @@ func TestDeleteWorkerWorkflow_ReleasesBoundActor(t *testing.T) { ctx := context.Background() wf, persistence := newWorkerDeleteWorkflow(t) seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - actor := seedAPIActor(t, ctx, persistence, ateapipb.ActorState_ACTOR_STATE_RUNNING, func(a *ateapipb.Actor) { + actor := seedAPIActor(t, ctx, persistence, ateapi.ActorState_ACTOR_STATE_RUNNING, func(a *ateapi.Actor) { a.Status.LastAssignedGeneration = 2 - a.Status.Snapshots = []*ateapipb.Snapshot{ - newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "last", someActorSnapshotURI(t, testStorageLocation, apiActorRef.Atespace, "last"), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), - newInProgressSnapshot(t, 2, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "partial-snapshot"), + a.Status.Snapshots = []*ateapi.Snapshot{ + newDurableSnapshot(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "", "last", someActorSnapshotURI(t, testStorageLocation, apiActorRef.Atespace, "last"), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED), + newInProgressSnapshot(t, 2, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, "partial-snapshot"), } }) assignAPIWorker(t, ctx, persistence, apiWorkerName, actor.GetMetadata().GetUid()) @@ -129,7 +129,7 @@ func TestDeleteWorkerWorkflow_ReleasesBoundActor(t *testing.T) { if err != nil { t.Fatalf("GetActor() failed: %v", err) } - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("actor state = %v, want CRASHED: it never suspended cleanly", got.GetStatus().GetState()) } if msg := got.GetStatus().GetCrash().GetMessage(); msg != crashMessageWorkerPodGone { @@ -140,12 +140,12 @@ func TestDeleteWorkerWorkflow_ReleasesBoundActor(t *testing.T) { } // The in-progress checkpoint is kept: it names the prefix whatever atelet // already uploaded lives under, which delete or revert needs to collect it. - gotInProgressSnap := findLatestDurableSnapshot(got.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) + gotInProgressSnap := findLatestDurableSnapshot(got.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING) if want := someActorSnapshotURI(t, testStorageLocation, apiActorRef.Atespace, "partial-snapshot"); gotInProgressSnap.GetDurableSnapshot().GetObject().GetSnapshotUri() != want { t.Errorf("in-progress external checkpoint not preserved: %v", got.GetStatus()) } // The last completed snapshot is what makes the actor resumable, so it stays. - gotCompletedSnap := findLatestDurableSnapshot(got.GetStatus(), ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) + gotCompletedSnap := findLatestDurableSnapshot(got.GetStatus(), ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED) if want := someActorSnapshotURI(t, testStorageLocation, apiActorRef.Atespace, "last"); gotCompletedSnap.GetDurableSnapshot().GetObject().GetSnapshotUri() != want { t.Errorf("external snapshot = %q, want it preserved as %q", gotCompletedSnap.GetDurableSnapshot().GetObject().GetSnapshotUri(), want) } @@ -159,18 +159,18 @@ func TestDeleteWorkerWorkflow_ReleasesBoundActor(t *testing.T) { func TestDeleteWorkerWorkflow_ReleasedActorStateTransitions(t *testing.T) { tests := []struct { name string - start ateapipb.ActorState - wantState ateapipb.ActorState + start ateapi.ActorState + wantState ateapi.ActorState wantOp string wantMetric bool }{ - {name: "running becomes crashed", start: ateapipb.ActorState_ACTOR_STATE_RUNNING, wantState: ateapipb.ActorState_ACTOR_STATE_CRASHED, wantOp: ateattr.OperationUnknown, wantMetric: true}, - {name: "resuming becomes crashed", start: ateapipb.ActorState_ACTOR_STATE_RESUMING, wantState: ateapipb.ActorState_ACTOR_STATE_CRASHED, wantOp: ateattr.OperationResume, wantMetric: true}, - {name: "suspending becomes crashed", start: ateapipb.ActorState_ACTOR_STATE_SUSPENDING, wantState: ateapipb.ActorState_ACTOR_STATE_CRASHED, wantOp: ateattr.OperationSuspend, wantMetric: true}, - {name: "reverting becomes crashed", start: ateapipb.ActorState_ACTOR_STATE_REVERTING, wantState: ateapipb.ActorState_ACTOR_STATE_CRASHED, wantOp: ateattr.OperationRevert, wantMetric: true}, - {name: "deleting stays deleting", start: ateapipb.ActorState_ACTOR_STATE_DELETING, wantState: ateapipb.ActorState_ACTOR_STATE_DELETING, wantMetric: false}, - {name: "suspended stays suspended", start: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, wantState: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, wantMetric: false}, - {name: "crashed is not counted twice", start: ateapipb.ActorState_ACTOR_STATE_CRASHED, wantState: ateapipb.ActorState_ACTOR_STATE_CRASHED, wantMetric: false}, + {name: "running becomes crashed", start: ateapi.ActorState_ACTOR_STATE_RUNNING, wantState: ateapi.ActorState_ACTOR_STATE_CRASHED, wantOp: ateattr.OperationUnknown, wantMetric: true}, + {name: "resuming becomes crashed", start: ateapi.ActorState_ACTOR_STATE_RESUMING, wantState: ateapi.ActorState_ACTOR_STATE_CRASHED, wantOp: ateattr.OperationResume, wantMetric: true}, + {name: "suspending becomes crashed", start: ateapi.ActorState_ACTOR_STATE_SUSPENDING, wantState: ateapi.ActorState_ACTOR_STATE_CRASHED, wantOp: ateattr.OperationSuspend, wantMetric: true}, + {name: "reverting becomes crashed", start: ateapi.ActorState_ACTOR_STATE_REVERTING, wantState: ateapi.ActorState_ACTOR_STATE_CRASHED, wantOp: ateattr.OperationRevert, wantMetric: true}, + {name: "deleting stays deleting", start: ateapi.ActorState_ACTOR_STATE_DELETING, wantState: ateapi.ActorState_ACTOR_STATE_DELETING, wantMetric: false}, + {name: "suspended stays suspended", start: ateapi.ActorState_ACTOR_STATE_SUSPENDED, wantState: ateapi.ActorState_ACTOR_STATE_SUSPENDED, wantMetric: false}, + {name: "crashed is not counted twice", start: ateapi.ActorState_ACTOR_STATE_CRASHED, wantState: ateapi.ActorState_ACTOR_STATE_CRASHED, wantMetric: false}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { @@ -196,7 +196,7 @@ func TestDeleteWorkerWorkflow_ReleasedActorStateTransitions(t *testing.T) { if got.GetStatus().GetState() != tc.wantState { t.Errorf("actor state = %v, want %v", got.GetStatus().GetState(), tc.wantState) } - if tc.wantState == ateapipb.ActorState_ACTOR_STATE_CRASHED && got.GetStatus().GetWorkerAssignment() != nil { + if tc.wantState == ateapi.ActorState_ACTOR_STATE_CRASHED && got.GetStatus().GetWorkerAssignment() != nil { t.Errorf("crashed actor worker assignment = %v, want it cleared", got.GetStatus().GetWorkerAssignment()) } if tc.wantMetric { @@ -215,7 +215,7 @@ func TestDeleteWorkerWorkflow_IgnoresStaleIncarnationAssignment(t *testing.T) { ctx := context.Background() wf, persistence := newWorkerDeleteWorkflow(t) seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - seedAPIActor(t, ctx, persistence, ateapipb.ActorState_ACTOR_STATE_RUNNING) + seedAPIActor(t, ctx, persistence, ateapi.ActorState_ACTOR_STATE_RUNNING) assignAPIWorker(t, ctx, persistence, apiWorkerName, "old-incarnation-uid") if _, err := wf.DeleteWorker(ctx, apiWorkerName, store.DeletePreconditions{}); err != nil { @@ -226,7 +226,7 @@ func TestDeleteWorkerWorkflow_IgnoresStaleIncarnationAssignment(t *testing.T) { if err != nil { t.Fatalf("GetActor() failed: %v", err) } - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("actor state = %v, want RUNNING: the dead worker was bound to a different incarnation", got.GetStatus().GetState()) } } @@ -237,7 +237,7 @@ func TestDeleteWorkerWorkflow_IgnoresActorMovedElsewhere(t *testing.T) { ctx := context.Background() wf, persistence := newWorkerDeleteWorkflow(t) seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - actor := seedAPIActor(t, ctx, persistence, ateapipb.ActorState_ACTOR_STATE_RUNNING, func(a *ateapipb.Actor) { + actor := seedAPIActor(t, ctx, persistence, ateapi.ActorState_ACTOR_STATE_RUNNING, func(a *ateapi.Actor) { a.Status.WorkerAssignment.Worker = workerRef(apiOtherWorkerName) }) assignAPIWorker(t, ctx, persistence, apiWorkerName, actor.GetMetadata().GetUid()) @@ -250,7 +250,7 @@ func TestDeleteWorkerWorkflow_IgnoresActorMovedElsewhere(t *testing.T) { if err != nil { t.Fatalf("GetActor() failed: %v", err) } - if got.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("actor state = %v, want RUNNING: it is running on another worker", got.GetStatus().GetState()) } if got.GetStatus().GetWorkerAssignment().GetWorker().GetName() != apiOtherWorkerName { @@ -285,7 +285,7 @@ func TestDeleteWorkerWorkflow_FailedReleaseKeepsWorker(t *testing.T) { name string updateErr error wantCode codes.Code - wantActor ateapipb.ActorState + wantActor ateapi.ActorState wantWorker bool }{ { @@ -294,7 +294,7 @@ func TestDeleteWorkerWorkflow_FailedReleaseKeepsWorker(t *testing.T) { name: "store unavailable", updateErr: errors.New("store is down"), wantCode: codes.Internal, - wantActor: ateapipb.ActorState_ACTOR_STATE_RUNNING, + wantActor: ateapi.ActorState_ACTOR_STATE_RUNNING, wantWorker: true, }, { @@ -303,7 +303,7 @@ func TestDeleteWorkerWorkflow_FailedReleaseKeepsWorker(t *testing.T) { name: "lost the version guard", updateErr: store.ErrVersionConflict, wantCode: codes.Aborted, - wantActor: ateapipb.ActorState_ACTOR_STATE_RUNNING, + wantActor: ateapi.ActorState_ACTOR_STATE_RUNNING, wantWorker: true, }, } @@ -312,7 +312,7 @@ func TestDeleteWorkerWorkflow_FailedReleaseKeepsWorker(t *testing.T) { ctx := context.Background() _, persistence := newWorkerDeleteWorkflow(t) seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - actor := seedAPIActor(t, ctx, persistence, ateapipb.ActorState_ACTOR_STATE_RUNNING) + actor := seedAPIActor(t, ctx, persistence, ateapi.ActorState_ACTOR_STATE_RUNNING) assignAPIWorker(t, ctx, persistence, apiWorkerName, actor.GetMetadata().GetUid()) wf := NewWorkerWorkflow(failingUpdateActorStore{Interface: persistence, err: tc.updateErr}, newNodeAteletDialer(t, &capturingTerminator{})) @@ -359,7 +359,7 @@ func TestDeleteWorkerWorkflow_ActorDeletedDuringRelease(t *testing.T) { ctx := context.Background() _, persistence := newWorkerDeleteWorkflow(t) seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - actor := seedAPIActor(t, ctx, persistence, ateapipb.ActorState_ACTOR_STATE_RUNNING) + actor := seedAPIActor(t, ctx, persistence, ateapi.ActorState_ACTOR_STATE_RUNNING) assignAPIWorker(t, ctx, persistence, apiWorkerName, actor.GetMetadata().GetUid()) wf := NewWorkerWorkflow(failingUpdateActorStore{Interface: persistence, err: store.ErrNotFound}, newNodeAteletDialer(t, &capturingTerminator{})) @@ -395,7 +395,7 @@ type failingUpdateActorStore struct { err error } -func (f failingUpdateActorStore) UpdateActor(context.Context, resources.ActorRef, store.Precondition, func(*ateapipb.Actor) error) (*ateapipb.Actor, error) { +func (f failingUpdateActorStore) UpdateActor(context.Context, resources.ActorRef, store.Precondition, func(*ateapi.Actor) error) (*ateapi.Actor, error) { return nil, f.err } @@ -403,11 +403,11 @@ func TestDeleteWorkerWorkflow_DrainedWorkerIsStillAdmitted(t *testing.T) { ctx := context.Background() wf, persistence := newWorkerDeleteWorkflow(t) worker := seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - drained, err := persistence.UpdateWorker(ctx, apiWorkerName, store.PreconditionFrom(worker), func(toUpdate *ateapipb.Worker) error { + drained, err := persistence.UpdateWorker(ctx, apiWorkerName, store.PreconditionFrom(worker), func(toUpdate *ateapi.Worker) error { if toUpdate.Status == nil { - toUpdate.Status = &ateapipb.WorkerStatus{} + toUpdate.Status = &ateapi.WorkerStatus{} } - toUpdate.Status.State = ateapipb.WorkerState_WORKER_STATE_DRAINING + toUpdate.Status.State = ateapi.WorkerState_WORKER_STATE_DRAINING return nil }) if err != nil { @@ -433,16 +433,16 @@ func TestDeleteWorkerWorkflow_ReclaimsActorNodeState(t *testing.T) { tests := []struct { name string // state the actor is in when its pod disappears. - state ateapipb.ActorState + state ateapi.ActorState // seed further shapes the stored actor. - seed func(*ateapipb.Actor) + seed func(*ateapi.Actor) // terminateErr is what the atelet answers, if anything. terminateErr error wantTerminate bool }{ { name: "running actor is reclaimed", - state: ateapipb.ActorState_ACTOR_STATE_RUNNING, + state: ateapi.ActorState_ACTOR_STATE_RUNNING, wantTerminate: true, }, { @@ -450,7 +450,7 @@ func TestDeleteWorkerWorkflow_ReclaimsActorNodeState(t *testing.T) { // snapshot while running. When its worker pod vanishes, it crashes // and its node state is reclaimed along with any local snapshot. name: "running actor with a local snapshot is reclaimed", - state: ateapipb.ActorState_ACTOR_STATE_RUNNING, + state: ateapi.ActorState_ACTOR_STATE_RUNNING, seed: withPausedShape(t, "node-1"), wantTerminate: true, }, @@ -458,7 +458,7 @@ func TestDeleteWorkerWorkflow_ReclaimsActorNodeState(t *testing.T) { // A cleanly suspended actor already ran Checkpoint's teardown, // volume unmount, and resetActorDirs, and stays resumable. name: "cleanly suspended actor is left alone", - state: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + state: ateapi.ActorState_ACTOR_STATE_SUSPENDED, wantTerminate: false, }, { @@ -466,7 +466,7 @@ func TestDeleteWorkerWorkflow_ReclaimsActorNodeState(t *testing.T) { // the worker still goes, and the actor's revert or delete collects // what this could not. name: "a failing terminate does not fail the delete", - state: ateapipb.ActorState_ACTOR_STATE_RUNNING, + state: ateapi.ActorState_ACTOR_STATE_RUNNING, terminateErr: apierror.Internal("atelet is having a bad day"), wantTerminate: true, }, @@ -482,7 +482,7 @@ func TestDeleteWorkerWorkflow_ReclaimsActorNodeState(t *testing.T) { wf := NewWorkerWorkflow(persistence, newNodeAteletDialer(t, atelet)) seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - seeds := []func(*ateapipb.Actor){} + seeds := []func(*ateapi.Actor){} if tt.seed != nil { seeds = append(seeds, tt.seed) } @@ -533,7 +533,7 @@ func TestDeleteWorkerWorkflow_ReleasesUnderTheActorLease(t *testing.T) { wf := NewWorkerWorkflow(persistence, newNodeAteletDialer(t, atelet)) seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) - actor := seedAPIActor(t, ctx, persistence, ateapipb.ActorState_ACTOR_STATE_SUSPENDING, func(a *ateapipb.Actor) { + actor := seedAPIActor(t, ctx, persistence, ateapi.ActorState_ACTOR_STATE_SUSPENDING, func(a *ateapi.Actor) { withPauseInProgress(t)(a) a.Status.AssignedNode = "node-1" }) @@ -551,7 +551,7 @@ func TestDeleteWorkerWorkflow_ReleasesUnderTheActorLease(t *testing.T) { t.Errorf("DeleteWorker() with the actor's lease held = %v, want ABORTED", err) } held := mustGetActor(t, ctx, persistence) - if got := held.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDING { + if got := held.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDING { t.Errorf("actor state = %v, want SUSPENDING while its lease is held", got) } if got := held.GetStatus().GetWorkerAssignment().GetWorker().GetName(); got != apiWorkerName { @@ -568,7 +568,7 @@ func TestDeleteWorkerWorkflow_ReleasesUnderTheActorLease(t *testing.T) { if got := atelet.requests(); len(got) != 1 { t.Errorf("atelet received %d Terminate calls once the lease was free, want 1", len(got)) } - if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_CRASHED { + if got := mustGetActor(t, ctx, persistence).GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_CRASHED { t.Errorf("actor state = %v, want CRASHED once the lease is free", got) } } @@ -588,12 +588,12 @@ func TestDeleteWorkerWorkflow_BusyActorDoesNotHoldUpOthers(t *testing.T) { var refs []resources.ActorRef var uids []string for _, name := range []string{"busy", "free"} { - actor := seedAPIActor(t, ctx, persistence, ateapipb.ActorState_ACTOR_STATE_RUNNING, func(a *ateapipb.Actor) { + actor := seedAPIActor(t, ctx, persistence, ateapi.ActorState_ACTOR_STATE_RUNNING, func(a *ateapi.Actor) { a.Metadata.Name = name }) ref := resources.ActorRefFromActor(actor) - if err := persistence.BindActorToWorker(ctx, apiWorkerName, &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: ref.Atespace, Name: ref.Name}, + if err := persistence.BindActorToWorker(ctx, apiWorkerName, &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: ref.Atespace, Name: ref.Name}, ActorUid: actor.GetMetadata().GetUid(), }, nil); err != nil { t.Fatalf("assigning %s to worker %s: %v", ref, apiWorkerName, err) @@ -615,7 +615,7 @@ func TestDeleteWorkerWorkflow_BusyActorDoesNotHoldUpOthers(t *testing.T) { if len(got) != 1 || got[0].GetActorUid() != uids[1] { t.Errorf("atelet received %v, want exactly one Terminate, for the free actor %s", got, uids[1]) } - for i, want := range []ateapipb.ActorState{ateapipb.ActorState_ACTOR_STATE_RUNNING, ateapipb.ActorState_ACTOR_STATE_CRASHED} { + for i, want := range []ateapi.ActorState{ateapi.ActorState_ACTOR_STATE_RUNNING, ateapi.ActorState_ACTOR_STATE_CRASHED} { actor, err := persistence.GetActor(ctx, refs[i]) if err != nil { t.Fatalf("GetActor(%s) failed: %v", refs[i], err) @@ -653,14 +653,14 @@ func TestDeleteWorkerWorkflow_HungReclaimDoesNotWedgeDelete(t *testing.T) { wf.now = func() time.Time { return now } bindRunningActor := func(workerName, actorName string) resources.ActorRef { - actor := seedAPIActor(t, ctx, persistence, ateapipb.ActorState_ACTOR_STATE_RUNNING, func(a *ateapipb.Actor) { + actor := seedAPIActor(t, ctx, persistence, ateapi.ActorState_ACTOR_STATE_RUNNING, func(a *ateapi.Actor) { a.Metadata.Name = actorName a.Status.WorkerAssignment.Worker = workerRef(workerName) a.Status.WorkerAssignment.WorkerPodUid = workerName }) ref := resources.ActorRefFromActor(actor) - if err := persistence.BindActorToWorker(ctx, workerName, &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: ref.Atespace, Name: ref.Name}, + if err := persistence.BindActorToWorker(ctx, workerName, &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: ref.Atespace, Name: ref.Name}, ActorUid: actor.GetMetadata().GetUid(), }, nil); err != nil { t.Fatalf("assigning %s to worker %s: %v", ref, workerName, err) diff --git a/cmd/ateapi/internal/controlapi/workload_spec.go b/cmd/ateapi/internal/controlapi/workload_spec.go index 3aa46b8966..41eac2a4a4 100644 --- a/cmd/ateapi/internal/controlapi/workload_spec.go +++ b/cmd/ateapi/internal/controlapi/workload_spec.go @@ -17,14 +17,14 @@ package controlapi import ( "fmt" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/proto/ateletpb" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // toAteletResources copies declared limits into atelet's form. Returns nil // when no limits are declared, so the OCI spec stays untouched for templates // that do not use them. -func toAteletResources(r *ateapipb.ResourceRequirements) *ateletpb.ResourceRequirements { +func toAteletResources(r *ateapi.ResourceRequirements) *ateletpb.ResourceRequirements { l := r.GetLimits() if l.GetMemoryBytes() == 0 && l.GetCpuMillicores() == 0 { return nil @@ -34,7 +34,7 @@ func toAteletResources(r *ateapipb.ResourceRequirements) *ateletpb.ResourceRequi // workloadSpecFromActorTemplate builds a WorkloadSpec from the template; // container env is copied verbatim. -func workloadSpecFromActorTemplate(actorTemplate *ateapipb.ActorTemplate, actor *ateapipb.Actor, volumePublishContexts map[string]map[string]string) (*ateletpb.WorkloadSpec, error) { +func workloadSpecFromActorTemplate(actorTemplate *ateapi.ActorTemplate, actor *ateapi.Actor, volumePublishContexts map[string]map[string]string) (*ateletpb.WorkloadSpec, error) { workloadSpec := &ateletpb.WorkloadSpec{} // Convert volumes to atelet's representation. ActorTemplate validation has @@ -134,7 +134,7 @@ func workloadSpecFromActorTemplate(actorTemplate *ateapipb.ActorTemplate, actor // and appends them to workloadSpec if they are referenced in container // volumeMounts. volumePublishContexts carries the attachment metadata of the current // resume by volume name; it is nil on paths that do not mount. -func appendExternalVolumes(workloadSpec *ateletpb.WorkloadSpec, template *ateapipb.ActorTemplate, actor *ateapipb.Actor, volumePublishContexts map[string]map[string]string) error { +func appendExternalVolumes(workloadSpec *ateletpb.WorkloadSpec, template *ateapi.ActorTemplate, actor *ateapi.Actor, volumePublishContexts map[string]map[string]string) error { if template == nil { return nil } @@ -175,7 +175,7 @@ func appendExternalVolumes(workloadSpec *ateletpb.WorkloadSpec, template *ateapi return nil } -func isVolumeMounted(volumeName string, template *ateapipb.ActorTemplate) bool { +func isVolumeMounted(volumeName string, template *ateapi.ActorTemplate) bool { for _, ctr := range template.GetContainers() { for _, mount := range ctr.GetVolumeMounts() { if mount.GetName() == volumeName { @@ -189,13 +189,13 @@ func isVolumeMounted(volumeName string, template *ateapipb.ActorTemplate) bool { // toAteletActorMetadataField projects the template field selector onto the // atelet wire enum. Unknown values map to UNSPECIFIED, which atelet skips; // template validation makes that unreachable for stored templates. -func toAteletActorMetadataField(in ateapipb.ActorMetadataField) ateletpb.ActorMetadataField { +func toAteletActorMetadataField(in ateapi.ActorMetadataField) ateletpb.ActorMetadataField { switch in { - case ateapipb.ActorMetadataField_ACTOR_METADATA_FIELD_NAME: + case ateapi.ActorMetadataField_ACTOR_METADATA_FIELD_NAME: return ateletpb.ActorMetadataField_ACTOR_METADATA_FIELD_NAME - case ateapipb.ActorMetadataField_ACTOR_METADATA_FIELD_ATESPACE: + case ateapi.ActorMetadataField_ACTOR_METADATA_FIELD_ATESPACE: return ateletpb.ActorMetadataField_ACTOR_METADATA_FIELD_ATESPACE - case ateapipb.ActorMetadataField_ACTOR_METADATA_FIELD_UID: + case ateapi.ActorMetadataField_ACTOR_METADATA_FIELD_UID: return ateletpb.ActorMetadataField_ACTOR_METADATA_FIELD_UID default: return ateletpb.ActorMetadataField_ACTOR_METADATA_FIELD_UNSPECIFIED @@ -205,7 +205,7 @@ func toAteletActorMetadataField(in ateapipb.ActorMetadataField) ateletpb.ActorMe // toAteletWakeupProbe projects the template wakeup probe field onto the ateletpb wire // type. Returns nil when the source is nil so containers without a probe // stay unchanged on the wire. -func toAteletWakeupProbe(in *ateapipb.WakeupProbe) *ateletpb.WakeupProbe { +func toAteletWakeupProbe(in *ateapi.WakeupProbe) *ateletpb.WakeupProbe { if in == nil { return nil } @@ -222,7 +222,7 @@ func toAteletWakeupProbe(in *ateapipb.WakeupProbe) *ateletpb.WakeupProbe { // toAteletSecurityContext projects the template securityContext onto the // ateletpb wire type. Returns nil when the source is nil or carries nothing, // so containers that set no security settings stay unchanged on the wire. -func toAteletSecurityContext(in *ateapipb.SecurityContext) *ateletpb.SecurityContext { +func toAteletSecurityContext(in *ateapi.SecurityContext) *ateletpb.SecurityContext { caps := in.GetCapabilities() if caps == nil || (len(caps.GetAdd()) == 0 && len(caps.GetDrop()) == 0) { return nil diff --git a/cmd/ateapi/internal/controlapi/workload_spec_test.go b/cmd/ateapi/internal/controlapi/workload_spec_test.go index 0b085a0e5a..7749db8973 100644 --- a/cmd/ateapi/internal/controlapi/workload_spec_test.go +++ b/cmd/ateapi/internal/controlapi/workload_spec_test.go @@ -18,29 +18,29 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/proto/ateletpb" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/testing/protocmp" ) func TestWorkloadSpecFromActorTemplate(t *testing.T) { tests := []struct { name string - template *ateapipb.ActorTemplate + template *ateapi.ActorTemplate want *ateletpb.WorkloadSpec }{ { name: "converts DurableDir volume and mounts", - template: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, - Volumes: []*ateapipb.Volume{ - {Name: "home", DurableDir: &ateapipb.DurableDirVolumeSource{}}, + template: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, + Volumes: []*ateapi.Volume{ + {Name: "home", DurableDir: &ateapi.DurableDirVolumeSource{}}, }, - Containers: []*ateapipb.Container{ + Containers: []*ateapi.Container{ { Name: "main", Image: "main", - VolumeMounts: []*ateapipb.VolumeMount{ + VolumeMounts: []*ateapi.VolumeMount{ {Name: "home", MountPath: "/home/user"}, {Name: "home", MountPath: "/workspace"}, }, @@ -68,29 +68,29 @@ func TestWorkloadSpecFromActorTemplate(t *testing.T) { }, { name: "converts SystemInfo volume with actorMetadata items", - template: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, - Volumes: []*ateapipb.Volume{ + template: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, + Volumes: []*ateapi.Volume{ { Name: "system-info", - SystemInfo: &ateapipb.SystemInfoVolumeSource{ - DataSources: []*ateapipb.SystemInfoDataSource{ - {ActorMetadata: &ateapipb.ActorMetadataDataSource{ - Items: []*ateapipb.ActorMetadataItem{ - {Field: ateapipb.ActorMetadataField_ACTOR_METADATA_FIELD_NAME, Path: "actor-name"}, - {Field: ateapipb.ActorMetadataField_ACTOR_METADATA_FIELD_ATESPACE, Path: "atespace"}, - {Field: ateapipb.ActorMetadataField_ACTOR_METADATA_FIELD_UID, Path: "identity/actor-uid"}, + SystemInfo: &ateapi.SystemInfoVolumeSource{ + DataSources: []*ateapi.SystemInfoDataSource{ + {ActorMetadata: &ateapi.ActorMetadataDataSource{ + Items: []*ateapi.ActorMetadataItem{ + {Field: ateapi.ActorMetadataField_ACTOR_METADATA_FIELD_NAME, Path: "actor-name"}, + {Field: ateapi.ActorMetadataField_ACTOR_METADATA_FIELD_ATESPACE, Path: "atespace"}, + {Field: ateapi.ActorMetadataField_ACTOR_METADATA_FIELD_UID, Path: "identity/actor-uid"}, }, }}, }, }, }, }, - Containers: []*ateapipb.Container{ + Containers: []*ateapi.Container{ { Name: "main", Image: "main", - VolumeMounts: []*ateapipb.VolumeMount{ + VolumeMounts: []*ateapi.VolumeMount{ {Name: "system-info", MountPath: "/run/ate"}, }, }, @@ -126,17 +126,17 @@ func TestWorkloadSpecFromActorTemplate(t *testing.T) { }, { name: "converts Image volume and mounts", - template: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, - Volumes: []*ateapipb.Volume{ - {Name: "home", DurableDir: &ateapipb.DurableDirVolumeSource{}}, - {Name: "agent", Image: &ateapipb.ImageVolumeSource{Reference: "example.com/agent@sha256:abc"}}, + template: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, + Volumes: []*ateapi.Volume{ + {Name: "home", DurableDir: &ateapi.DurableDirVolumeSource{}}, + {Name: "agent", Image: &ateapi.ImageVolumeSource{Reference: "example.com/agent@sha256:abc"}}, }, - Containers: []*ateapipb.Container{ + Containers: []*ateapi.Container{ { Name: "main", Image: "main", - VolumeMounts: []*ateapipb.VolumeMount{ + VolumeMounts: []*ateapi.VolumeMount{ {Name: "home", MountPath: "/home/user"}, {Name: "agent", MountPath: "/ate"}, }, @@ -168,23 +168,23 @@ func TestWorkloadSpecFromActorTemplate(t *testing.T) { }, { name: "converts trustBundle data sources carrying the name for node-side resolution", - template: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, - Volumes: []*ateapipb.Volume{ + template: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, + Volumes: []*ateapi.Volume{ { Name: "system-info", - SystemInfo: &ateapipb.SystemInfoVolumeSource{ - DataSources: []*ateapipb.SystemInfoDataSource{ - {TrustBundle: &ateapipb.TrustBundleDataSource{Names: []string{"egress-trust"}, Path: "trust/ca.pem"}}, + SystemInfo: &ateapi.SystemInfoVolumeSource{ + DataSources: []*ateapi.SystemInfoDataSource{ + {TrustBundle: &ateapi.TrustBundleDataSource{Names: []string{"egress-trust"}, Path: "trust/ca.pem"}}, }, }, }, }, - Containers: []*ateapipb.Container{ + Containers: []*ateapi.Container{ { Name: "main", Image: "main", - VolumeMounts: []*ateapipb.VolumeMount{ + VolumeMounts: []*ateapi.VolumeMount{ {Name: "system-info", MountPath: "/run/substrate/certs"}, }, }, @@ -216,17 +216,17 @@ func TestWorkloadSpecFromActorTemplate(t *testing.T) { }, { name: "skips non-DurableDir volumes", - template: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, - Volumes: []*ateapipb.Volume{ + template: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, + Volumes: []*ateapi.Volume{ {Name: "unsupported"}, - {Name: "home", DurableDir: &ateapipb.DurableDirVolumeSource{}}, + {Name: "home", DurableDir: &ateapi.DurableDirVolumeSource{}}, }, - Containers: []*ateapipb.Container{ + Containers: []*ateapi.Container{ { Name: "main", Image: "main", - VolumeMounts: []*ateapipb.VolumeMount{ + VolumeMounts: []*ateapi.VolumeMount{ {Name: "home", MountPath: "/workspace"}, }, }, @@ -252,12 +252,12 @@ func TestWorkloadSpecFromActorTemplate(t *testing.T) { }, { name: "container without volume mounts has none", - template: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, - Volumes: []*ateapipb.Volume{ - {Name: "home", DurableDir: &ateapipb.DurableDirVolumeSource{}}, + template: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, + Volumes: []*ateapi.Volume{ + {Name: "home", DurableDir: &ateapi.DurableDirVolumeSource{}}, }, - Containers: []*ateapipb.Container{ + Containers: []*ateapi.Container{ {Name: "main", Image: "main"}, }, }, @@ -273,13 +273,13 @@ func TestWorkloadSpecFromActorTemplate(t *testing.T) { }, { name: "maps literal env", - template: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, - Containers: []*ateapipb.Container{ + template: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, + Containers: []*ateapi.Container{ { Name: "main", Image: "main", - Env: []*ateapipb.EnvVar{ + Env: []*ateapi.EnvVar{ {Name: "LITERAL", Value: "plain"}, {Name: "EMPTY", Value: ""}, }, @@ -299,9 +299,9 @@ func TestWorkloadSpecFromActorTemplate(t *testing.T) { }, { name: "maps command and args", - template: &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, - Containers: []*ateapipb.Container{ + template: &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, + Containers: []*ateapi.Container{ { Name: "main", Image: "main", @@ -335,14 +335,14 @@ func TestWorkloadSpecFromActorTemplate(t *testing.T) { } func TestWorkloadSpecFromActorTemplatePropagatesWakeupProbe(t *testing.T) { - got, err := workloadSpecFromActorTemplate(&ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl-wakeup-probe"}, - Containers: []*ateapipb.Container{ + got, err := workloadSpecFromActorTemplate(&ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl-wakeup-probe"}, + Containers: []*ateapi.Container{ { Name: "with-probe", Image: "main", - WakeupProbe: &ateapipb.WakeupProbe{ - HttpGet: &ateapipb.HttpGetAction{Path: "/health", Port: 8080}, + WakeupProbe: &ateapi.WakeupProbe{ + HttpGet: &ateapi.HttpGetAction{Path: "/health", Port: 8080}, TimeoutSeconds: 45, }, }, @@ -378,42 +378,42 @@ func TestWorkloadSpecFromActorTemplatePropagatesWakeupProbe(t *testing.T) { } func TestAppendExternalVolumes(t *testing.T) { - template := &ateapipb.ActorTemplate{ - Containers: []*ateapipb.Container{ + template := &ateapi.ActorTemplate{ + Containers: []*ateapi.Container{ { Name: "main", - VolumeMounts: []*ateapipb.VolumeMount{ + VolumeMounts: []*ateapi.VolumeMount{ {Name: "vol-1", MountPath: "/mnt/vol1"}, }, }, }, - Volumes: []*ateapipb.Volume{ + Volumes: []*ateapi.Volume{ { Name: "vol-1", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "pd-standard", }}, }, { Name: "vol-2", - DurableDir: &ateapipb.DurableDirVolumeSource{}, + DurableDir: &ateapi.DurableDirVolumeSource{}, }, { Name: "unmounted-vol", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ StorageClassName: "pd-standard", }}, }, }, } - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "space-abc", Name: "actor-123", }, - Status: &ateapipb.ActorStatus{ - ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{ + Status: &ateapi.ActorStatus{ + ExternalVolumes: &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{ { Name: "vol-1", StorageVolumeId: "vol-gce-pd-123", @@ -465,12 +465,12 @@ func TestAppendExternalVolumes(t *testing.T) { } // Test missing mounted volume returns an error - missingActor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ + missingActor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "space-abc", Name: "actor-123", }, - Status: &ateapipb.ActorStatus{ExternalVolumes: &ateapipb.ExternalVolumes{Volumes: []*ateapipb.ExternalVolumeStatus{}}}, + Status: &ateapi.ActorStatus{ExternalVolumes: &ateapi.ExternalVolumes{Volumes: []*ateapi.ExternalVolumeStatus{}}}, } if err := appendExternalVolumes(&ateletpb.WorkloadSpec{}, template, missingActor, nil); err == nil { t.Errorf("appendExternalVolumes expected error for missing volume, got nil") @@ -478,14 +478,14 @@ func TestAppendExternalVolumes(t *testing.T) { } func TestWorkloadSpecFromActorTemplatePropagatesSecurityContext(t *testing.T) { - got, err := workloadSpecFromActorTemplate(&ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl-caps"}, - Containers: []*ateapipb.Container{ + got, err := workloadSpecFromActorTemplate(&ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl-caps"}, + Containers: []*ateapi.Container{ { Name: "adjusted", Image: "main", - SecurityContext: &ateapipb.SecurityContext{ - Capabilities: &ateapipb.Capabilities{ + SecurityContext: &ateapi.SecurityContext{ + Capabilities: &ateapi.Capabilities{ Add: []string{"NET_ADMIN"}, Drop: []string{"ALL"}, }, @@ -500,7 +500,7 @@ func TestWorkloadSpecFromActorTemplatePropagatesSecurityContext(t *testing.T) { // nothing is put on the wire for it. Name: "empty", Image: "third", - SecurityContext: &ateapipb.SecurityContext{Capabilities: &ateapipb.Capabilities{}}, + SecurityContext: &ateapi.SecurityContext{Capabilities: &ateapi.Capabilities{}}, }, }, }, nil, nil) @@ -538,7 +538,7 @@ func TestWorkloadSpecFromActorTemplatePropagatesSecurityContext(t *testing.T) { func TestToAteletResources(t *testing.T) { tests := []struct { name string - in *ateapipb.ResourceRequirements + in *ateapi.ResourceRequirements want *ateletpb.ResourceRequirements }{{ name: "nil resources", @@ -546,19 +546,19 @@ func TestToAteletResources(t *testing.T) { want: nil, }, { name: "empty resources", - in: &ateapipb.ResourceRequirements{}, + in: &ateapi.ResourceRequirements{}, want: nil, }, { name: "memory only", - in: &ateapipb.ResourceRequirements{Limits: &ateapipb.Resources{MemoryBytes: 256 << 20}}, + in: &ateapi.ResourceRequirements{Limits: &ateapi.Resources{MemoryBytes: 256 << 20}}, want: &ateletpb.ResourceRequirements{Limits: &ateletpb.Resources{MemoryBytes: 268435456}}, }, { name: "cpu only", - in: &ateapipb.ResourceRequirements{Limits: &ateapipb.Resources{CpuMillicores: 200}}, + in: &ateapi.ResourceRequirements{Limits: &ateapi.Resources{CpuMillicores: 200}}, want: &ateletpb.ResourceRequirements{Limits: &ateletpb.Resources{CpuMillicores: 200}}, }, { name: "both", - in: &ateapipb.ResourceRequirements{Limits: &ateapipb.Resources{CpuMillicores: 1000, MemoryBytes: 1 << 30}}, + in: &ateapi.ResourceRequirements{Limits: &ateapi.Resources{CpuMillicores: 1000, MemoryBytes: 1 << 30}}, want: &ateletpb.ResourceRequirements{Limits: &ateletpb.Resources{MemoryBytes: 1073741824, CpuMillicores: 1000}}, }} @@ -583,13 +583,13 @@ func TestToAteletResources(t *testing.T) { // literal leaves every test in the repository green while limits never leave // ate-api-server. func TestWorkloadSpecFromActorTemplatePropagatesResources(t *testing.T) { - got, err := workloadSpecFromActorTemplate(&ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl-limits"}, - Containers: []*ateapipb.Container{ + got, err := workloadSpecFromActorTemplate(&ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl-limits"}, + Containers: []*ateapi.Container{ { Name: "limited", Image: "main", - Resources: &ateapipb.ResourceRequirements{Limits: &ateapipb.Resources{CpuMillicores: 200, MemoryBytes: 256 << 20}}, + Resources: &ateapi.ResourceRequirements{Limits: &ateapi.Resources{CpuMillicores: 200, MemoryBytes: 256 << 20}}, }, {Name: "unlimited", Image: "main"}, }, diff --git a/cmd/ateapi/internal/defaults/defaults.go b/cmd/ateapi/internal/defaults/defaults.go index 59b09648b6..2ed3a32690 100644 --- a/cmd/ateapi/internal/defaults/defaults.go +++ b/cmd/ateapi/internal/defaults/defaults.go @@ -21,39 +21,39 @@ package defaults import ( "fmt" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/protobuf/proto" ) // Apply set default values to Substrate resource proto messages. func Apply(m proto.Message) { switch v := m.(type) { - case *ateapipb.AccessPolicy: + case *ateapi.AccessPolicy: applyAccessPolicyDefaults(v) - case *ateapipb.Actor: + case *ateapi.Actor: applyActorDefaults(v) - case *ateapipb.ActorTemplate: + case *ateapi.ActorTemplate: applyActorTemplateDefaults(v) - case *ateapipb.Atespace: + case *ateapi.Atespace: applyAtespaceDefaults(v) - case *ateapipb.EgressPolicy: + case *ateapi.EgressPolicy: applyEgressPolicyDefaults(v) - case *ateapipb.Tag: + case *ateapi.Tag: applyTagDefaults(v) - case *ateapipb.Worker: + case *ateapi.Worker: applyWorkerDefaults(v) default: panic(fmt.Sprintf("unknown resource message %T", m)) } } -func applyActorTemplateDefaults(t *ateapipb.ActorTemplate) { +func applyActorTemplateDefaults(t *ateapi.ActorTemplate) { if t == nil { return } // snapshot_config is optional; an omitted one takes every default. if t.SnapshotConfig == nil { - t.SnapshotConfig = &ateapipb.SnapshotConfig{} + t.SnapshotConfig = &ateapi.SnapshotConfig{} } applySnapshotConfigDefaults(t.SnapshotConfig) applyEgressRuleDefaults(t.GetGoldenEgressPolicy().GetRules()) @@ -62,22 +62,22 @@ func applyActorTemplateDefaults(t *ateapipb.ActorTemplate) { } } -func applySnapshotConfigDefaults(sc *ateapipb.SnapshotConfig) { +func applySnapshotConfigDefaults(sc *ateapi.SnapshotConfig) { if sc == nil { return } - if sc.PreferredFidelity == ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED { - sc.PreferredFidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + if sc.PreferredFidelity == ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED { + sc.PreferredFidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY } if sc.GoldenSnapshotConfig == nil { - sc.GoldenSnapshotConfig = &ateapipb.GoldenSnapshotConfig{} + sc.GoldenSnapshotConfig = &ateapi.GoldenSnapshotConfig{} } - if sc.GoldenSnapshotConfig.Mode == ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_UNSPECIFIED { - sc.GoldenSnapshotConfig.Mode = ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED + if sc.GoldenSnapshotConfig.Mode == ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_UNSPECIFIED { + sc.GoldenSnapshotConfig.Mode = ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED } } -func applyContainerDefaults(c *ateapipb.Container) { +func applyContainerDefaults(c *ateapi.Container) { const ( defaultWakeupProbeTimeoutSeconds int32 = 30 defaultWakeupProbePath = "/" @@ -93,30 +93,30 @@ func applyContainerDefaults(c *ateapipb.Container) { } } -func applyAccessPolicyDefaults(*ateapipb.AccessPolicy) {} +func applyAccessPolicyDefaults(*ateapi.AccessPolicy) {} -func applyActorDefaults(*ateapipb.Actor) {} +func applyActorDefaults(*ateapi.Actor) {} -func applyAtespaceDefaults(*ateapipb.Atespace) {} +func applyAtespaceDefaults(*ateapi.Atespace) {} -func applyEgressPolicyDefaults(p *ateapipb.EgressPolicy) { +func applyEgressPolicyDefaults(p *ateapi.EgressPolicy) { applyEgressRuleDefaults(p.GetRules()) } // applyEgressRuleDefaults fills the port of an http or https rule that // names none: the protocol's well-known port. A tls_passthrough rule has no // default; validation requires its ports. -func applyEgressRuleDefaults(rules []*ateapipb.EgressRule) { +func applyEgressRuleDefaults(rules []*ateapi.EgressRule) { for _, r := range rules { switch { case r.GetHttp() != nil && r.Http.Ports == nil: - r.Http.Ports = &ateapipb.Ports{Numbers: []int32{80}} + r.Http.Ports = &ateapi.Ports{Numbers: []int32{80}} case r.GetHttps() != nil && r.Https.Ports == nil: - r.Https.Ports = &ateapipb.Ports{Numbers: []int32{443}} + r.Https.Ports = &ateapi.Ports{Numbers: []int32{443}} } } } -func applyTagDefaults(*ateapipb.Tag) {} +func applyTagDefaults(*ateapi.Tag) {} -func applyWorkerDefaults(*ateapipb.Worker) {} +func applyWorkerDefaults(*ateapi.Worker) {} diff --git a/cmd/ateapi/internal/defaults/defaults_test.go b/cmd/ateapi/internal/defaults/defaults_test.go index c798c7c35e..c1263ec43f 100644 --- a/cmd/ateapi/internal/defaults/defaults_test.go +++ b/cmd/ateapi/internal/defaults/defaults_test.go @@ -18,7 +18,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" @@ -26,14 +26,14 @@ import ( func TestApply(t *testing.T) { const ( - scopeFull = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY - scopeData = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES + scopeFull = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + scopeData = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES ) // defaultSnapshotConfig is what an omitted snapshot_config defaults to. - defaultSnapshotConfig := func() *ateapipb.SnapshotConfig { - return &ateapipb.SnapshotConfig{ + defaultSnapshotConfig := func() *ateapi.SnapshotConfig { + return &ateapi.SnapshotConfig{ PreferredFidelity: scopeFull, - GoldenSnapshotConfig: &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, + GoldenSnapshotConfig: &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, } } tests := []struct { @@ -42,123 +42,123 @@ func TestApply(t *testing.T) { want proto.Message }{{ name: "nil actor template is tolerated", - in: (*ateapipb.ActorTemplate)(nil), - want: (*ateapipb.ActorTemplate)(nil), + in: (*ateapi.ActorTemplate)(nil), + want: (*ateapi.ActorTemplate)(nil), }, { name: "missing snapshot_config gets every default", - in: &ateapipb.ActorTemplate{}, - want: &ateapipb.ActorTemplate{SnapshotConfig: defaultSnapshotConfig()}, + in: &ateapi.ActorTemplate{}, + want: &ateapi.ActorTemplate{SnapshotConfig: defaultSnapshotConfig()}, }, { name: "empty snapshot_config gets every default", - in: &ateapipb.ActorTemplate{SnapshotConfig: &ateapipb.SnapshotConfig{}}, - want: &ateapipb.ActorTemplate{SnapshotConfig: &ateapipb.SnapshotConfig{ + in: &ateapi.ActorTemplate{SnapshotConfig: &ateapi.SnapshotConfig{}}, + want: &ateapi.ActorTemplate{SnapshotConfig: &ateapi.SnapshotConfig{ PreferredFidelity: scopeFull, - GoldenSnapshotConfig: &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, + GoldenSnapshotConfig: &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, }}, }, { name: "set scopes are kept", - in: &ateapipb.ActorTemplate{SnapshotConfig: &ateapipb.SnapshotConfig{ + in: &ateapi.ActorTemplate{SnapshotConfig: &ateapi.SnapshotConfig{ PreferredFidelity: scopeData, }}, - want: &ateapipb.ActorTemplate{SnapshotConfig: &ateapipb.SnapshotConfig{ + want: &ateapi.ActorTemplate{SnapshotConfig: &ateapi.SnapshotConfig{ PreferredFidelity: scopeData, - GoldenSnapshotConfig: &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, + GoldenSnapshotConfig: &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, }}, }, { name: "container without wakeup probe stays without one", - in: &ateapipb.ActorTemplate{Containers: []*ateapipb.Container{{Name: "main"}}}, - want: &ateapipb.ActorTemplate{SnapshotConfig: defaultSnapshotConfig(), Containers: []*ateapipb.Container{{Name: "main"}}}, + in: &ateapi.ActorTemplate{Containers: []*ateapi.Container{{Name: "main"}}}, + want: &ateapi.ActorTemplate{SnapshotConfig: defaultSnapshotConfig(), Containers: []*ateapi.Container{{Name: "main"}}}, }, { name: "wakeup probe gets timeout and path", - in: &ateapipb.ActorTemplate{Containers: []*ateapipb.Container{ - {Name: "main", WakeupProbe: &ateapipb.WakeupProbe{HttpGet: &ateapipb.HttpGetAction{Port: 8080}}}, + in: &ateapi.ActorTemplate{Containers: []*ateapi.Container{ + {Name: "main", WakeupProbe: &ateapi.WakeupProbe{HttpGet: &ateapi.HttpGetAction{Port: 8080}}}, }}, - want: &ateapipb.ActorTemplate{SnapshotConfig: defaultSnapshotConfig(), Containers: []*ateapipb.Container{ - {Name: "main", WakeupProbe: &ateapipb.WakeupProbe{ - HttpGet: &ateapipb.HttpGetAction{Port: 8080, Path: "/"}, + want: &ateapi.ActorTemplate{SnapshotConfig: defaultSnapshotConfig(), Containers: []*ateapi.Container{ + {Name: "main", WakeupProbe: &ateapi.WakeupProbe{ + HttpGet: &ateapi.HttpGetAction{Port: 8080, Path: "/"}, TimeoutSeconds: 30, }}, }}, }, { name: "wakeup probe without http_get gets only the timeout", - in: &ateapipb.ActorTemplate{Containers: []*ateapipb.Container{ - {Name: "main", WakeupProbe: &ateapipb.WakeupProbe{}}, + in: &ateapi.ActorTemplate{Containers: []*ateapi.Container{ + {Name: "main", WakeupProbe: &ateapi.WakeupProbe{}}, }}, - want: &ateapipb.ActorTemplate{SnapshotConfig: defaultSnapshotConfig(), Containers: []*ateapipb.Container{ - {Name: "main", WakeupProbe: &ateapipb.WakeupProbe{TimeoutSeconds: 30}}, + want: &ateapi.ActorTemplate{SnapshotConfig: defaultSnapshotConfig(), Containers: []*ateapi.Container{ + {Name: "main", WakeupProbe: &ateapi.WakeupProbe{TimeoutSeconds: 30}}, }}, }, { name: "set wakeup probe fields are kept", - in: &ateapipb.ActorTemplate{Containers: []*ateapipb.Container{ - {Name: "main", WakeupProbe: &ateapipb.WakeupProbe{ - HttpGet: &ateapipb.HttpGetAction{Port: 8080, Path: "/healthz"}, + in: &ateapi.ActorTemplate{Containers: []*ateapi.Container{ + {Name: "main", WakeupProbe: &ateapi.WakeupProbe{ + HttpGet: &ateapi.HttpGetAction{Port: 8080, Path: "/healthz"}, TimeoutSeconds: 5, }}, }}, - want: &ateapipb.ActorTemplate{SnapshotConfig: defaultSnapshotConfig(), Containers: []*ateapipb.Container{ - {Name: "main", WakeupProbe: &ateapipb.WakeupProbe{ - HttpGet: &ateapipb.HttpGetAction{Port: 8080, Path: "/healthz"}, + want: &ateapi.ActorTemplate{SnapshotConfig: defaultSnapshotConfig(), Containers: []*ateapi.Container{ + {Name: "main", WakeupProbe: &ateapi.WakeupProbe{ + HttpGet: &ateapi.HttpGetAction{Port: 8080, Path: "/healthz"}, TimeoutSeconds: 5, }}, }}, }, { name: "every container is defaulted", - in: &ateapipb.ActorTemplate{Containers: []*ateapipb.Container{ - {Name: "a", WakeupProbe: &ateapipb.WakeupProbe{HttpGet: &ateapipb.HttpGetAction{Port: 1}}}, + in: &ateapi.ActorTemplate{Containers: []*ateapi.Container{ + {Name: "a", WakeupProbe: &ateapi.WakeupProbe{HttpGet: &ateapi.HttpGetAction{Port: 1}}}, {Name: "b"}, - {Name: "c", WakeupProbe: &ateapipb.WakeupProbe{HttpGet: &ateapipb.HttpGetAction{Port: 3}}}, + {Name: "c", WakeupProbe: &ateapi.WakeupProbe{HttpGet: &ateapi.HttpGetAction{Port: 3}}}, }}, - want: &ateapipb.ActorTemplate{SnapshotConfig: defaultSnapshotConfig(), Containers: []*ateapipb.Container{ - {Name: "a", WakeupProbe: &ateapipb.WakeupProbe{HttpGet: &ateapipb.HttpGetAction{Port: 1, Path: "/"}, TimeoutSeconds: 30}}, + want: &ateapi.ActorTemplate{SnapshotConfig: defaultSnapshotConfig(), Containers: []*ateapi.Container{ + {Name: "a", WakeupProbe: &ateapi.WakeupProbe{HttpGet: &ateapi.HttpGetAction{Port: 1, Path: "/"}, TimeoutSeconds: 30}}, {Name: "b"}, - {Name: "c", WakeupProbe: &ateapipb.WakeupProbe{HttpGet: &ateapipb.HttpGetAction{Port: 3, Path: "/"}, TimeoutSeconds: 30}}, + {Name: "c", WakeupProbe: &ateapi.WakeupProbe{HttpGet: &ateapi.HttpGetAction{Port: 3, Path: "/"}, TimeoutSeconds: 30}}, }}, }, { name: "actor has no defaults", - in: &ateapipb.Actor{WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "1"}}}, - want: &ateapipb.Actor{WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "1"}}}, + in: &ateapi.Actor{WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "1"}}}, + want: &ateapi.Actor{WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "1"}}}, }, { name: "atespace has no defaults", - in: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "team-a"}}, - want: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "team-a"}}, + in: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "team-a"}}, + want: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "team-a"}}, }, { name: "egress policy defaults http and https ports only", - in: &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{ - {Http: &ateapipb.HttpRule{Hostnames: []string{"a.example.com"}}}, - {Https: &ateapipb.HttpsRule{Hostnames: []string{"b.example.com"}}}, - {Http: &ateapipb.HttpRule{Hostnames: []string{"c.example.com"}, Ports: &ateapipb.Ports{All: &ateapipb.AllPorts{}}}}, - {TlsPassthrough: &ateapipb.TlsPassthroughRule{Hostnames: []string{"d.example.com"}}}, + in: &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{ + {Http: &ateapi.HttpRule{Hostnames: []string{"a.example.com"}}}, + {Https: &ateapi.HttpsRule{Hostnames: []string{"b.example.com"}}}, + {Http: &ateapi.HttpRule{Hostnames: []string{"c.example.com"}, Ports: &ateapi.Ports{All: &ateapi.AllPorts{}}}}, + {TlsPassthrough: &ateapi.TlsPassthroughRule{Hostnames: []string{"d.example.com"}}}, {}, }}, - want: &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{ - {Http: &ateapipb.HttpRule{Hostnames: []string{"a.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{80}}}}, - {Https: &ateapipb.HttpsRule{Hostnames: []string{"b.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{443}}}}, - {Http: &ateapipb.HttpRule{Hostnames: []string{"c.example.com"}, Ports: &ateapipb.Ports{All: &ateapipb.AllPorts{}}}}, - {TlsPassthrough: &ateapipb.TlsPassthroughRule{Hostnames: []string{"d.example.com"}}}, + want: &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{ + {Http: &ateapi.HttpRule{Hostnames: []string{"a.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{80}}}}, + {Https: &ateapi.HttpsRule{Hostnames: []string{"b.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{443}}}}, + {Http: &ateapi.HttpRule{Hostnames: []string{"c.example.com"}, Ports: &ateapi.Ports{All: &ateapi.AllPorts{}}}}, + {TlsPassthrough: &ateapi.TlsPassthroughRule{Hostnames: []string{"d.example.com"}}}, {}, }}, }, { name: "template defaults egress ports", - in: &ateapipb.ActorTemplate{GoldenEgressPolicy: &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{ - {Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}}}, - {Https: &ateapipb.HttpsRule{Hostnames: []string{"api.example.com"}}}, - {Https: &ateapipb.HttpsRule{Hostnames: []string{"custom.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{8443}}}}, - {TlsPassthrough: &ateapipb.TlsPassthroughRule{Hostnames: []string{"tcp.example.com"}}}, + in: &ateapi.ActorTemplate{GoldenEgressPolicy: &ateapi.EgressPolicyTemplate{Rules: []*ateapi.EgressRule{ + {Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}}}, + {Https: &ateapi.HttpsRule{Hostnames: []string{"api.example.com"}}}, + {Https: &ateapi.HttpsRule{Hostnames: []string{"custom.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{8443}}}}, + {TlsPassthrough: &ateapi.TlsPassthroughRule{Hostnames: []string{"tcp.example.com"}}}, }}}, - want: &ateapipb.ActorTemplate{SnapshotConfig: defaultSnapshotConfig(), GoldenEgressPolicy: &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{ - {Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{80}}}}, - {Https: &ateapipb.HttpsRule{Hostnames: []string{"api.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{443}}}}, - {Https: &ateapipb.HttpsRule{Hostnames: []string{"custom.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{8443}}}}, - {TlsPassthrough: &ateapipb.TlsPassthroughRule{Hostnames: []string{"tcp.example.com"}}}, + want: &ateapi.ActorTemplate{SnapshotConfig: defaultSnapshotConfig(), GoldenEgressPolicy: &ateapi.EgressPolicyTemplate{Rules: []*ateapi.EgressRule{ + {Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{80}}}}, + {Https: &ateapi.HttpsRule{Hostnames: []string{"api.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{443}}}}, + {Https: &ateapi.HttpsRule{Hostnames: []string{"custom.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{8443}}}}, + {TlsPassthrough: &ateapi.TlsPassthroughRule{Hostnames: []string{"tcp.example.com"}}}, }}}, }, { name: "tag has no defaults", - in: &ateapipb.Tag{Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED}, - want: &ateapipb.Tag{Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED}, + in: &ateapi.Tag{Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED}, + want: &ateapi.Tag{Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED}, }, { name: "worker has no defaults", - in: &ateapipb.Worker{Metadata: &ateapipb.ResourceMetadata{Name: "worker-1"}}, - want: &ateapipb.Worker{Metadata: &ateapipb.ResourceMetadata{Name: "worker-1"}}, + in: &ateapi.Worker{Metadata: &ateapi.ResourceMetadata{Name: "worker-1"}}, + want: &ateapi.Worker{Metadata: &ateapi.ResourceMetadata{Name: "worker-1"}}, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -180,17 +180,17 @@ func TestGoldenSnapshotDefaults(t *testing.T) { for _, tt := range []struct { name string config string - mode ateapipb.GoldenSnapshotMode + mode ateapi.GoldenSnapshotMode }{ - {"omitted config", `{}`, ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, - {"omitted mode", `{"goldenSnapshotConfig": {}}`, ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, - {"unspecified mode", `{"goldenSnapshotConfig": {"mode": "GOLDEN_SNAPSHOT_MODE_UNSPECIFIED"}}`, ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, - {"explicit zero", `{"goldenSnapshotConfig": {"mode": 0}}`, ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, - {"enabled", `{"goldenSnapshotConfig": {"mode": "GOLDEN_SNAPSHOT_MODE_ENABLED"}}`, ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, - {"disabled", `{"goldenSnapshotConfig": {"mode": "GOLDEN_SNAPSHOT_MODE_DISABLED"}}`, ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED}, + {"omitted config", `{}`, ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, + {"omitted mode", `{"goldenSnapshotConfig": {}}`, ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, + {"unspecified mode", `{"goldenSnapshotConfig": {"mode": "GOLDEN_SNAPSHOT_MODE_UNSPECIFIED"}}`, ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, + {"explicit zero", `{"goldenSnapshotConfig": {"mode": 0}}`, ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, + {"enabled", `{"goldenSnapshotConfig": {"mode": "GOLDEN_SNAPSHOT_MODE_ENABLED"}}`, ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, + {"disabled", `{"goldenSnapshotConfig": {"mode": "GOLDEN_SNAPSHOT_MODE_DISABLED"}}`, ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED}, } { t.Run(tt.name, func(t *testing.T) { - tmpl := &ateapipb.ActorTemplate{} + tmpl := &ateapi.ActorTemplate{} if err := protojson.Unmarshal([]byte(`{"snapshotConfig": `+tt.config+`}`), tmpl); err != nil { t.Fatal(err) } @@ -203,7 +203,7 @@ func TestGoldenSnapshotDefaults(t *testing.T) { t.Fatal(err) } Apply(tmpl) - want := &ateapipb.GoldenSnapshotConfig{Mode: tt.mode} + want := &ateapi.GoldenSnapshotConfig{Mode: tt.mode} if diff := cmp.Diff(want, tmpl.GetSnapshotConfig().GetGoldenSnapshotConfig(), protocmp.Transform()); diff != "" { t.Fatalf("golden snapshot default mismatch (-want +got):\n%s", diff) } diff --git a/cmd/ateapi/internal/scheduling/scheduling.go b/cmd/ateapi/internal/scheduling/scheduling.go index bdeaba6ed8..d43dd5aef5 100644 --- a/cmd/ateapi/internal/scheduling/scheduling.go +++ b/cmd/ateapi/internal/scheduling/scheduling.go @@ -22,9 +22,9 @@ import ( "math/rand" "slices" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/hardware" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "k8s.io/apimachinery/pkg/labels" ) @@ -55,7 +55,7 @@ type Constraints struct { // Limits are the actor's declared resource limits, in the units a Worker // reports its capacity in, so the two subtract. - Limits *ateapipb.Resources + Limits *ateapi.Resources } // ErrNoCapacity is returned by Schedule when no worker that meets the @@ -67,20 +67,20 @@ var ErrNoCapacity = errors.New("no worker that meets the constraints has room") type Scheduler interface { // Schedule returns a worker that meets constraints and has room. // Returns ErrNoCapacity when no worker that meets constraints has room. - Schedule(ctx context.Context, constraints Constraints) (*ateapipb.Worker, error) + Schedule(ctx context.Context, constraints Constraints) (*ateapi.Worker, error) // Applies reports whether worker satisfies non-capacity constraints. Capacity // is excluded so an existing assignment does not make its Worker ineligible. - Applies(worker *ateapipb.Worker, constraints Constraints) bool + Applies(worker *ateapi.Worker, constraints Constraints) bool // HasRoom reports whether worker's remaining capacity admits one more actor // of this size, in every dimension. Independent of Applies. - HasRoom(worker *ateapipb.Worker, constraints Constraints) bool + HasRoom(worker *ateapi.Worker, constraints Constraints) bool } // WorkerSource provides the whole fleet of workers. type WorkerSource interface { - Workers() ([]*ateapipb.Worker, error) + Workers() ([]*ateapi.Worker, error) } type scheduler struct { @@ -112,7 +112,7 @@ func New(source WorkerSource, opts ...Option) Scheduler { // random (power of two choices), and returns the less-loaded one, where load is // the higher of actor-slot and compute-resource utilization. Spreading across // the warm pool avoids hotspots until autoscaling reclaims idle workers. -func (s *scheduler) Schedule(ctx context.Context, constraints Constraints) (*ateapipb.Worker, error) { +func (s *scheduler) Schedule(ctx context.Context, constraints Constraints) (*ateapi.Worker, error) { workers, err := s.source.Workers() if err != nil { return nil, fmt.Errorf("while listing workers: %w", err) @@ -148,7 +148,7 @@ func (s *scheduler) Schedule(ctx context.Context, constraints Constraints) (*ate // candidate pairs an eligible worker with its cached compute utilization. type candidate struct { - worker *ateapipb.Worker + worker *ateapi.Worker // resUtil is the worker's dominant compute-resource utilization in [0,1], // or -1 if not yet computed. resUtil float64 @@ -188,11 +188,11 @@ func lessLoaded(a, b *candidate) bool { // workerResourceUtilization returns the highest allocated/capacity ratio across // compute dimensions, or 1 when capacity is unreported. -func workerResourceUtilization(w *ateapipb.Worker) float64 { +func workerResourceUtilization(w *ateapi.Worker) float64 { return utilization(w.GetStatus().GetCapacity(), w.GetStatus().GetAllocated()) } -func utilization(capacity, used *ateapipb.WorkerResources) float64 { +func utilization(capacity, used *ateapi.WorkerResources) float64 { var ( maxRatio float64 hasPositive bool @@ -216,11 +216,11 @@ func utilization(capacity, used *ateapipb.WorkerResources) float64 { // and reported its sandbox class and runtimes. The assignment records the // runtime and atelet requires it on Run/Restore, so a worker without one // cannot host anything yet. -func Registered(worker *ateapipb.Worker) bool { +func Registered(worker *ateapi.Worker) bool { return worker.GetStatus().GetRegisteredEpoch() != 0 && hardware.SandboxClass(worker.GetStatus()) != "" } -func (s *scheduler) Applies(worker *ateapipb.Worker, constraints Constraints) bool { +func (s *scheduler) Applies(worker *ateapi.Worker, constraints Constraints) bool { if !Registered(worker) { return false } @@ -229,7 +229,7 @@ func (s *scheduler) Applies(worker *ateapipb.Worker, constraints Constraints) bo return false } - if worker.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_ACTIVE { + if worker.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_ACTIVE { return false } @@ -251,12 +251,12 @@ func (s *scheduler) Applies(worker *ateapipb.Worker, constraints Constraints) bo // HasRoom reports whether what the worker has left admits one more actor of // this size. A dimension the worker does not report is unconstrained, so // placement is never blocked by missing data. -func (s *scheduler) HasRoom(worker *ateapipb.Worker, constraints Constraints) bool { +func (s *scheduler) HasRoom(worker *ateapi.Worker, constraints Constraints) bool { _, ok := checkRoom(worker, constraints.Limits) return ok } -func checkRoom(worker *ateapipb.Worker, want *ateapipb.Resources) (candidate, bool) { +func checkRoom(worker *ateapi.Worker, want *ateapi.Resources) (candidate, bool) { capacity := worker.GetStatus().GetCapacity() used := worker.GetStatus().GetAllocated() diff --git a/cmd/ateapi/internal/scheduling/scheduling_test.go b/cmd/ateapi/internal/scheduling/scheduling_test.go index efa9436a94..8e2985d52c 100644 --- a/cmd/ateapi/internal/scheduling/scheduling_test.go +++ b/cmd/ateapi/internal/scheduling/scheduling_test.go @@ -19,9 +19,9 @@ import ( "errors" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/hardware" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "k8s.io/apimachinery/pkg/labels" ) @@ -109,21 +109,21 @@ func TestSchedule(t *testing.T) { { name: "draining workers never scheduled", fleet: fleet{ - worker("w-draining", "gvisor", "node-a", tierTwo, withState(ateapipb.WorkerState_WORKER_STATE_DRAINING)), + worker("w-draining", "gvisor", "node-a", tierTwo, withState(ateapi.WorkerState_WORKER_STATE_DRAINING)), }, constraints: Constraints{}, }, { name: "unspecified workers never scheduled", fleet: fleet{ - worker("w-unspecified", "gvisor", "node-a", tierTwo, withState(ateapipb.WorkerState_WORKER_STATE_UNSPECIFIED)), + worker("w-unspecified", "gvisor", "node-a", tierTwo, withState(ateapi.WorkerState_WORKER_STATE_UNSPECIFIED)), }, constraints: Constraints{}, }, { name: "picks active worker over draining one", fleet: fleet{ - worker("w-draining", "gvisor", "node-a", tierTwo, withState(ateapipb.WorkerState_WORKER_STATE_DRAINING)), + worker("w-draining", "gvisor", "node-a", tierTwo, withState(ateapi.WorkerState_WORKER_STATE_DRAINING)), worker("w-active", "gvisor", "node-a", tierTwo), }, constraints: Constraints{}, @@ -369,13 +369,13 @@ func TestSchedule(t *testing.T) { func TestRegistered(t *testing.T) { tests := []struct { name string - mutate func(*ateapipb.Worker) + mutate func(*ateapi.Worker) want bool }{ - {name: "registered with runtimes", mutate: func(*ateapipb.Worker) {}, want: true}, - {name: "no registered epoch", mutate: func(w *ateapipb.Worker) { w.Status.RegisteredEpoch = 0 }}, - {name: "no sandbox class", mutate: func(w *ateapipb.Worker) { w.Status.SandboxClasses = nil }}, - {name: "no status", mutate: func(w *ateapipb.Worker) { w.Status = nil }}, + {name: "registered with runtimes", mutate: func(*ateapi.Worker) {}, want: true}, + {name: "no registered epoch", mutate: func(w *ateapi.Worker) { w.Status.RegisteredEpoch = 0 }}, + {name: "no sandbox class", mutate: func(w *ateapi.Worker) { w.Status.SandboxClasses = nil }}, + {name: "no status", mutate: func(w *ateapi.Worker) { w.Status = nil }}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { @@ -392,7 +392,7 @@ func TestApplies(t *testing.T) { tests := []struct { name string - worker *ateapipb.Worker + worker *ateapi.Worker constraints Constraints want bool }{ @@ -417,7 +417,7 @@ func TestApplies(t *testing.T) { }, { name: "worker process not registered", - worker: worker("w", "gvisor", "node-a", nil, func(w *ateapipb.Worker) { + worker: worker("w", "gvisor", "node-a", nil, func(w *ateapi.Worker) { w.Status.RegisteredEpoch = 0 }), constraints: Constraints{}, @@ -477,19 +477,19 @@ func TestApplies(t *testing.T) { }, { name: "skips draining worker", - worker: worker("w", "gvisor", "node-a", nil, withState(ateapipb.WorkerState_WORKER_STATE_DRAINING)), + worker: worker("w", "gvisor", "node-a", nil, withState(ateapi.WorkerState_WORKER_STATE_DRAINING)), constraints: Constraints{}, want: false, }, { name: "skips unavailable worker", - worker: worker("w", "gvisor", "node-a", nil, withState(ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE)), + worker: worker("w", "gvisor", "node-a", nil, withState(ateapi.WorkerState_WORKER_STATE_UNAVAILABLE)), constraints: Constraints{}, want: false, }, { name: "skips unspecified worker", - worker: worker("w", "gvisor", "node-a", nil, withState(ateapipb.WorkerState_WORKER_STATE_UNSPECIFIED)), + worker: worker("w", "gvisor", "node-a", nil, withState(ateapi.WorkerState_WORKER_STATE_UNSPECIFIED)), constraints: Constraints{}, want: false, }, @@ -530,20 +530,20 @@ func TestApplies(t *testing.T) { } } -type fleet []*ateapipb.Worker +type fleet []*ateapi.Worker -func (f fleet) Workers() ([]*ateapipb.Worker, error) { return f, nil } +func (f fleet) Workers() ([]*ateapi.Worker, error) { return f, nil } -func worker(pod, class, node string, lbls map[string]string, opts ...func(*ateapipb.Worker)) *ateapipb.Worker { - w := &ateapipb.Worker{ +func worker(pod, class, node string, lbls map[string]string, opts ...func(*ateapi.Worker)) *ateapi.Worker { + w := &ateapi.Worker{ WorkerPod: pod, NodeName: node, Labels: lbls, // A stored Worker always carries a ceiling; CreateWorker reifies one. - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, RegisteredEpoch: 1, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Capacity: &ateapi.WorkerResources{Actors: 1}, }, } if class != "" { @@ -555,14 +555,14 @@ func worker(pod, class, node string, lbls map[string]string, opts ...func(*ateap return w } -func sandboxRuntime(class, arch string, bundleHash ...string) *ateapipb.ActorSandboxRuntime { - attrs := []*ateapipb.AttributeEntry{{Key: "architecture", Value: arch}} +func sandboxRuntime(class, arch string, bundleHash ...string) *ateapi.ActorSandboxRuntime { + attrs := []*ateapi.AttributeEntry{{Key: "architecture", Value: arch}} if len(bundleHash) > 0 && bundleHash[0] != "" { - attrs = append(attrs, &ateapipb.AttributeEntry{Key: "sandbox_bundle_hash", Value: bundleHash[0]}) + attrs = append(attrs, &ateapi.AttributeEntry{Key: "sandbox_bundle_hash", Value: bundleHash[0]}) } - return &ateapipb.ActorSandboxRuntime{ + return &ateapi.ActorSandboxRuntime{ SandboxClass: class, - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", Attributes: attrs, }, @@ -571,32 +571,32 @@ func sandboxRuntime(class, arch string, bundleHash ...string) *ateapipb.ActorSan // sandboxClass is the WorkerSandboxClass entry of def's class, with def as // its default runtime and restorable as the others. -func sandboxClass(def *ateapipb.ActorSandboxRuntime, restorable ...*ateapipb.ActorSandboxRuntime) *ateapipb.WorkerSandboxClass { - c := &ateapipb.WorkerSandboxClass{SandboxClass: def.GetSandboxClass(), DefaultRuntime: &ateapipb.WorkerSandboxRuntime{Version: def.GetVersion()}} +func sandboxClass(def *ateapi.ActorSandboxRuntime, restorable ...*ateapi.ActorSandboxRuntime) *ateapi.WorkerSandboxClass { + c := &ateapi.WorkerSandboxClass{SandboxClass: def.GetSandboxClass(), DefaultRuntime: &ateapi.WorkerSandboxRuntime{Version: def.GetVersion()}} for _, r := range restorable { - c.RestorableRuntimes = append(c.RestorableRuntimes, &ateapipb.WorkerSandboxRuntime{Version: r.GetVersion()}) + c.RestorableRuntimes = append(c.RestorableRuntimes, &ateapi.WorkerSandboxRuntime{Version: r.GetVersion()}) } return c } // withRuntimes gives the worker one sandbox class, def's. A nil def leaves // the worker as before it registered: no class at all. -func withRuntimes(def *ateapipb.ActorSandboxRuntime, restorable ...*ateapipb.ActorSandboxRuntime) func(*ateapipb.Worker) { - return func(w *ateapipb.Worker) { +func withRuntimes(def *ateapi.ActorSandboxRuntime, restorable ...*ateapi.ActorSandboxRuntime) func(*ateapi.Worker) { + return func(w *ateapi.Worker) { w.Status.SandboxClasses = nil if def != nil { - w.Status.SandboxClasses = []*ateapipb.WorkerSandboxClass{sandboxClass(def, restorable...)} + w.Status.SandboxClasses = []*ateapi.WorkerSandboxClass{sandboxClass(def, restorable...)} } } } -func withState(state ateapipb.WorkerState) func(*ateapipb.Worker) { - return func(w *ateapipb.Worker) { +func withState(state ateapi.WorkerState) func(*ateapi.Worker) { + return func(w *ateapi.Worker) { w.Status.State = state } } -func assigned(atespace, name string) func(*ateapipb.Worker) { +func assigned(atespace, name string) func(*ateapi.Worker) { return assignedFor(atespace, name, nil) } @@ -604,32 +604,32 @@ func assigned(atespace, name string) func(*ateapipb.Worker) { // place against what is left rather than against the whole capacity. Only the // allocation total, which is all placement reads: the assignments themselves are // their own records and never on the worker. -func assignedFor(atespace, name string, took *ateapipb.Resources) func(*ateapipb.Worker) { - return func(w *ateapipb.Worker) { +func assignedFor(atespace, name string, took *ateapi.Resources) func(*ateapi.Worker) { + return func(w *ateapi.Worker) { if w.Status == nil { - w.Status = &ateapipb.WorkerStatus{} + w.Status = &ateapi.WorkerStatus{} } w.Status.Allocated = resources.AddToAllocated(w.Status.Allocated, - &ateapipb.ActorAssignment{ActorUid: atespace + "/" + name, Resources: took}, +1) + &ateapi.ActorAssignment{ActorUid: atespace + "/" + name, Resources: took}, +1) } } -func withMaxActors(n int32) func(*ateapipb.Worker) { - return func(w *ateapipb.Worker) { +func withMaxActors(n int32) func(*ateapi.Worker) { + return func(w *ateapi.Worker) { if w.Status == nil { - w.Status = &ateapipb.WorkerStatus{} + w.Status = &ateapi.WorkerStatus{} } if w.Status.Capacity == nil { - w.Status.Capacity = &ateapipb.WorkerResources{} + w.Status.Capacity = &ateapi.WorkerResources{} } w.Status.Capacity.Actors = n } } -func withCapacity(cpuMilli, memBytes int64) func(*ateapipb.Worker) { - return func(w *ateapipb.Worker) { +func withCapacity(cpuMilli, memBytes int64) func(*ateapi.Worker) { + return func(w *ateapi.Worker) { if w.Status.Capacity == nil { - w.Status.Capacity = &ateapipb.WorkerResources{} + w.Status.Capacity = &ateapi.WorkerResources{} } w.Status.Capacity.CpuMillicores = cpuMilli w.Status.Capacity.MemoryBytes = memBytes diff --git a/cmd/ateapi/internal/store/atepg/access_policy.go b/cmd/ateapi/internal/store/atepg/access_policy.go index 94b63783d4..66df2e2c2b 100644 --- a/cmd/ateapi/internal/store/atepg/access_policy.go +++ b/cmd/ateapi/internal/store/atepg/access_policy.go @@ -20,14 +20,14 @@ import ( "fmt" "github.com/jackc/pgx/v5" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" ) -func (p *Persistence) CreateGlobalAccessPolicy(ctx context.Context, policy *ateapipb.AccessPolicy) (*ateapipb.AccessPolicy, error) { - dbPolicy := proto.Clone(policy).(*ateapipb.AccessPolicy) +func (p *Persistence) CreateGlobalAccessPolicy(ctx context.Context, policy *ateapi.AccessPolicy) (*ateapi.AccessPolicy, error) { + dbPolicy := proto.Clone(policy).(*ateapi.AccessPolicy) setCreateMetadata(dbPolicy.Metadata) protoBytes, err := proto.Marshal(dbPolicy) if err != nil { @@ -58,13 +58,13 @@ func (p *Persistence) CreateGlobalAccessPolicy(ctx context.Context, policy *atea return dbPolicy, nil } -func (p *Persistence) GetGlobalAccessPolicy(ctx context.Context) (*ateapipb.AccessPolicy, error) { +func (p *Persistence) GetGlobalAccessPolicy(ctx context.Context) (*ateapi.AccessPolicy, error) { return getAccessPolicyRow(ctx, p.pool, ` SELECT uid, version, proto FROM global_access_policy WHERE id = true`) } -func (p *Persistence) UpdateGlobalAccessPolicy(ctx context.Context, precondition store.Precondition, mutate func(*ateapipb.AccessPolicy) error) (*ateapipb.AccessPolicy, error) { +func (p *Persistence) UpdateGlobalAccessPolicy(ctx context.Context, precondition store.Precondition, mutate func(*ateapi.AccessPolicy) error) (*ateapi.AccessPolicy, error) { if err := precondition.Validate(); err != nil { return nil, err } @@ -109,8 +109,8 @@ func (p *Persistence) UpdateGlobalAccessPolicy(ctx context.Context, precondition return dbPolicy, nil } -func (p *Persistence) CreateAtespaceAccessPolicy(ctx context.Context, name string, policy *ateapipb.AccessPolicy) (*ateapipb.AccessPolicy, error) { - dbPolicy := proto.Clone(policy).(*ateapipb.AccessPolicy) +func (p *Persistence) CreateAtespaceAccessPolicy(ctx context.Context, name string, policy *ateapi.AccessPolicy) (*ateapi.AccessPolicy, error) { + dbPolicy := proto.Clone(policy).(*ateapi.AccessPolicy) setCreateMetadata(dbPolicy.Metadata) protoBytes, err := proto.Marshal(dbPolicy) if err != nil { @@ -144,13 +144,13 @@ func (p *Persistence) CreateAtespaceAccessPolicy(ctx context.Context, name strin return dbPolicy, nil } -func (p *Persistence) GetAtespaceAccessPolicy(ctx context.Context, name string) (*ateapipb.AccessPolicy, error) { +func (p *Persistence) GetAtespaceAccessPolicy(ctx context.Context, name string) (*ateapi.AccessPolicy, error) { return getAccessPolicyRow(ctx, p.pool, ` SELECT uid, version, proto FROM atespace_access_policies WHERE atespace_name = $1`, name) } -func (p *Persistence) UpdateAtespaceAccessPolicy(ctx context.Context, name string, precondition store.Precondition, mutate func(*ateapipb.AccessPolicy) error) (*ateapipb.AccessPolicy, error) { +func (p *Persistence) UpdateAtespaceAccessPolicy(ctx context.Context, name string, precondition store.Precondition, mutate func(*ateapi.AccessPolicy) error) (*ateapi.AccessPolicy, error) { if err := precondition.Validate(); err != nil { return nil, err } @@ -195,7 +195,7 @@ func (p *Persistence) UpdateAtespaceAccessPolicy(ctx context.Context, name strin return dbPolicy, nil } -func (p *Persistence) DeleteAtespaceAccessPolicy(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapipb.AccessPolicy, error) { +func (p *Persistence) DeleteAtespaceAccessPolicy(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.AccessPolicy, error) { tx, err := p.pool.Begin(ctx) if err != nil { return nil, fmt.Errorf("beginning access policy delete for %s: %w", name, err) @@ -232,7 +232,7 @@ func (p *Persistence) DeleteAtespaceAccessPolicy(ctx context.Context, name strin return deleted, nil } -func getAccessPolicyRow(ctx context.Context, q querier, query string, args ...any) (*ateapipb.AccessPolicy, error) { +func getAccessPolicyRow(ctx context.Context, q querier, query string, args ...any) (*ateapi.AccessPolicy, error) { var uid string var version int64 var protoBytes []byte @@ -245,8 +245,8 @@ func getAccessPolicyRow(ctx context.Context, q querier, query string, args ...an return unmarshalAccessPolicy(uid, version, protoBytes) } -func unmarshalAccessPolicy(uid string, version int64, protoBytes []byte) (*ateapipb.AccessPolicy, error) { - policy := &ateapipb.AccessPolicy{} +func unmarshalAccessPolicy(uid string, version int64, protoBytes []byte) (*ateapi.AccessPolicy, error) { + policy := &ateapi.AccessPolicy{} if err := unmarshalStored(protoBytes, policy); err != nil { return nil, fmt.Errorf("unmarshaling access policy: %w", err) } diff --git a/cmd/ateapi/internal/store/atepg/access_policy_test.go b/cmd/ateapi/internal/store/atepg/access_policy_test.go index 3a118ae358..e3410e38c6 100644 --- a/cmd/ateapi/internal/store/atepg/access_policy_test.go +++ b/cmd/ateapi/internal/store/atepg/access_policy_test.go @@ -21,9 +21,9 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/authz" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/testing/protocmp" ) @@ -35,9 +35,9 @@ func TestGlobalAccessPolicy_Lifecycle(t *testing.T) { t.Fatalf("GetGlobalAccessPolicy before create = %v, want ErrNotFound", err) } - policy := &ateapipb.AccessPolicy{ - Metadata: &ateapipb.ResourceMetadata{Name: "default"}, - Bindings: []*ateapipb.Binding{ + policy := &ateapi.AccessPolicy{ + Metadata: &ateapi.ResourceMetadata{Name: "default"}, + Bindings: []*ateapi.Binding{ {Role: authz.RoleViewer, Members: []string{"user:bob"}}, {Role: authz.RoleOwner, Members: []string{"user:alice"}}, }, @@ -62,18 +62,18 @@ func TestGlobalAccessPolicy_Lifecycle(t *testing.T) { t.Fatalf("GetGlobalAccessPolicy = %v, %v; want %v", got, err, created) } - if _, err := p.UpdateGlobalAccessPolicy(ctx, store.Precondition{}, func(*ateapipb.AccessPolicy) error { return nil }); !errors.Is(err, store.ErrPreconditionRequired) { + if _, err := p.UpdateGlobalAccessPolicy(ctx, store.Precondition{}, func(*ateapi.AccessPolicy) error { return nil }); !errors.Is(err, store.ErrPreconditionRequired) { t.Fatalf("UpdateGlobalAccessPolicy without precondition = %v, want ErrPreconditionRequired", err) } - if _, err := p.UpdateGlobalAccessPolicy(ctx, store.Precondition{UID: created.GetMetadata().GetUid(), Version: 99}, func(*ateapipb.AccessPolicy) error { return nil }); !errors.Is(err, store.ErrVersionConflict) { + if _, err := p.UpdateGlobalAccessPolicy(ctx, store.Precondition{UID: created.GetMetadata().GetUid(), Version: 99}, func(*ateapi.AccessPolicy) error { return nil }); !errors.Is(err, store.ErrVersionConflict) { t.Fatalf("UpdateGlobalAccessPolicy wrong version = %v, want ErrVersionConflict", err) } - if _, err := p.UpdateGlobalAccessPolicy(ctx, store.Precondition{UID: "wrong-uid", Version: 1}, func(*ateapipb.AccessPolicy) error { return nil }); !errors.Is(err, store.ErrUIDConflict) { + if _, err := p.UpdateGlobalAccessPolicy(ctx, store.Precondition{UID: "wrong-uid", Version: 1}, func(*ateapi.AccessPolicy) error { return nil }); !errors.Is(err, store.ErrUIDConflict) { t.Fatalf("UpdateGlobalAccessPolicy wrong uid = %v, want ErrUIDConflict", err) } - updated, err := p.UpdateGlobalAccessPolicy(ctx, store.PreconditionFrom(created), func(toUpdate *ateapipb.AccessPolicy) error { - toUpdate.Bindings = []*ateapipb.Binding{ + updated, err := p.UpdateGlobalAccessPolicy(ctx, store.PreconditionFrom(created), func(toUpdate *ateapi.AccessPolicy) error { + toUpdate.Bindings = []*ateapi.Binding{ {Role: authz.RoleOwner, Members: []string{"user:alice", "user:carol"}}, } return nil @@ -87,9 +87,9 @@ func TestAtespaceAccessPolicy_LifecycleAndCascade(t *testing.T) { p := setupPostgresPersistence(t) ctx := t.Context() - policy := &ateapipb.AccessPolicy{ - Metadata: &ateapipb.ResourceMetadata{Name: "default"}, - Bindings: []*ateapipb.Binding{ + policy := &ateapi.AccessPolicy{ + Metadata: &ateapi.ResourceMetadata{Name: "default"}, + Bindings: []*ateapi.Binding{ {Role: authz.RoleEditor, Members: []string{"user:bob"}}, }, } @@ -112,8 +112,8 @@ func TestAtespaceAccessPolicy_LifecycleAndCascade(t *testing.T) { t.Fatalf("second CreateAtespaceAccessPolicy = %v, want ErrAlreadyExists", err) } - updated, err := p.UpdateAtespaceAccessPolicy(ctx, "team-a", store.PreconditionFrom(created), func(toUpdate *ateapipb.AccessPolicy) error { - toUpdate.Bindings = []*ateapipb.Binding{ + updated, err := p.UpdateAtespaceAccessPolicy(ctx, "team-a", store.PreconditionFrom(created), func(toUpdate *ateapi.AccessPolicy) error { + toUpdate.Bindings = []*ateapi.Binding{ {Role: authz.RoleViewer, Members: []string{"user:dave"}}, } return nil @@ -133,7 +133,7 @@ func TestAtespaceAccessPolicy_LifecycleAndCascade(t *testing.T) { UID: updated.GetMetadata().GetUid(), Version: updated.GetMetadata().GetVersion(), }) - if err != nil || !cmp.Equal(deleted, updated, protocmp.Transform(), protocmp.IgnoreFields(&ateapipb.ResourceMetadata{}, "delete_time")) { + if err != nil || !cmp.Equal(deleted, updated, protocmp.Transform(), protocmp.IgnoreFields(&ateapi.ResourceMetadata{}, "delete_time")) { t.Fatalf("DeleteAtespaceAccessPolicy = %v, %v; want %v", deleted, err, updated) } if deleted.GetMetadata().GetDeleteTime() == nil { @@ -185,9 +185,9 @@ func TestGlobalAccessPolicy_UpdateIsAtomic(t *testing.T) { p := setupPostgresPersistence(t) ctx := t.Context() - created, err := p.CreateGlobalAccessPolicy(ctx, &ateapipb.AccessPolicy{ - Metadata: &ateapipb.ResourceMetadata{Name: "default"}, - Bindings: []*ateapipb.Binding{{Role: authz.RoleOwner, Members: []string{"user:alice"}}}, + created, err := p.CreateGlobalAccessPolicy(ctx, &ateapi.AccessPolicy{ + Metadata: &ateapi.ResourceMetadata{Name: "default"}, + Bindings: []*ateapi.Binding{{Role: authz.RoleOwner, Members: []string{"user:alice"}}}, }) if err != nil { t.Fatalf("CreateGlobalAccessPolicy failed: %v", err) @@ -201,8 +201,8 @@ func TestGlobalAccessPolicy_UpdateIsAtomic(t *testing.T) { t.Run("failed tuple write rolls back the row and earlier tuple deletes", func(t *testing.T) { // Reconciling deletes alice's tuple and then fails writing a relation // the model does not define, after the row UPDATE has run. - _, err := p.UpdateGlobalAccessPolicy(ctx, pre, func(ap *ateapipb.AccessPolicy) error { - ap.Bindings = []*ateapipb.Binding{{Role: "not-a-relation", Members: []string{"user:bob"}}} + _, err := p.UpdateGlobalAccessPolicy(ctx, pre, func(ap *ateapi.AccessPolicy) error { + ap.Bindings = []*ateapi.Binding{{Role: "not-a-relation", Members: []string{"user:bob"}}} return nil }) if err == nil { @@ -228,8 +228,8 @@ func TestGlobalAccessPolicy_UpdateIsAtomic(t *testing.T) { wg.Add(1) go func() { defer wg.Done() - _, errs[i] = p.UpdateGlobalAccessPolicy(ctx, pre, func(ap *ateapipb.AccessPolicy) error { - ap.Bindings = []*ateapipb.Binding{{Role: authz.RoleOwner, Members: []string{member}}} + _, errs[i] = p.UpdateGlobalAccessPolicy(ctx, pre, func(ap *ateapi.AccessPolicy) error { + ap.Bindings = []*ateapi.Binding{{Role: authz.RoleOwner, Members: []string{member}}} return nil }) }() diff --git a/cmd/ateapi/internal/store/atepg/actor.go b/cmd/ateapi/internal/store/atepg/actor.go index e702bcfb5f..e0e8d822e6 100644 --- a/cmd/ateapi/internal/store/atepg/actor.go +++ b/cmd/ateapi/internal/store/atepg/actor.go @@ -20,13 +20,13 @@ import ( "fmt" "github.com/jackc/pgx/v5" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" ) -func (p *Persistence) CreateActor(ctx context.Context, actor *ateapipb.Actor) (*ateapipb.Actor, error) { +func (p *Persistence) CreateActor(ctx context.Context, actor *ateapi.Actor) (*ateapi.Actor, error) { atespace := actor.GetMetadata().GetAtespace() name := actor.GetMetadata().GetName() @@ -34,8 +34,11 @@ func (p *Persistence) CreateActor(ctx context.Context, actor *ateapipb.Actor) (* // make modifications to the actor before passing it in, so we can safely // mutate it in place. This breaks some of the contract tests, so we can // fix it later. - dbActor := proto.Clone(actor).(*ateapipb.Actor) + dbActor := proto.Clone(actor).(*ateapi.Actor) setCreateMetadata(dbActor.Metadata) + if err := validateSnapshotURIs("actor "+resources.ActorRefFromActor(dbActor).String(), dbActor.GetStatus().GetSnapshots()...); err != nil { + return nil, err + } protoBytes, err := proto.Marshal(dbActor) if err != nil { @@ -60,7 +63,7 @@ func (p *Persistence) CreateActor(ctx context.Context, actor *ateapipb.Actor) (* return dbActor, nil } -func (p *Persistence) GetActor(ctx context.Context, actorRef resources.ActorRef) (*ateapipb.Actor, error) { +func (p *Persistence) GetActor(ctx context.Context, actorRef resources.ActorRef) (*ateapi.Actor, error) { var protoBytes []byte err := p.pool.QueryRow(ctx, `SELECT proto FROM actors WHERE atespace = $1 AND name = $2`, actorRef.Atespace, actorRef.Name).Scan(&protoBytes) if err != nil { @@ -69,25 +72,25 @@ func (p *Persistence) GetActor(ctx context.Context, actorRef resources.ActorRef) } return nil, fmt.Errorf("getting actor %s/%s: %w", actorRef.Atespace, actorRef.Name, err) } - out := &ateapipb.Actor{} + out := &ateapi.Actor{} if err := unmarshalStored(protoBytes, out); err != nil { return nil, fmt.Errorf("unmarshaling actor: %w", err) } return out, nil } -func (p *Persistence) UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(*ateapipb.Actor) error) (*ateapipb.Actor, error) { +func (p *Persistence) UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(*ateapi.Actor) error) (*ateapi.Actor, error) { if err := precondition.Validate(); err != nil { return nil, err } return p.updateActor(ctx, actorRef, store.DeletePreconditions(precondition), mutate, false) } -func (p *Persistence) MarkActorForDeletion(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions, mutate func(*ateapipb.Actor) error) (*ateapipb.Actor, error) { +func (p *Persistence) MarkActorForDeletion(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions, mutate func(*ateapi.Actor) error) (*ateapi.Actor, error) { return p.updateActor(ctx, actorRef, precondition, mutate, true) } -func (p *Persistence) updateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions, mutate func(*ateapipb.Actor) error, markForDeletion bool) (*ateapipb.Actor, error) { +func (p *Persistence) updateActor(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions, mutate func(*ateapi.Actor) error, markForDeletion bool) (*ateapi.Actor, error) { atespace, name := actorRef.Atespace, actorRef.Name var currentUID string var currentVersion int64 @@ -101,7 +104,7 @@ func (p *Persistence) updateActor(ctx context.Context, actorRef resources.ActorR return nil, fmt.Errorf("getting actor %s/%s for update: %w", atespace, name, err) } - dbActor := &ateapipb.Actor{} + dbActor := &ateapi.Actor{} if err := unmarshalStored(currentBytes, dbActor); err != nil { return nil, fmt.Errorf("unmarshaling actor for update: %w", err) } @@ -117,6 +120,9 @@ func (p *Persistence) updateActor(ctx context.Context, actorRef resources.ActorR return nil, err } } + if err := validateSnapshotURIs("actor "+actorRef.String(), dbActor.GetStatus().GetSnapshots()...); err != nil { + return nil, err + } // Stored metadata is authoritative; discard any metadata edits made by the // closure and derive the next revision from the state this attempt read. setUpdateMetadata(dbActor.Metadata, oldMeta) @@ -145,7 +151,7 @@ func (p *Persistence) updateActor(ctx context.Context, actorRef resources.ActorR return dbActor, nil } -func (p *Persistence) DeleteActor(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (*ateapipb.Actor, error) { +func (p *Persistence) DeleteActor(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (*ateapi.Actor, error) { atespace, name := actorRef.Atespace, actorRef.Name var protoBytes []byte err := p.pool.QueryRow(ctx, ` @@ -163,19 +169,19 @@ func (p *Persistence) DeleteActor(ctx context.Context, actorRef resources.ActorR if err != nil { return nil, fmt.Errorf("deleting actor %s/%s: %w", atespace, name, err) } - out := &ateapipb.Actor{} + out := &ateapi.Actor{} if err := unmarshalStored(protoBytes, out); err != nil { return nil, fmt.Errorf("unmarshaling deleted actor: %w", err) } return out, nil } -func (p *Persistence) ListActors(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapipb.Actor], error) { +func (p *Persistence) ListActors(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapi.Actor], error) { opts, err := store.NormalizeListOptions(opts) if err != nil { - return store.ListResponse[*ateapipb.Actor]{}, err + return store.ListResponse[*ateapi.Actor]{}, err } - var items []*ateapipb.Actor + var items []*ateapi.Actor var nextToken string if atespace != "" { items, nextToken, err = p.listActorsScoped(ctx, atespace, opts.PageSize, opts.PageToken) @@ -183,12 +189,12 @@ func (p *Persistence) ListActors(ctx context.Context, atespace string, opts stor items, nextToken, err = p.listActorsGlobal(ctx, opts.PageSize, opts.PageToken) } if err != nil { - return store.ListResponse[*ateapipb.Actor]{}, err + return store.ListResponse[*ateapi.Actor]{}, err } - return store.ListResponse[*ateapipb.Actor]{Items: items, NextPageToken: nextToken}, nil + return store.ListResponse[*ateapi.Actor]{Items: items, NextPageToken: nextToken}, nil } -func (p *Persistence) listActorsScoped(ctx context.Context, atespace string, pageSize int32, pageTokenStr string) ([]*ateapipb.Actor, string, error) { +func (p *Persistence) listActorsScoped(ctx context.Context, atespace string, pageSize int32, pageTokenStr string) ([]*ateapi.Actor, string, error) { token, err := decodePageToken(pageTokenStr, kindActor, atespace, 1) if err != nil { return nil, "", err @@ -209,14 +215,14 @@ func (p *Persistence) listActorsScoped(ctx context.Context, atespace string, pag defer rows.Close() var names []string - var result []*ateapipb.Actor + var result []*ateapi.Actor for rows.Next() { var name string var protoBytes []byte if err := rows.Scan(&name, &protoBytes); err != nil { return nil, "", fmt.Errorf("scanning actor row: %w", err) } - a := &ateapipb.Actor{} + a := &ateapi.Actor{} if err := unmarshalRow(protoBytes, a, "actor", atespace, name); err != nil { return nil, "", err } @@ -235,7 +241,7 @@ func (p *Persistence) listActorsScoped(ctx context.Context, atespace string, pag return result, nextToken, nil } -func (p *Persistence) listActorsGlobal(ctx context.Context, pageSize int32, pageTokenStr string) ([]*ateapipb.Actor, string, error) { +func (p *Persistence) listActorsGlobal(ctx context.Context, pageSize int32, pageTokenStr string) ([]*ateapi.Actor, string, error) { token, err := decodePageToken(pageTokenStr, kindActor, "", 2) if err != nil { return nil, "", err @@ -257,14 +263,14 @@ func (p *Persistence) listActorsGlobal(ctx context.Context, pageSize int32, page type key struct{ atespace, name string } var keys []key - var result []*ateapipb.Actor + var result []*ateapi.Actor for rows.Next() { var k key var protoBytes []byte if err := rows.Scan(&k.atespace, &k.name, &protoBytes); err != nil { return nil, "", fmt.Errorf("scanning actor row: %w", err) } - a := &ateapipb.Actor{} + a := &ateapi.Actor{} if err := unmarshalRow(protoBytes, a, "actor", k.atespace, k.name); err != nil { return nil, "", err } diff --git a/cmd/ateapi/internal/store/atepg/actor_template.go b/cmd/ateapi/internal/store/atepg/actor_template.go index 6a4b95faea..ab808817c5 100644 --- a/cmd/ateapi/internal/store/atepg/actor_template.go +++ b/cmd/ateapi/internal/store/atepg/actor_template.go @@ -20,17 +20,17 @@ import ( "fmt" "github.com/jackc/pgx/v5" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" ) -func (p *Persistence) CreateActorTemplate(ctx context.Context, template *ateapipb.ActorTemplate) (*ateapipb.ActorTemplate, error) { +func (p *Persistence) CreateActorTemplate(ctx context.Context, template *ateapi.ActorTemplate) (*ateapi.ActorTemplate, error) { atespace, name := template.GetMetadata().GetAtespace(), template.GetMetadata().GetName() - dbTemplate := proto.Clone(template).(*ateapipb.ActorTemplate) + dbTemplate := proto.Clone(template).(*ateapi.ActorTemplate) if dbTemplate.Metadata == nil { - dbTemplate.Metadata = &ateapipb.ResourceMetadata{} + dbTemplate.Metadata = &ateapi.ResourceMetadata{} } setCreateMetadata(dbTemplate.Metadata) protoBytes, err := proto.Marshal(dbTemplate) @@ -53,7 +53,7 @@ func (p *Persistence) CreateActorTemplate(ctx context.Context, template *ateapip return dbTemplate, nil } -func (p *Persistence) GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapipb.ActorTemplate, error) { +func (p *Persistence) GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapi.ActorTemplate, error) { var protoBytes []byte err := p.pool.QueryRow(ctx, `SELECT proto FROM actor_templates WHERE atespace = $1 AND name = $2`, templateRef.Atespace, templateRef.Name).Scan(&protoBytes) if err != nil { @@ -62,14 +62,14 @@ func (p *Persistence) GetActorTemplate(ctx context.Context, templateRef resource } return nil, fmt.Errorf("getting actor template %s: %w", templateRef, err) } - out := &ateapipb.ActorTemplate{} + out := &ateapi.ActorTemplate{} if err := unmarshalStored(protoBytes, out); err != nil { return nil, fmt.Errorf("unmarshaling actor template: %w", err) } return out, nil } -func validateUpdateActorTemplateMutation(storedTemplate, mutatedTemplate *ateapipb.ActorTemplate) error { +func validateUpdateActorTemplateMutation(storedTemplate, mutatedTemplate *ateapi.ActorTemplate) error { if stored, mutated := storedTemplate.GetMetadata().GetAtespace(), mutatedTemplate.GetMetadata().GetAtespace(); stored != mutated { return fmt.Errorf("metadata.atespace is immutable: mutation changed it from %q to %q", stored, mutated) } @@ -79,18 +79,18 @@ func validateUpdateActorTemplateMutation(storedTemplate, mutatedTemplate *ateapi return nil } -func (p *Persistence) UpdateActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.Precondition, mutate func(*ateapipb.ActorTemplate) error) (*ateapipb.ActorTemplate, error) { +func (p *Persistence) UpdateActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.Precondition, mutate func(*ateapi.ActorTemplate) error) (*ateapi.ActorTemplate, error) { if err := precondition.Validate(); err != nil { return nil, err } return p.updateActorTemplate(ctx, templateRef, store.DeletePreconditions(precondition), mutate, false) } -func (p *Persistence) MarkActorTemplateForDeletion(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions, mutate func(*ateapipb.ActorTemplate) error) (*ateapipb.ActorTemplate, error) { +func (p *Persistence) MarkActorTemplateForDeletion(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions, mutate func(*ateapi.ActorTemplate) error) (*ateapi.ActorTemplate, error) { return p.updateActorTemplate(ctx, templateRef, precondition, mutate, true) } -func (p *Persistence) updateActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions, mutate func(*ateapipb.ActorTemplate) error, markForDeletion bool) (*ateapipb.ActorTemplate, error) { +func (p *Persistence) updateActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions, mutate func(*ateapi.ActorTemplate) error, markForDeletion bool) (*ateapi.ActorTemplate, error) { var currentUID string var currentVersion int64 var currentBytes []byte @@ -103,7 +103,7 @@ func (p *Persistence) updateActorTemplate(ctx context.Context, templateRef resou return nil, fmt.Errorf("getting actor template %s for update: %w", templateRef, err) } - dbTemplate := &ateapipb.ActorTemplate{} + dbTemplate := &ateapi.ActorTemplate{} if err := unmarshalStored(currentBytes, dbTemplate); err != nil { return nil, fmt.Errorf("unmarshaling actor template for update: %w", err) } @@ -113,7 +113,7 @@ func (p *Persistence) updateActorTemplate(ctx context.Context, templateRef resou if err := precondition.Check(dbTemplate.GetMetadata()); err != nil { return nil, err } - templateBeforeMutation := proto.Clone(dbTemplate).(*ateapipb.ActorTemplate) + templateBeforeMutation := proto.Clone(dbTemplate).(*ateapi.ActorTemplate) if mutate != nil { if err := mutate(dbTemplate); err != nil { return nil, err @@ -123,7 +123,7 @@ func (p *Persistence) updateActorTemplate(ctx context.Context, templateRef resou return nil, err } if dbTemplate.Metadata == nil { - dbTemplate.Metadata = &ateapipb.ResourceMetadata{} + dbTemplate.Metadata = &ateapi.ResourceMetadata{} } setUpdateMetadata(dbTemplate.Metadata, templateBeforeMutation.GetMetadata()) if markForDeletion && dbTemplate.Metadata.DeleteTime == nil { @@ -149,10 +149,10 @@ func (p *Persistence) updateActorTemplate(ctx context.Context, templateRef resou return dbTemplate, nil } -func (p *Persistence) ListActorTemplates(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapipb.ActorTemplate], error) { +func (p *Persistence) ListActorTemplates(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapi.ActorTemplate], error) { opts, err := store.NormalizeListOptions(opts) if err != nil { - return store.ListResponse[*ateapipb.ActorTemplate]{}, err + return store.ListResponse[*ateapi.ActorTemplate]{}, err } pageSize, pageTokenStr := opts.PageSize, opts.PageToken keyParts := 2 @@ -161,7 +161,7 @@ func (p *Persistence) ListActorTemplates(ctx context.Context, atespace string, o } token, err := decodePageToken(pageTokenStr, kindActorTemplate, atespace, keyParts) if err != nil { - return store.ListResponse[*ateapipb.ActorTemplate]{}, err + return store.ListResponse[*ateapi.ActorTemplate]{}, err } var rows pgx.Rows @@ -185,28 +185,28 @@ func (p *Persistence) ListActorTemplates(ctx context.Context, atespace string, o ORDER BY atespace, name LIMIT $3`, lastAtespace, lastName, int64(pageSize)+1) } if err != nil { - return store.ListResponse[*ateapipb.ActorTemplate]{}, fmt.Errorf("listing actor templates: %w", err) + return store.ListResponse[*ateapi.ActorTemplate]{}, fmt.Errorf("listing actor templates: %w", err) } defer rows.Close() type key struct{ atespace, name string } var keys []key - var result []*ateapipb.ActorTemplate + var result []*ateapi.ActorTemplate for rows.Next() { var k key var protoBytes []byte if err := rows.Scan(&k.atespace, &k.name, &protoBytes); err != nil { - return store.ListResponse[*ateapipb.ActorTemplate]{}, fmt.Errorf("scanning actor template row: %w", err) + return store.ListResponse[*ateapi.ActorTemplate]{}, fmt.Errorf("scanning actor template row: %w", err) } - template := &ateapipb.ActorTemplate{} + template := &ateapi.ActorTemplate{} if err := unmarshalRow(protoBytes, template, "actor template", k.atespace, k.name); err != nil { - return store.ListResponse[*ateapipb.ActorTemplate]{}, err + return store.ListResponse[*ateapi.ActorTemplate]{}, err } keys = append(keys, k) result = append(result, template) } if err := rows.Err(); err != nil { - return store.ListResponse[*ateapipb.ActorTemplate]{}, fmt.Errorf("listing actor templates: %w", err) + return store.ListResponse[*ateapi.ActorTemplate]{}, fmt.Errorf("listing actor templates: %w", err) } var nextToken string if len(result) > int(pageSize) { @@ -218,10 +218,10 @@ func (p *Persistence) ListActorTemplates(ctx context.Context, atespace string, o } nextToken = encodePageToken(kindActorTemplate, atespace, lastParts) } - return store.ListResponse[*ateapipb.ActorTemplate]{Items: result, NextPageToken: nextToken}, nil + return store.ListResponse[*ateapi.ActorTemplate]{Items: result, NextPageToken: nextToken}, nil } -func (p *Persistence) DeleteActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions) (*ateapipb.ActorTemplate, error) { +func (p *Persistence) DeleteActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions) (*ateapi.ActorTemplate, error) { var protoBytes []byte err := p.pool.QueryRow(ctx, ` DELETE FROM actor_templates AS t @@ -238,7 +238,7 @@ func (p *Persistence) DeleteActorTemplate(ctx context.Context, templateRef resou if err != nil { return nil, fmt.Errorf("deleting actor template %s: %w", templateRef, err) } - out := &ateapipb.ActorTemplate{} + out := &ateapi.ActorTemplate{} if err := unmarshalStored(protoBytes, out); err != nil { return nil, fmt.Errorf("unmarshaling deleted actor template: %w", err) } diff --git a/cmd/ateapi/internal/store/atepg/actor_template_test.go b/cmd/ateapi/internal/store/atepg/actor_template_test.go index 48954008fe..24e41a0b51 100644 --- a/cmd/ateapi/internal/store/atepg/actor_template_test.go +++ b/cmd/ateapi/internal/store/atepg/actor_template_test.go @@ -21,16 +21,16 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/testing/protocmp" ) func createTestActorTemplate(t *testing.T, s *Persistence, atespace, name string) { t.Helper() - if _, err := s.CreateActorTemplate(context.Background(), &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: name}, + if _, err := s.CreateActorTemplate(context.Background(), &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: name}, }); err != nil { t.Fatalf("CreateActorTemplate(%q/%q) failed: %v", atespace, name, err) } @@ -48,15 +48,15 @@ func TestUpdateActorTemplate_ConcurrentWriteReturnsConflict(t *testing.T) { } mutations := 0 - _, err = s.UpdateActorTemplate(ctx, templateRef, store.PreconditionFrom(created), func(toUpdate *ateapipb.ActorTemplate) error { + _, err = s.UpdateActorTemplate(ctx, templateRef, store.PreconditionFrom(created), func(toUpdate *ateapi.ActorTemplate) error { mutations++ - if _, err := s.UpdateActorTemplate(ctx, templateRef, store.PreconditionFrom(created), func(concurrent *ateapipb.ActorTemplate) error { - concurrent.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}} + if _, err := s.UpdateActorTemplate(ctx, templateRef, store.PreconditionFrom(created), func(concurrent *ateapi.ActorTemplate) error { + concurrent.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}} return nil }); err != nil { return fmt.Errorf("concurrent actor template update: %w", err) } - toUpdate.Status = &ateapipb.ActorTemplateStatus{GoldenSnapshotStatus: &ateapipb.GoldenSnapshotStatus{ + toUpdate.Status = &ateapi.ActorTemplateStatus{GoldenSnapshotStatus: &ateapi.GoldenSnapshotStatus{ ErrorMessage: "LosingUpdate", }} return nil @@ -84,9 +84,9 @@ func TestGetActorTemplate_BackfillsDefaults(t *testing.T) { ctx := context.Background() createTestAtespace(t, s, "team-a") - if _, err := s.CreateActorTemplate(ctx, &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "template-a"}, - SnapshotConfig: &ateapipb.SnapshotConfig{}, + if _, err := s.CreateActorTemplate(ctx, &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "template-a"}, + SnapshotConfig: &ateapi.SnapshotConfig{}, }); err != nil { t.Fatalf("CreateActorTemplate failed: %v", err) } @@ -96,9 +96,9 @@ func TestGetActorTemplate_BackfillsDefaults(t *testing.T) { if err != nil { t.Fatalf("GetActorTemplate failed: %v", err) } - want := &ateapipb.SnapshotConfig{ - PreferredFidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - GoldenSnapshotConfig: &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, + want := &ateapi.SnapshotConfig{ + PreferredFidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + GoldenSnapshotConfig: &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, } if diff := cmp.Diff(want, got.GetSnapshotConfig(), protocmp.Transform()); diff != "" { t.Errorf("GetActorTemplate did not backfill snapshot_config defaults (-want +got):\n%s", diff) diff --git a/cmd/ateapi/internal/store/atepg/actor_test.go b/cmd/ateapi/internal/store/atepg/actor_test.go index 713f91aa30..57f73158d2 100644 --- a/cmd/ateapi/internal/store/atepg/actor_test.go +++ b/cmd/ateapi/internal/store/atepg/actor_test.go @@ -20,19 +20,19 @@ import ( "fmt" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) func TestUpdateActor_ConcurrentWriteReturnsConflict(t *testing.T) { s := setupPostgresPersistence(t) ctx := context.Background() createTestAtespace(t, s, "team-a") - created, err := s.CreateActor(ctx, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "actor-a"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "default", Name: "template-a"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + created, err := s.CreateActor(ctx, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "actor-a"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "default", Name: "template-a"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) if err != nil { t.Fatalf("CreateActor failed: %v", err) @@ -40,15 +40,15 @@ func TestUpdateActor_ConcurrentWriteReturnsConflict(t *testing.T) { actorRef := resources.ActorRefFromActor(created) mutations := 0 - _, err = s.UpdateActor(ctx, actorRef, store.PreconditionFrom(created), func(toUpdate *ateapipb.Actor) error { + _, err = s.UpdateActor(ctx, actorRef, store.PreconditionFrom(created), func(toUpdate *ateapi.Actor) error { mutations++ - if _, err := s.UpdateActor(ctx, actorRef, store.PreconditionFrom(created), func(concurrent *ateapipb.Actor) error { - concurrent.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}} + if _, err := s.UpdateActor(ctx, actorRef, store.PreconditionFrom(created), func(concurrent *ateapi.Actor) error { + concurrent.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}} return nil }); err != nil { return fmt.Errorf("concurrent actor update: %w", err) } - toUpdate.Status.State = ateapipb.ActorState_ACTOR_STATE_RUNNING + toUpdate.Status.State = ateapi.ActorState_ACTOR_STATE_RUNNING return nil }) if !errors.Is(err, store.ErrVersionConflict) { @@ -61,7 +61,7 @@ func TestUpdateActor_ConcurrentWriteReturnsConflict(t *testing.T) { if err != nil { t.Fatalf("GetActor failed: %v", err) } - if stored.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if stored.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("state = %v, want SUSPENDED: losing update was persisted", stored.GetStatus().GetState()) } if got := stored.GetWorkerSelector().GetMatchLabels()["tier"]; got != "paid" { @@ -80,10 +80,10 @@ func TestCreateActor_MissingAtespace_FailedPrecondition(t *testing.T) { s := setupPostgresPersistence(t) ctx := context.Background() - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "id1", Atespace: "no-such-atespace"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "id1", Atespace: "no-such-atespace"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, } if _, err := s.CreateActor(ctx, actor); !errors.Is(err, store.ErrFailedPrecondition) { t.Errorf("CreateActor with missing atespace = %v, want ErrFailedPrecondition", err) @@ -110,7 +110,7 @@ func TestListActors_CrossScopePageToken(t *testing.T) { t.Fatalf("CreateAtespace(team-b) failed: %v", err) } for _, name := range []string{"a1", "a2"} { - if _, err := s.CreateActor(ctx, &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Name: name, Atespace: "team-a"}, Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}}); err != nil { + if _, err := s.CreateActor(ctx, &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Name: name, Atespace: "team-a"}, Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}}); err != nil { t.Fatalf("CreateActor failed: %v", err) } } diff --git a/cmd/ateapi/internal/store/atepg/atepg.go b/cmd/ateapi/internal/store/atepg/atepg.go index 73bde914ce..2a72019644 100644 --- a/cmd/ateapi/internal/store/atepg/atepg.go +++ b/cmd/ateapi/internal/store/atepg/atepg.go @@ -34,10 +34,11 @@ import ( "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgconn" "github.com/jackc/pgx/v5/pgxpool" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/authz" "go.ate.dev/substrate/cmd/ateapi/internal/defaults" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/internal/resources" "go.opentelemetry.io/otel" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" @@ -112,7 +113,7 @@ func (p *Persistence) publishLocally(ctx context.Context, payload []byte) { } for ch := range p.watchers { select { - case ch <- store.WorkerEvent{Type: event.Type, Worker: proto.Clone(event.Worker).(*ateapipb.Worker)}: + case ch <- store.WorkerEvent{Type: event.Type, Worker: proto.Clone(event.Worker).(*ateapi.Worker)}: default: } } @@ -404,7 +405,7 @@ func unmarshalRow(b []byte, m proto.Message, kind string, id ...string) error { return nil } -func setCreateMetadata(metadata *ateapipb.ResourceMetadata) { +func setCreateMetadata(metadata *ateapi.ResourceMetadata) { metadata.Uid = uuid.NewString() metadata.Version = 1 metadata.CreateTime = timestamppb.Now() @@ -414,7 +415,7 @@ func setCreateMetadata(metadata *ateapipb.ResourceMetadata) { // validateProtoMetadataMatchesColumns verifies that the metadata in the database // matches the metadata in the proto. -func validateProtoMetadataMatchesColumns(resource string, metadata *ateapipb.ResourceMetadata, uid string, version int64) error { +func validateProtoMetadataMatchesColumns(resource string, metadata *ateapi.ResourceMetadata, uid string, version int64) error { if metadata.GetUid() != uid { return fmt.Errorf("%s uid projection %q does not match proto metadata uid %q", resource, uid, metadata.GetUid()) } @@ -424,7 +425,21 @@ func validateProtoMetadataMatchesColumns(resource string, metadata *ateapipb.Res return nil } -func setUpdateMetadata(newMeta, oldMeta *ateapipb.ResourceMetadata) { +// validateSnapshotURIs requires the URI of every durable snapshot to parse, so +// readers can rely on resources.ParseSnapshotURI. +func validateSnapshotURIs(resource string, snapshots ...*ateapi.Snapshot) error { + for _, snap := range snapshots { + if snap.GetDurableSnapshot() == nil { + continue + } + if _, err := resources.ParseSnapshotURI(snap.GetDurableSnapshot().GetObject().GetSnapshotUri()); err != nil { + return fmt.Errorf("%s snapshot %s: %w", resource, snap.GetUuid(), err) + } + } + return nil +} + +func setUpdateMetadata(newMeta, oldMeta *ateapi.ResourceMetadata) { newMeta.Uid = oldMeta.Uid newMeta.Version = oldMeta.Version + 1 newMeta.CreateTime = oldMeta.CreateTime @@ -439,7 +454,7 @@ func mapDeleteError(err error, uid string, version int64, precondition store.Del if err != nil { return fmt.Errorf("reading after a guarded delete matched nothing: %w", err) } - if err := precondition.Check(&ateapipb.ResourceMetadata{Uid: uid, Version: version}); err != nil { + if err := precondition.Check(&ateapi.ResourceMetadata{Uid: uid, Version: version}); err != nil { return err } // The row matches the guards now, so it changed between the two statements. diff --git a/cmd/ateapi/internal/store/atepg/atepg_test.go b/cmd/ateapi/internal/store/atepg/atepg_test.go index a1063ba6bd..848c468643 100644 --- a/cmd/ateapi/internal/store/atepg/atepg_test.go +++ b/cmd/ateapi/internal/store/atepg/atepg_test.go @@ -19,8 +19,8 @@ import ( "strings" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // A listing fails as a whole on one undecodable row, so the error has to name @@ -31,14 +31,14 @@ func TestList_NamesAnUndecodableRow(t *testing.T) { createTestAtespace(t, s, "team-a") createTestActorTemplate(t, s, "team-a", "t1") createTestTag(t, s, "team-a", "v1") - if _, err := s.CreateActor(ctx, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "a1", Atespace: "team-a"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + if _, err := s.CreateActor(ctx, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "a1", Atespace: "team-a"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }); err != nil { t.Fatalf("CreateActor failed: %v", err) } - if _, err := s.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "w1"}, + if _, err := s.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "w1"}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "pod", diff --git a/cmd/ateapi/internal/store/atepg/atespace.go b/cmd/ateapi/internal/store/atepg/atespace.go index 12822bb1b5..ab7b8a09a7 100644 --- a/cmd/ateapi/internal/store/atepg/atespace.go +++ b/cmd/ateapi/internal/store/atepg/atespace.go @@ -20,16 +20,16 @@ import ( "fmt" "github.com/jackc/pgx/v5" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" ) -func (p *Persistence) CreateAtespace(ctx context.Context, atespace *ateapipb.Atespace) (*ateapipb.Atespace, error) { +func (p *Persistence) CreateAtespace(ctx context.Context, atespace *ateapi.Atespace) (*ateapi.Atespace, error) { name := atespace.GetMetadata().GetName() - dbAtespace := proto.Clone(atespace).(*ateapipb.Atespace) + dbAtespace := proto.Clone(atespace).(*ateapi.Atespace) setCreateMetadata(dbAtespace.Metadata) protoBytes, err := proto.Marshal(dbAtespace) @@ -50,7 +50,7 @@ func (p *Persistence) CreateAtespace(ctx context.Context, atespace *ateapipb.Ate return dbAtespace, nil } -func (p *Persistence) GetAtespace(ctx context.Context, name string) (*ateapipb.Atespace, error) { +func (p *Persistence) GetAtespace(ctx context.Context, name string) (*ateapi.Atespace, error) { var protoBytes []byte err := p.pool.QueryRow(ctx, `SELECT proto FROM atespaces WHERE name = $1`, name).Scan(&protoBytes) if err != nil { @@ -59,22 +59,22 @@ func (p *Persistence) GetAtespace(ctx context.Context, name string) (*ateapipb.A } return nil, fmt.Errorf("getting atespace %q: %w", name, err) } - out := &ateapipb.Atespace{} + out := &ateapi.Atespace{} if err := unmarshalStored(protoBytes, out); err != nil { return nil, fmt.Errorf("unmarshaling atespace: %w", err) } return out, nil } -func (p *Persistence) ListAtespaces(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapipb.Atespace], error) { +func (p *Persistence) ListAtespaces(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapi.Atespace], error) { opts, err := store.NormalizeListOptions(opts) if err != nil { - return store.ListResponse[*ateapipb.Atespace]{}, err + return store.ListResponse[*ateapi.Atespace]{}, err } pageSize, pageTokenStr := opts.PageSize, opts.PageToken token, err := decodePageToken(pageTokenStr, kindAtespace, "", 1) if err != nil { - return store.ListResponse[*ateapipb.Atespace]{}, err + return store.ListResponse[*ateapi.Atespace]{}, err } var last *string if len(token.Last) > 0 { @@ -87,27 +87,27 @@ func (p *Persistence) ListAtespaces(ctx context.Context, opts store.ListOptions) ORDER BY name LIMIT $2`, last, int64(pageSize)+1) if err != nil { - return store.ListResponse[*ateapipb.Atespace]{}, fmt.Errorf("listing atespaces: %w", err) + return store.ListResponse[*ateapi.Atespace]{}, fmt.Errorf("listing atespaces: %w", err) } defer rows.Close() var names []string - var result []*ateapipb.Atespace + var result []*ateapi.Atespace for rows.Next() { var name string var protoBytes []byte if err := rows.Scan(&name, &protoBytes); err != nil { - return store.ListResponse[*ateapipb.Atespace]{}, fmt.Errorf("scanning atespace row: %w", err) + return store.ListResponse[*ateapi.Atespace]{}, fmt.Errorf("scanning atespace row: %w", err) } - a := &ateapipb.Atespace{} + a := &ateapi.Atespace{} if err := unmarshalRow(protoBytes, a, "atespace", name); err != nil { - return store.ListResponse[*ateapipb.Atespace]{}, err + return store.ListResponse[*ateapi.Atespace]{}, err } result = append(result, a) names = append(names, name) } if err := rows.Err(); err != nil { - return store.ListResponse[*ateapipb.Atespace]{}, fmt.Errorf("listing atespaces: %w", err) + return store.ListResponse[*ateapi.Atespace]{}, fmt.Errorf("listing atespaces: %w", err) } var nextToken string @@ -115,10 +115,10 @@ func (p *Persistence) ListAtespaces(ctx context.Context, opts store.ListOptions) result = result[:pageSize] nextToken = encodePageToken(kindAtespace, "", []string{names[pageSize-1]}) } - return store.ListResponse[*ateapipb.Atespace]{Items: result, NextPageToken: nextToken}, nil + return store.ListResponse[*ateapi.Atespace]{Items: result, NextPageToken: nextToken}, nil } -func (p *Persistence) DeleteAtespace(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapipb.Atespace, error) { +func (p *Persistence) DeleteAtespace(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.Atespace, error) { tx, err := p.pool.Begin(ctx) if err != nil { return nil, fmt.Errorf("beginning atespace delete: %w", err) @@ -150,7 +150,7 @@ func (p *Persistence) DeleteAtespace(ctx context.Context, name string, precondit if err := tx.Commit(ctx); err != nil { return nil, fmt.Errorf("committing atespace delete %q: %w", name, err) } - out := &ateapipb.Atespace{} + out := &ateapi.Atespace{} if err := unmarshalStored(protoBytes, out); err != nil { return nil, fmt.Errorf("unmarshaling deleted atespace: %w", err) } diff --git a/cmd/ateapi/internal/store/atepg/common_test.go b/cmd/ateapi/internal/store/atepg/common_test.go index acf24efd93..30a21388ba 100644 --- a/cmd/ateapi/internal/store/atepg/common_test.go +++ b/cmd/ateapi/internal/store/atepg/common_test.go @@ -18,9 +18,9 @@ import ( "context" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/authz" "go.ate.dev/substrate/internal/installdefaults" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // clearAll truncates every table so the next test starts from an empty store @@ -68,8 +68,8 @@ func setTestPolicyManager(t *testing.T, p *Persistence) { p.SetPolicyManager(policyManager) } -func newTestAtespace(name string) *ateapipb.Atespace { - return &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: name}} +func newTestAtespace(name string) *ateapi.Atespace { + return &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: name}} } func createTestAtespace(t *testing.T, s *Persistence, name string) { diff --git a/cmd/ateapi/internal/store/atepg/egress_policy.go b/cmd/ateapi/internal/store/atepg/egress_policy.go index d9ed4ee795..9c90729282 100644 --- a/cmd/ateapi/internal/store/atepg/egress_policy.go +++ b/cmd/ateapi/internal/store/atepg/egress_policy.go @@ -20,15 +20,15 @@ import ( "fmt" "github.com/jackc/pgx/v5" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" ) -func (p *Persistence) CreateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, policy *ateapipb.EgressPolicy) (*ateapipb.EgressPolicy, error) { - dbPolicy := proto.Clone(policy).(*ateapipb.EgressPolicy) +func (p *Persistence) CreateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, policy *ateapi.EgressPolicy) (*ateapi.EgressPolicy, error) { + dbPolicy := proto.Clone(policy).(*ateapi.EgressPolicy) setCreateMetadata(dbPolicy.Metadata) protoBytes, err := proto.Marshal(dbPolicy) if err != nil { @@ -49,13 +49,13 @@ func (p *Persistence) CreateEgressPolicy(ctx context.Context, actorRef resources return dbPolicy, nil } -func (p *Persistence) GetEgressPolicy(ctx context.Context, actorRef resources.ActorRef) (*ateapipb.EgressPolicy, error) { +func (p *Persistence) GetEgressPolicy(ctx context.Context, actorRef resources.ActorRef) (*ateapi.EgressPolicy, error) { return getEgressPolicyRow(ctx, p.pool, ` SELECT uid, version, proto FROM actor_egress_policies WHERE atespace = $1 AND actor_name = $2`, actorRef.Atespace, actorRef.Name) } -func (p *Persistence) UpdateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(*ateapipb.EgressPolicy) error) (*ateapipb.EgressPolicy, error) { +func (p *Persistence) UpdateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition store.Precondition, mutate func(*ateapi.EgressPolicy) error) (*ateapi.EgressPolicy, error) { if err := precondition.Validate(); err != nil { return nil, err } @@ -96,7 +96,7 @@ func (p *Persistence) UpdateEgressPolicy(ctx context.Context, actorRef resources return dbPolicy, nil } -func (p *Persistence) DeleteEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (*ateapipb.EgressPolicy, error) { +func (p *Persistence) DeleteEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition store.DeletePreconditions) (*ateapi.EgressPolicy, error) { var version int64 var uid string var protoBytes []byte @@ -121,7 +121,7 @@ func (p *Persistence) DeleteEgressPolicy(ctx context.Context, actorRef resources return deleted, nil } -func getEgressPolicyRow(ctx context.Context, q querier, query string, args ...any) (*ateapipb.EgressPolicy, error) { +func getEgressPolicyRow(ctx context.Context, q querier, query string, args ...any) (*ateapi.EgressPolicy, error) { var uid string var version int64 var protoBytes []byte @@ -134,8 +134,8 @@ func getEgressPolicyRow(ctx context.Context, q querier, query string, args ...an return unmarshalEgressPolicy(uid, version, protoBytes) } -func unmarshalEgressPolicy(uid string, version int64, protoBytes []byte) (*ateapipb.EgressPolicy, error) { - policy := &ateapipb.EgressPolicy{} +func unmarshalEgressPolicy(uid string, version int64, protoBytes []byte) (*ateapi.EgressPolicy, error) { + policy := &ateapi.EgressPolicy{} if err := unmarshalStored(protoBytes, policy); err != nil { return nil, fmt.Errorf("unmarshaling egress policy: %w", err) } diff --git a/cmd/ateapi/internal/store/atepg/outbox.go b/cmd/ateapi/internal/store/atepg/outbox.go index 3d1e71de45..058b01ef27 100644 --- a/cmd/ateapi/internal/store/atepg/outbox.go +++ b/cmd/ateapi/internal/store/atepg/outbox.go @@ -29,15 +29,15 @@ import ( "time" "github.com/jackc/pgx/v5" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" ) // Outbox payload format: one event-type byte followed by the binary Worker proto. // The tag byte is read by other replicas during rolling deploys, so // store.WorkerEventType values must stay append-only stable and fit a byte. -func marshalWorkerEvent(eventType store.WorkerEventType, worker *ateapipb.Worker) ([]byte, error) { +func marshalWorkerEvent(eventType store.WorkerEventType, worker *ateapi.Worker) ([]byte, error) { b, err := proto.Marshal(worker) if err != nil { return nil, fmt.Errorf("in proto.Marshal: %w", err) @@ -58,7 +58,7 @@ func unmarshalWorkerEvent(payload []byte) (store.WorkerEvent, error) { default: return store.WorkerEvent{}, fmt.Errorf("unknown worker event type byte %d", payload[0]) } - worker := &ateapipb.Worker{} + worker := &ateapi.Worker{} if err := unmarshalStored(payload[1:], worker); err != nil { return store.WorkerEvent{}, fmt.Errorf("in unmarshalStored: %w", err) } @@ -76,7 +76,7 @@ func unmarshalWorkerEvent(payload []byte) (store.WorkerEvent, error) { // committed. The worker comes from fn rather than from the caller because an // update only knows what it wrote once its mutation has run inside the // transaction. -func (p *Persistence) writeAndAppendEvent(ctx context.Context, eventType store.WorkerEventType, fn func(ctx context.Context, tx pgx.Tx) (*ateapipb.Worker, error)) (*ateapipb.Worker, error) { +func (p *Persistence) writeAndAppendEvent(ctx context.Context, eventType store.WorkerEventType, fn func(ctx context.Context, tx pgx.Tx) (*ateapi.Worker, error)) (*ateapi.Worker, error) { tx, err := p.pool.Begin(ctx) if err != nil { return nil, fmt.Errorf("beginning transaction: %w", err) diff --git a/cmd/ateapi/internal/store/atepg/outbox_test.go b/cmd/ateapi/internal/store/atepg/outbox_test.go index e700131ae7..c2df12c862 100644 --- a/cmd/ateapi/internal/store/atepg/outbox_test.go +++ b/cmd/ateapi/internal/store/atepg/outbox_test.go @@ -30,8 +30,8 @@ import ( "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // TestConnect_DedicatedWatchPool covers the auxiliary-pool path only Connect @@ -70,8 +70,8 @@ func TestConnect_DedicatedWatchPool(t *testing.T) { t.Fatalf("WatchWorkers failed: %v", err) } defer watch.Close() - worker := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "watchpool-worker"}, + worker := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "watchpool-worker"}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "watchpool-pod", @@ -104,8 +104,8 @@ func TestWorkerEvent_OnlyAfterCommit(t *testing.T) { defer watch.Close() const workerName = "6e4d2f81-b3a9-4c05-8e72-1f9d4a0c7b63" - worker := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: workerName}, + worker := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: workerName}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "pod", @@ -153,10 +153,10 @@ func TestWorkerEvent_OnlyAfterCommit(t *testing.T) { t.Errorf("expected WorkerEventCreated, got %v", event.Type) } // CreateWorker assigns the uid, version and timestamps server-side. - want := proto.Clone(worker).(*ateapipb.Worker) + want := proto.Clone(worker).(*ateapi.Worker) want.Metadata.Version = 1 if diff := cmp.Diff(want, event.Worker, protocmp.Transform(), - protocmp.IgnoreFields(&ateapipb.ResourceMetadata{}, "uid", "create_time", "update_time")); diff != "" { + protocmp.IgnoreFields(&ateapi.ResourceMetadata{}, "uid", "create_time", "update_time")); diff != "" { t.Errorf("event worker mismatch (-want +got):\n%s", diff) } case <-time.After(2 * time.Second): @@ -183,8 +183,8 @@ func TestWatchWorkers_OutOfOrderCommitNotSkipped(t *testing.T) { mkPayload := func(pod string) []byte { payload, err := marshalWorkerEvent(store.WorkerEventCreated, - &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: pod}, + &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: pod}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: pod, }) if err != nil { @@ -356,8 +356,8 @@ func TestWorkerEvents_OneRowPerTransaction(t *testing.T) { s := setupPostgresPersistence(t) ctx := context.Background() - worker := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "one-row-worker"}, + worker := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "one-row-worker"}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "pod", @@ -370,7 +370,7 @@ func TestWorkerEvents_OneRowPerTransaction(t *testing.T) { if err != nil { t.Fatalf("GetWorker failed: %v", err) } - if _, err := s.UpdateWorker(ctx, "one-row-worker", store.PreconditionFrom(stored), func(*ateapipb.Worker) error { + if _, err := s.UpdateWorker(ctx, "one-row-worker", store.PreconditionFrom(stored), func(*ateapi.Worker) error { return nil }); err != nil { t.Fatalf("UpdateWorker %d failed: %v", i, err) @@ -413,8 +413,8 @@ func TestWatchWorkers_DeliveryFencedByOldestTransaction(t *testing.T) { t.Fatalf("assigning blocker xid failed: %v", err) } - worker := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "fenced-worker"}, + worker := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "fenced-worker"}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "fenced", @@ -627,8 +627,8 @@ func TestWatchWorkers_ClosesWhenTrimmedPastCursor(t *testing.T) { defer watch.Close() // Deliver one event normally so the cursor is established. - worker := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "trim-worker"}, + worker := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "trim-worker"}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "pod", @@ -712,8 +712,8 @@ func TestPartitionCreation_UnwedgesFromStrayedDefault(t *testing.T) { t.Fatalf("dropping current partition: %v", err) } // A write during the stall detours into DEFAULT. - worker := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "wedge-worker"}, + worker := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "wedge-worker"}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "wedge-pod", @@ -797,8 +797,8 @@ func TestOutboxMaintenance_NoDeadlockWithConcurrentWriters(t *testing.T) { go func(g int) { defer wg.Done() for i := 0; writerCtx.Err() == nil; i++ { - w := &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: fmt.Sprintf("ddl-worker-%d-%d", g, i)}, + w := &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: fmt.Sprintf("ddl-worker-%d-%d", g, i)}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: fmt.Sprintf("ddl-pod-%d-%d", g, i), } if _, err := s.CreateWorker(writerCtx, w); err != nil && writerCtx.Err() == nil { @@ -929,8 +929,8 @@ func TestWatchWorkers_BaselineDoesNotMaskOwedTrims(t *testing.T) { // C: a LATER xid that commits BEFORE the subscribe — the baseline poison: // a visible outbox row whose xid exceeds W's. - if _, err := s.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "baseline-poison"}, + if _, err := s.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "baseline-poison"}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "baseline-pod", }); err != nil { t.Fatalf("CreateWorker (C): %v", err) @@ -977,8 +977,8 @@ func TestWatchWorkers_BaselineDoesNotMaskOwedTrims(t *testing.T) { // TestUnmarshalWorkerEvent_BoundaryAssertions pins the write-side invariants // asserted at the read boundary: known event-type byte and a keyable worker. func TestUnmarshalWorkerEvent_BoundaryAssertions(t *testing.T) { - valid, err := marshalWorkerEvent(store.WorkerEventUpdated, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "w1"}, + valid, err := marshalWorkerEvent(store.WorkerEventUpdated, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "w1"}, }) if err != nil { t.Fatalf("marshal: %v", err) @@ -992,7 +992,7 @@ func TestUnmarshalWorkerEvent_BoundaryAssertions(t *testing.T) { "unknown type byte": {[]byte{0xff, 0x00}, true}, "type byte only": {[]byte{byte(store.WorkerEventCreated)}, true}, // empty proto = nameless "garbage proto": {append([]byte{byte(store.WorkerEventCreated)}, 0xde, 0xad, 0xbe), true}, - "nameless worker": {func() []byte { b, _ := marshalWorkerEvent(store.WorkerEventDeleted, &ateapipb.Worker{}); return b }(), true}, + "nameless worker": {func() []byte { b, _ := marshalWorkerEvent(store.WorkerEventDeleted, &ateapi.Worker{}); return b }(), true}, } { t.Run(name, func(t *testing.T) { _, err := unmarshalWorkerEvent(tc.payload) @@ -1076,8 +1076,8 @@ func TestLocalPublishReachesWatchers(t *testing.T) { } } - created, err := p.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "local-publish-worker"}, + created, err := p.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "local-publish-worker"}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "pod", @@ -1090,7 +1090,7 @@ func TestLocalPublishReachesWatchers(t *testing.T) { t.Errorf("created event version = %d, want committed version %d", got, want) } - updated, err := p.UpdateWorker(ctx, created.GetMetadata().GetName(), store.PreconditionFrom(created), func(toUpdate *ateapipb.Worker) error { + updated, err := p.UpdateWorker(ctx, created.GetMetadata().GetName(), store.PreconditionFrom(created), func(toUpdate *ateapi.Worker) error { toUpdate.Labels = map[string]string{"tier": "batch"} return nil }) @@ -1144,8 +1144,8 @@ func TestLocalPublishSurvivesWatchClose(t *testing.T) { watch.Close() }() name := fmt.Sprintf("close-race-worker-%d", i) - w, err := p.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: name}, + w, err := p.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: name}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "pod", diff --git a/cmd/ateapi/internal/store/atepg/tag.go b/cmd/ateapi/internal/store/atepg/tag.go index a90190ed21..d5cca85516 100644 --- a/cmd/ateapi/internal/store/atepg/tag.go +++ b/cmd/ateapi/internal/store/atepg/tag.go @@ -20,13 +20,13 @@ import ( "fmt" "github.com/jackc/pgx/v5" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" ) -func (p *Persistence) GetTag(ctx context.Context, tagRef resources.TagRef) (*ateapipb.Tag, error) { +func (p *Persistence) GetTag(ctx context.Context, tagRef resources.TagRef) (*ateapi.Tag, error) { atespace, name := tagRef.Atespace, tagRef.Name var protoBytes []byte if err := p.pool.QueryRow(ctx, ` @@ -37,19 +37,19 @@ func (p *Persistence) GetTag(ctx context.Context, tagRef resources.TagRef) (*ate } return nil, fmt.Errorf("getting tag %s/%s: %w", atespace, name, err) } - tag := &ateapipb.Tag{} + tag := &ateapi.Tag{} if err := unmarshalStored(protoBytes, tag); err != nil { return nil, fmt.Errorf("unmarshaling tag: %w", err) } return tag, nil } -func (p *Persistence) ListTags(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapipb.Tag], error) { +func (p *Persistence) ListTags(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapi.Tag], error) { opts, err := store.NormalizeListOptions(opts) if err != nil { - return store.ListResponse[*ateapipb.Tag]{}, err + return store.ListResponse[*ateapi.Tag]{}, err } - var items []*ateapipb.Tag + var items []*ateapi.Tag var nextToken string if atespace != "" { items, nextToken, err = p.listTagsScoped(ctx, atespace, opts.PageSize, opts.PageToken) @@ -57,12 +57,12 @@ func (p *Persistence) ListTags(ctx context.Context, atespace string, opts store. items, nextToken, err = p.listTagsGlobal(ctx, opts.PageSize, opts.PageToken) } if err != nil { - return store.ListResponse[*ateapipb.Tag]{}, err + return store.ListResponse[*ateapi.Tag]{}, err } - return store.ListResponse[*ateapipb.Tag]{Items: items, NextPageToken: nextToken}, nil + return store.ListResponse[*ateapi.Tag]{Items: items, NextPageToken: nextToken}, nil } -func (p *Persistence) listTagsScoped(ctx context.Context, atespace string, pageSize int32, pageTokenStr string) ([]*ateapipb.Tag, string, error) { +func (p *Persistence) listTagsScoped(ctx context.Context, atespace string, pageSize int32, pageTokenStr string) ([]*ateapi.Tag, string, error) { token, err := decodePageToken(pageTokenStr, kindTag, atespace, 1) if err != nil { return nil, "", err @@ -82,14 +82,14 @@ func (p *Persistence) listTagsScoped(ctx context.Context, atespace string, pageS defer rows.Close() var names []string - var result []*ateapipb.Tag + var result []*ateapi.Tag for rows.Next() { var name string var protoBytes []byte if err := rows.Scan(&name, &protoBytes); err != nil { return nil, "", fmt.Errorf("scanning tag row: %w", err) } - tag := &ateapipb.Tag{} + tag := &ateapi.Tag{} if err := unmarshalRow(protoBytes, tag, "tag", atespace, name); err != nil { return nil, "", err } @@ -107,7 +107,7 @@ func (p *Persistence) listTagsScoped(ctx context.Context, atespace string, pageS return result, nextToken, nil } -func (p *Persistence) listTagsGlobal(ctx context.Context, pageSize int32, pageTokenStr string) ([]*ateapipb.Tag, string, error) { +func (p *Persistence) listTagsGlobal(ctx context.Context, pageSize int32, pageTokenStr string) ([]*ateapi.Tag, string, error) { token, err := decodePageToken(pageTokenStr, kindTag, "", 2) if err != nil { return nil, "", err @@ -128,14 +128,14 @@ func (p *Persistence) listTagsGlobal(ctx context.Context, pageSize int32, pageTo type key struct{ atespace, name string } var keys []key - var result []*ateapipb.Tag + var result []*ateapi.Tag for rows.Next() { var k key var protoBytes []byte if err := rows.Scan(&k.atespace, &k.name, &protoBytes); err != nil { return nil, "", fmt.Errorf("scanning tag row: %w", err) } - tag := &ateapipb.Tag{} + tag := &ateapi.Tag{} if err := unmarshalRow(protoBytes, tag, "tag", k.atespace, k.name); err != nil { return nil, "", err } @@ -154,11 +154,14 @@ func (p *Persistence) listTagsGlobal(ctx context.Context, pageSize int32, pageTo return result, nextToken, nil } -func (p *Persistence) CreateTag(ctx context.Context, tag *ateapipb.Tag) (*ateapipb.Tag, error) { +func (p *Persistence) CreateTag(ctx context.Context, tag *ateapi.Tag) (*ateapi.Tag, error) { atespace := tag.GetMetadata().GetAtespace() name := tag.GetMetadata().GetName() dbTag := proto.CloneOf(tag) setCreateMetadata(dbTag.Metadata) + if err := validateSnapshotURIs(fmt.Sprintf("tag %s/%s", atespace, name), dbTag.GetStatus().GetSnapshot()); err != nil { + return nil, err + } protoBytes, err := proto.Marshal(dbTag) if err != nil { return nil, fmt.Errorf("marshaling tag: %w", err) @@ -185,23 +188,23 @@ func (p *Persistence) CreateTag(ctx context.Context, tag *ateapipb.Tag) (*ateapi return dbTag, nil } -func isAllowedTagSnapshotTransition(stored, mutated *ateapipb.Snapshot) bool { +func isAllowedTagSnapshotTransition(stored, mutated *ateapi.Snapshot) bool { if proto.Equal(stored, mutated) || stored == nil { return true } if mutated == nil || stored.GetDurableSnapshot() == nil || mutated.GetDurableSnapshot() == nil { return false } - if stored.GetDurableSnapshot().GetStatus() != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING || - mutated.GetDurableSnapshot().GetStatus() != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { + if stored.GetDurableSnapshot().GetStatus() != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING || + mutated.GetDurableSnapshot().GetStatus() != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { return false } expected := proto.CloneOf(stored) - expected.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + expected.DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED return proto.Equal(expected, mutated) } -func validateUpdateTagMutation(storedTag, mutatedTag *ateapipb.Tag) error { +func validateUpdateTagMutation(storedTag, mutatedTag *ateapi.Tag) error { if stored, mutated := storedTag.GetMetadata().GetAtespace(), mutatedTag.GetMetadata().GetAtespace(); stored != mutated { return fmt.Errorf("metadata.atespace is immutable: mutation changed it from %q to %q", stored, mutated) } @@ -217,18 +220,18 @@ func validateUpdateTagMutation(storedTag, mutatedTag *ateapipb.Tag) error { return nil } -func (p *Persistence) UpdateTag(ctx context.Context, tagRef resources.TagRef, precondition store.Precondition, mutate func(*ateapipb.Tag) error) (*ateapipb.Tag, error) { +func (p *Persistence) UpdateTag(ctx context.Context, tagRef resources.TagRef, precondition store.Precondition, mutate func(*ateapi.Tag) error) (*ateapi.Tag, error) { if err := precondition.Validate(); err != nil { return nil, err } return p.updateTag(ctx, tagRef, store.DeletePreconditions(precondition), mutate, false) } -func (p *Persistence) MarkTagForDeletion(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions, mutate func(*ateapipb.Tag) error) (*ateapipb.Tag, error) { +func (p *Persistence) MarkTagForDeletion(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions, mutate func(*ateapi.Tag) error) (*ateapi.Tag, error) { return p.updateTag(ctx, tagRef, precondition, mutate, true) } -func (p *Persistence) updateTag(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions, mutate func(*ateapipb.Tag) error, markForDeletion bool) (*ateapipb.Tag, error) { +func (p *Persistence) updateTag(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions, mutate func(*ateapi.Tag) error, markForDeletion bool) (*ateapi.Tag, error) { atespace, name := tagRef.Atespace, tagRef.Name var currentUID string var currentVersion int64 @@ -242,7 +245,7 @@ func (p *Persistence) updateTag(ctx context.Context, tagRef resources.TagRef, pr return nil, fmt.Errorf("getting tag %s/%s for update: %w", atespace, name, err) } - dbTag := &ateapipb.Tag{} + dbTag := &ateapi.Tag{} if err := unmarshalStored(currentBytes, dbTag); err != nil { return nil, fmt.Errorf("unmarshaling tag: %w", err) } @@ -252,7 +255,7 @@ func (p *Persistence) updateTag(ctx context.Context, tagRef resources.TagRef, pr if err := precondition.Check(dbTag.GetMetadata()); err != nil { return nil, err } - tagBeforeMutation := proto.Clone(dbTag).(*ateapipb.Tag) + tagBeforeMutation := proto.Clone(dbTag).(*ateapi.Tag) oldMeta := proto.CloneOf(dbTag.Metadata) if mutate != nil { if err := mutate(dbTag); err != nil { @@ -263,6 +266,9 @@ func (p *Persistence) updateTag(ctx context.Context, tagRef resources.TagRef, pr if err := validateUpdateTagMutation(tagBeforeMutation, dbTag); err != nil { return nil, fmt.Errorf("%w: %w", store.ErrImmutableField, err) } + if err := validateSnapshotURIs(fmt.Sprintf("tag %s/%s", atespace, name), dbTag.GetStatus().GetSnapshot()); err != nil { + return nil, err + } // Stored metadata is authoritative; discard any metadata edits made by the // closure and derive the next revision from the state this attempt read. setUpdateMetadata(dbTag.Metadata, oldMeta) @@ -291,7 +297,7 @@ func (p *Persistence) updateTag(ctx context.Context, tagRef resources.TagRef, pr return dbTag, nil } -func (p *Persistence) DeleteTag(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions) (*ateapipb.Tag, error) { +func (p *Persistence) DeleteTag(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions) (*ateapi.Tag, error) { atespace, name := tagRef.Atespace, tagRef.Name var protoBytes []byte err := p.pool.QueryRow(ctx, ` @@ -309,7 +315,7 @@ func (p *Persistence) DeleteTag(ctx context.Context, tagRef resources.TagRef, pr if err != nil { return nil, fmt.Errorf("deleting tag %s/%s: %w", atespace, name, err) } - tag := &ateapipb.Tag{} + tag := &ateapi.Tag{} if err := unmarshalStored(protoBytes, tag); err != nil { return nil, fmt.Errorf("unmarshaling deleted tag: %w", err) } diff --git a/cmd/ateapi/internal/store/atepg/tag_test.go b/cmd/ateapi/internal/store/atepg/tag_test.go index 315fa8b68b..1b65f7ef0f 100644 --- a/cmd/ateapi/internal/store/atepg/tag_test.go +++ b/cmd/ateapi/internal/store/atepg/tag_test.go @@ -21,27 +21,27 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/testing/protocmp" ) // createTestTag creates tagName over its own copy of an actor's // external snapshot, already finalized. -func createTestTag(t *testing.T, s *Persistence, tagAtespace, tagName string) *ateapipb.Tag { +func createTestTag(t *testing.T, s *Persistence, tagAtespace, tagName string) *ateapi.Tag { t.Helper() - tag, err := s.CreateTag(context.Background(), &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: tagAtespace, Name: tagName}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - Status: &ateapipb.TagStatus{ - Snapshot: &ateapipb.Snapshot{ + tag, err := s.CreateTag(context.Background(), &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: tagAtespace, Name: tagName}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + Status: &ateapi.TagStatus{ + Snapshot: &ateapi.Snapshot{ Generation: 1, - Owner: ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - DurableSnapshot: &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: "gs://bucket/atespaces/" + tagAtespace + "/tags/" + tagName}, + Owner: ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + DurableSnapshot: &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, + Object: &ateapi.ObjectSnapshot{SnapshotUri: "gs://bucket/atespaces/" + tagAtespace + "/tags/" + tagName}, }, }, }, @@ -59,14 +59,14 @@ func TestUpdateTag_CASPreventsDeleteRecreateABA(t *testing.T) { original := createTestTag(t, s, "team-a", "tag-a") mutations := 0 - var recreated *ateapipb.Tag - _, err := s.UpdateTag(ctx, resources.TagRef{Atespace: "team-a", Name: "tag-a"}, store.PreconditionFrom(original), func(toUpdate *ateapipb.Tag) error { + var recreated *ateapi.Tag + _, err := s.UpdateTag(ctx, resources.TagRef{Atespace: "team-a", Name: "tag-a"}, store.PreconditionFrom(original), func(toUpdate *ateapi.Tag) error { mutations++ if _, err := s.DeleteTag(ctx, resources.TagRef{Atespace: "team-a", Name: "tag-a"}, store.DeletePreconditions{}); err != nil { return fmt.Errorf("deleting original tag: %w", err) } recreated = createTestTag(t, s, "team-a", "tag-a") - toUpdate.Scope = ateapipb.TagScope_TAG_SCOPE_PUBLISHED + toUpdate.Scope = ateapi.TagScope_TAG_SCOPE_PUBLISHED return nil }) if !errors.Is(err, store.ErrVersionConflict) { @@ -90,9 +90,9 @@ func TestCreateTag_TagForeignKeyErrors(t *testing.T) { createTestAtespace(t, s, "team-a") // A tag in an atespace that does not exist trips the tag's atespace FK. - _, err := s.CreateTag(ctx, &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "gone", Name: "latest"}, - Status: &ateapipb.TagStatus{}, + _, err := s.CreateTag(ctx, &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: "gone", Name: "latest"}, + Status: &ateapi.TagStatus{}, }) if !errors.Is(err, store.ErrFailedPrecondition) { t.Errorf("missing tag atespace error = %v, want ErrFailedPrecondition", err) diff --git a/cmd/ateapi/internal/store/atepg/worker.go b/cmd/ateapi/internal/store/atepg/worker.go index 03e4027d58..6fa626a9a0 100644 --- a/cmd/ateapi/internal/store/atepg/worker.go +++ b/cmd/ateapi/internal/store/atepg/worker.go @@ -20,15 +20,15 @@ import ( "fmt" "github.com/jackc/pgx/v5" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" ) -func (p *Persistence) CreateWorker(ctx context.Context, worker *ateapipb.Worker) (*ateapipb.Worker, error) { - dbWorker := proto.Clone(worker).(*ateapipb.Worker) +func (p *Persistence) CreateWorker(ctx context.Context, worker *ateapi.Worker) (*ateapi.Worker, error) { + dbWorker := proto.Clone(worker).(*ateapi.Worker) if dbWorker.Metadata == nil { - dbWorker.Metadata = &ateapipb.ResourceMetadata{} + dbWorker.Metadata = &ateapi.ResourceMetadata{} } setCreateMetadata(dbWorker.Metadata) @@ -37,7 +37,7 @@ func (p *Persistence) CreateWorker(ctx context.Context, worker *ateapipb.Worker) return nil, fmt.Errorf("marshaling worker: %w", err) } - created, err := p.writeAndAppendEvent(ctx, store.WorkerEventCreated, func(ctx context.Context, tx pgx.Tx) (*ateapipb.Worker, error) { + created, err := p.writeAndAppendEvent(ctx, store.WorkerEventCreated, func(ctx context.Context, tx pgx.Tx) (*ateapi.Worker, error) { _, err := tx.Exec(ctx, ` INSERT INTO workers (name, uid, version, proto) VALUES ($1, $2, $3, $4)`, @@ -56,7 +56,7 @@ func (p *Persistence) CreateWorker(ctx context.Context, worker *ateapipb.Worker) return created, nil } -func getWorkerRow(ctx context.Context, q querier, name string) (*ateapipb.Worker, error) { +func getWorkerRow(ctx context.Context, q querier, name string) (*ateapi.Worker, error) { var protoBytes []byte err := q.QueryRow(ctx, `SELECT proto FROM workers WHERE name = $1`, name).Scan(&protoBytes) if err != nil { @@ -65,21 +65,21 @@ func getWorkerRow(ctx context.Context, q querier, name string) (*ateapipb.Worker } return nil, fmt.Errorf("getting worker %s: %w", name, err) } - out := &ateapipb.Worker{} + out := &ateapi.Worker{} if err := unmarshalStored(protoBytes, out); err != nil { return nil, fmt.Errorf("unmarshaling worker: %w", err) } return out, nil } -func (p *Persistence) GetWorker(ctx context.Context, name string) (*ateapipb.Worker, error) { +func (p *Persistence) GetWorker(ctx context.Context, name string) (*ateapi.Worker, error) { return getWorkerRow(ctx, p.pool, name) } // getWorkerRowForUpdate reads the worker and holds its row lock for the rest of // tx, so nothing else can write the row between this read and the write that // follows it. -func getWorkerRowForUpdate(ctx context.Context, tx pgx.Tx, name string) (*ateapipb.Worker, error) { +func getWorkerRowForUpdate(ctx context.Context, tx pgx.Tx, name string) (*ateapi.Worker, error) { var protoBytes []byte if err := tx.QueryRow(ctx, `SELECT proto FROM workers WHERE name = $1 FOR UPDATE`, name).Scan(&protoBytes); err != nil { if errors.Is(err, pgx.ErrNoRows) { @@ -87,7 +87,7 @@ func getWorkerRowForUpdate(ctx context.Context, tx pgx.Tx, name string) (*ateapi } return nil, fmt.Errorf("locking worker %s for update: %w", name, err) } - out := &ateapipb.Worker{} + out := &ateapi.Worker{} if err := unmarshalStored(protoBytes, out); err != nil { return nil, fmt.Errorf("unmarshaling worker: %w", err) } @@ -99,19 +99,19 @@ func getWorkerRowForUpdate(ctx context.Context, tx pgx.Tx, name string) (*ateapi // interleaving. That is what makes an occupancy test inside mutate a // compare-and-set. The predicate cannot be pushed into SQL: the row stores an // opaque marshaled proto, so assignment is not addressable in a WHERE clause. -func (p *Persistence) UpdateWorker(ctx context.Context, name string, precondition store.Precondition, mutate func(*ateapipb.Worker) error) (*ateapipb.Worker, error) { +func (p *Persistence) UpdateWorker(ctx context.Context, name string, precondition store.Precondition, mutate func(*ateapi.Worker) error) (*ateapi.Worker, error) { if err := precondition.Validate(); err != nil { return nil, err } return p.updateWorker(ctx, name, store.DeletePreconditions(precondition), mutate, false) } -func (p *Persistence) MarkWorkerForDeletion(ctx context.Context, name string, precondition store.DeletePreconditions, mutate func(*ateapipb.Worker) error) (*ateapipb.Worker, error) { +func (p *Persistence) MarkWorkerForDeletion(ctx context.Context, name string, precondition store.DeletePreconditions, mutate func(*ateapi.Worker) error) (*ateapi.Worker, error) { return p.updateWorker(ctx, name, precondition, mutate, true) } -func (p *Persistence) updateWorker(ctx context.Context, name string, precondition store.DeletePreconditions, mutate func(*ateapipb.Worker) error, markForDeletion bool) (*ateapipb.Worker, error) { - return p.writeAndAppendEvent(ctx, store.WorkerEventUpdated, func(ctx context.Context, tx pgx.Tx) (*ateapipb.Worker, error) { +func (p *Persistence) updateWorker(ctx context.Context, name string, precondition store.DeletePreconditions, mutate func(*ateapi.Worker) error, markForDeletion bool) (*ateapi.Worker, error) { + return p.writeAndAppendEvent(ctx, store.WorkerEventUpdated, func(ctx context.Context, tx pgx.Tx) (*ateapi.Worker, error) { dbWorker, err := getWorkerRowForUpdate(ctx, tx, name) if err != nil { return nil, err @@ -156,8 +156,8 @@ func (p *Persistence) updateWorker(ctx context.Context, name string, preconditio }) } -func (p *Persistence) DeleteWorker(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapipb.Worker, error) { - return p.writeAndAppendEvent(ctx, store.WorkerEventDeleted, func(ctx context.Context, tx pgx.Tx) (*ateapipb.Worker, error) { +func (p *Persistence) DeleteWorker(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.Worker, error) { + return p.writeAndAppendEvent(ctx, store.WorkerEventDeleted, func(ctx context.Context, tx pgx.Tx) (*ateapi.Worker, error) { // Locked rather than plainly read so the incarnation precondition was evaluated // against is the one the DELETE removes. deleted, err := getWorkerRowForUpdate(ctx, tx, name) @@ -178,15 +178,15 @@ func (p *Persistence) DeleteWorker(ctx context.Context, name string, preconditio }) } -func (p *Persistence) ListWorkers(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapipb.Worker], error) { +func (p *Persistence) ListWorkers(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapi.Worker], error) { opts, err := store.NormalizeListOptions(opts) if err != nil { - return store.ListResponse[*ateapipb.Worker]{}, err + return store.ListResponse[*ateapi.Worker]{}, err } pageSize, pageTokenStr := opts.PageSize, opts.PageToken token, err := decodePageToken(pageTokenStr, kindWorker, "", 1) if err != nil { - return store.ListResponse[*ateapipb.Worker]{}, err + return store.ListResponse[*ateapi.Worker]{}, err } var last *string if len(token.Last) > 0 { @@ -199,27 +199,27 @@ func (p *Persistence) ListWorkers(ctx context.Context, opts store.ListOptions) ( ORDER BY name LIMIT $2`, last, int64(pageSize)+1) if err != nil { - return store.ListResponse[*ateapipb.Worker]{}, fmt.Errorf("listing workers: %w", err) + return store.ListResponse[*ateapi.Worker]{}, fmt.Errorf("listing workers: %w", err) } defer rows.Close() var names []string - var result []*ateapipb.Worker + var result []*ateapi.Worker for rows.Next() { var name string var protoBytes []byte if err := rows.Scan(&name, &protoBytes); err != nil { - return store.ListResponse[*ateapipb.Worker]{}, fmt.Errorf("scanning worker row: %w", err) + return store.ListResponse[*ateapi.Worker]{}, fmt.Errorf("scanning worker row: %w", err) } - w := &ateapipb.Worker{} + w := &ateapi.Worker{} if err := unmarshalRow(protoBytes, w, "worker", name); err != nil { - return store.ListResponse[*ateapipb.Worker]{}, err + return store.ListResponse[*ateapi.Worker]{}, err } result = append(result, w) names = append(names, name) } if err := rows.Err(); err != nil { - return store.ListResponse[*ateapipb.Worker]{}, fmt.Errorf("listing workers: %w", err) + return store.ListResponse[*ateapi.Worker]{}, fmt.Errorf("listing workers: %w", err) } var nextToken string @@ -227,5 +227,5 @@ func (p *Persistence) ListWorkers(ctx context.Context, opts store.ListOptions) ( result = result[:pageSize] nextToken = encodePageToken(kindWorker, "", []string{names[pageSize-1]}) } - return store.ListResponse[*ateapipb.Worker]{Items: result, NextPageToken: nextToken}, nil + return store.ListResponse[*ateapi.Worker]{Items: result, NextPageToken: nextToken}, nil } diff --git a/cmd/ateapi/internal/store/atepg/worker_assignment.go b/cmd/ateapi/internal/store/atepg/worker_assignment.go index 2ddebcddf8..1a6cbcf4c5 100644 --- a/cmd/ateapi/internal/store/atepg/worker_assignment.go +++ b/cmd/ateapi/internal/store/atepg/worker_assignment.go @@ -20,16 +20,16 @@ import ( "fmt" "github.com/jackc/pgx/v5" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" ) // getWorkerForUpdate reads a Worker and holds its row until the caller's // transaction commits, which is what serializes updates to its allocation. The // caller supplies the transaction; this only takes the lock. -func getWorkerForUpdate(ctx context.Context, tx pgx.Tx, name string) (*ateapipb.Worker, error) { +func getWorkerForUpdate(ctx context.Context, tx pgx.Tx, name string) (*ateapi.Worker, error) { var protoBytes []byte err := tx.QueryRow(ctx, `SELECT proto FROM workers WHERE name = $1 FOR UPDATE`, name).Scan(&protoBytes) if err != nil { @@ -38,7 +38,7 @@ func getWorkerForUpdate(ctx context.Context, tx pgx.Tx, name string) (*ateapipb. } return nil, fmt.Errorf("locking worker %s: %w", name, err) } - worker := &ateapipb.Worker{} + worker := &ateapi.Worker{} if err := proto.Unmarshal(protoBytes, worker); err != nil { return nil, fmt.Errorf("unmarshaling worker: %w", err) } @@ -47,7 +47,7 @@ func getWorkerForUpdate(ctx context.Context, tx pgx.Tx, name string) (*ateapipb. // saveWorker writes back a Worker whose allocation just moved, at the next // version. This assumes the caller holds the row lock getWorkerForUpdate took. -func saveWorker(ctx context.Context, tx pgx.Tx, worker *ateapipb.Worker) error { +func saveWorker(ctx context.Context, tx pgx.Tx, worker *ateapi.Worker) error { read := proto.CloneOf(worker.GetMetadata()) setUpdateMetadata(worker.GetMetadata(), worker.GetMetadata()) protoBytes, err := proto.Marshal(worker) @@ -69,7 +69,7 @@ func saveWorker(ctx context.Context, tx pgx.Tx, worker *ateapipb.Worker) error { return nil } -func (p *Persistence) BindActorToWorker(ctx context.Context, workerName string, assignment *ateapipb.ActorAssignment, admit func(*ateapipb.Worker) error) error { +func (p *Persistence) BindActorToWorker(ctx context.Context, workerName string, assignment *ateapi.ActorAssignment, admit func(*ateapi.Worker) error) error { actorUID := assignment.GetActorUid() if actorUID == "" { return fmt.Errorf("binding an assignment with no actor_uid to worker %s", workerName) @@ -77,16 +77,16 @@ func (p *Persistence) BindActorToWorker(ctx context.Context, workerName string, // The store assigns identity. atespace is empty because Workers are // global-scoped; the name is the Actor's UID, which is also the row key. // This is the identity a first bind gets; a rebind keeps the recorded one. - assignment.Metadata = &ateapipb.ResourceMetadata{Name: actorUID} + assignment.Metadata = &ateapi.ResourceMetadata{Name: actorUID} setCreateMetadata(assignment.Metadata) - _, err := p.writeAndAppendEvent(ctx, store.WorkerEventUpdated, func(ctx context.Context, tx pgx.Tx) (*ateapipb.Worker, error) { + _, err := p.writeAndAppendEvent(ctx, store.WorkerEventUpdated, func(ctx context.Context, tx pgx.Tx) (*ateapi.Worker, error) { worker, err := getWorkerForUpdate(ctx, tx, workerName) if err != nil { return nil, err } if worker.Status == nil { - worker.Status = &ateapipb.WorkerStatus{} + worker.Status = &ateapi.WorkerStatus{} } assignmentBytes, err := proto.Marshal(assignment) @@ -172,9 +172,9 @@ func (p *Persistence) BindActorToWorker(ctx context.Context, workerName string, return err } -func (p *Persistence) ReleaseActorFromWorker(ctx context.Context, workerName string, actorUID string) (*ateapipb.Worker, error) { - var released *ateapipb.Worker - _, err := p.writeAndAppendEvent(ctx, store.WorkerEventUpdated, func(ctx context.Context, tx pgx.Tx) (*ateapipb.Worker, error) { +func (p *Persistence) ReleaseActorFromWorker(ctx context.Context, workerName string, actorUID string) (*ateapi.Worker, error) { + var released *ateapi.Worker + _, err := p.writeAndAppendEvent(ctx, store.WorkerEventUpdated, func(ctx context.Context, tx pgx.Tx) (*ateapi.Worker, error) { released = nil worker, err := getWorkerForUpdate(ctx, tx, workerName) if err != nil { @@ -192,13 +192,13 @@ func (p *Persistence) ReleaseActorFromWorker(ctx context.Context, workerName str if err != nil { return nil, fmt.Errorf("releasing actor %s from worker %s: %w", actorUID, workerName, err) } - assignment := &ateapipb.ActorAssignment{} + assignment := &ateapi.ActorAssignment{} if err := proto.Unmarshal(protoBytes, assignment); err != nil { return nil, fmt.Errorf("unmarshaling released assignment: %w", err) } if worker.Status == nil { - worker.Status = &ateapipb.WorkerStatus{} + worker.Status = &ateapi.WorkerStatus{} } worker.Status.Allocated = resources.AddToAllocated(worker.Status.Allocated, assignment, -1) if err := saveWorker(ctx, tx, worker); err != nil { @@ -215,7 +215,7 @@ func (p *Persistence) ReleaseActorFromWorker(ctx context.Context, workerName str // getAssignmentRow reads the assignment for actorUID and names the worker // holding it. -func getAssignmentRow(ctx context.Context, q querier, actorUID string) (*ateapipb.ActorAssignment, string, error) { +func getAssignmentRow(ctx context.Context, q querier, actorUID string) (*ateapi.ActorAssignment, string, error) { var ( protoBytes []byte workerName string @@ -228,14 +228,14 @@ func getAssignmentRow(ctx context.Context, q querier, actorUID string) (*ateapip } return nil, "", fmt.Errorf("getting assignment for actor %s: %w", actorUID, err) } - assignment := &ateapipb.ActorAssignment{} + assignment := &ateapi.ActorAssignment{} if err := proto.Unmarshal(protoBytes, assignment); err != nil { return nil, "", fmt.Errorf("unmarshaling assignment: %w", err) } return assignment, workerName, nil } -func (p *Persistence) GetWorkerAssignment(ctx context.Context, workerName, actorUID string) (*ateapipb.ActorAssignment, error) { +func (p *Persistence) GetWorkerAssignment(ctx context.Context, workerName, actorUID string) (*ateapi.ActorAssignment, error) { assignment, holder, err := getAssignmentRow(ctx, p.pool, actorUID) if err != nil { return nil, err @@ -246,17 +246,17 @@ func (p *Persistence) GetWorkerAssignment(ctx context.Context, workerName, actor return assignment, nil } -func (p *Persistence) ListWorkerAssignments(ctx context.Context, workerName string, opts store.ListOptions) (store.ListResponse[*ateapipb.ActorAssignment], error) { +func (p *Persistence) ListWorkerAssignments(ctx context.Context, workerName string, opts store.ListOptions) (store.ListResponse[*ateapi.ActorAssignment], error) { opts, err := store.NormalizeListOptions(opts) if err != nil { - return store.ListResponse[*ateapipb.ActorAssignment]{}, err + return store.ListResponse[*ateapi.ActorAssignment]{}, err } pageSize := opts.PageSize // The token is scoped to the Worker, so one cannot be replayed against // another Worker's assignments. token, err := decodePageToken(opts.PageToken, kindWorkerAssign, workerName, 1) if err != nil { - return store.ListResponse[*ateapipb.ActorAssignment]{}, err + return store.ListResponse[*ateapi.ActorAssignment]{}, err } var last *string if len(token.Last) > 0 { @@ -269,27 +269,27 @@ func (p *Persistence) ListWorkerAssignments(ctx context.Context, workerName stri ORDER BY actor_uid LIMIT $3`, workerName, last, int64(pageSize)+1) if err != nil { - return store.ListResponse[*ateapipb.ActorAssignment]{}, fmt.Errorf("listing assignments of worker %s: %w", workerName, err) + return store.ListResponse[*ateapi.ActorAssignment]{}, fmt.Errorf("listing assignments of worker %s: %w", workerName, err) } defer rows.Close() var uids []string - var result []*ateapipb.ActorAssignment + var result []*ateapi.ActorAssignment for rows.Next() { var actorUID string var protoBytes []byte if err := rows.Scan(&actorUID, &protoBytes); err != nil { - return store.ListResponse[*ateapipb.ActorAssignment]{}, fmt.Errorf("scanning assignment of worker %s: %w", workerName, err) + return store.ListResponse[*ateapi.ActorAssignment]{}, fmt.Errorf("scanning assignment of worker %s: %w", workerName, err) } - assignment := &ateapipb.ActorAssignment{} + assignment := &ateapi.ActorAssignment{} if err := proto.Unmarshal(protoBytes, assignment); err != nil { - return store.ListResponse[*ateapipb.ActorAssignment]{}, fmt.Errorf("unmarshaling assignment of actor %s: %w", actorUID, err) + return store.ListResponse[*ateapi.ActorAssignment]{}, fmt.Errorf("unmarshaling assignment of actor %s: %w", actorUID, err) } result = append(result, assignment) uids = append(uids, actorUID) } if err := rows.Err(); err != nil { - return store.ListResponse[*ateapipb.ActorAssignment]{}, fmt.Errorf("listing assignments of worker %s: %w", workerName, err) + return store.ListResponse[*ateapi.ActorAssignment]{}, fmt.Errorf("listing assignments of worker %s: %w", workerName, err) } var nextToken string @@ -297,7 +297,7 @@ func (p *Persistence) ListWorkerAssignments(ctx context.Context, workerName stri result = result[:pageSize] nextToken = encodePageToken(kindWorkerAssign, workerName, []string{uids[pageSize-1]}) } - return store.ListResponse[*ateapipb.ActorAssignment]{Items: result, NextPageToken: nextToken}, nil + return store.ListResponse[*ateapi.ActorAssignment]{Items: result, NextPageToken: nextToken}, nil } func (p *Persistence) FindWorkerHostingActor(ctx context.Context, actorUID string) (string, error) { diff --git a/cmd/ateapi/internal/store/atepg/worker_assignment_test.go b/cmd/ateapi/internal/store/atepg/worker_assignment_test.go index 90739baf1a..77184320fe 100644 --- a/cmd/ateapi/internal/store/atepg/worker_assignment_test.go +++ b/cmd/ateapi/internal/store/atepg/worker_assignment_test.go @@ -19,8 +19,8 @@ import ( "errors" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // TestSaveWorker_RejectsAStaleWrite proves the precondition saveWorker states @@ -38,8 +38,8 @@ func TestSaveWorker_RejectsAStaleWrite(t *testing.T) { defer p.Close() clearAll(t, p) - created, err := p.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "stale-write-worker"}, + created, err := p.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "stale-write-worker"}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "pod", @@ -49,7 +49,7 @@ func TestSaveWorker_RejectsAStaleWrite(t *testing.T) { } // Move the stored Worker on, so the copy above is a version behind. - if _, err := p.UpdateWorker(ctx, created.GetMetadata().GetName(), store.PreconditionFrom(created), func(toUpdate *ateapipb.Worker) error { + if _, err := p.UpdateWorker(ctx, created.GetMetadata().GetName(), store.PreconditionFrom(created), func(toUpdate *ateapi.Worker) error { toUpdate.Labels = map[string]string{"tier": "batch"} return nil }); err != nil { @@ -80,8 +80,8 @@ func TestSaveWorker_RejectsAVanishedWorker(t *testing.T) { defer p.Close() clearAll(t, p) - created, err := p.CreateWorker(ctx, &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: "vanished-worker"}, + created, err := p.CreateWorker(ctx, &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: "vanished-worker"}, WorkerNamespace: "ns", WorkerPool: "pool", WorkerPod: "pod", diff --git a/cmd/ateapi/internal/store/store.go b/cmd/ateapi/internal/store/store.go index 318cc60107..50e336fefb 100644 --- a/cmd/ateapi/internal/store/store.go +++ b/cmd/ateapi/internal/store/store.go @@ -21,8 +21,8 @@ import ( "fmt" "sync" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) var ( @@ -70,14 +70,14 @@ type Interface interface { // server-assigned metadata (uid, version, timestamps). The input is not // mutated. Returns ErrAlreadyExists if key is taken, or // ErrFailedPrecondition if the actor's atespace does not exist. - CreateActor(ctx context.Context, actor *ateapipb.Actor) (*ateapipb.Actor, error) + CreateActor(ctx context.Context, actor *ateapi.Actor) (*ateapi.Actor, error) // Fetches an actor by reference. Returns ErrNotFound if missing. - GetActor(ctx context.Context, actorRef resources.ActorRef) (*ateapipb.Actor, error) + GetActor(ctx context.Context, actorRef resources.ActorRef) (*ateapi.Actor, error) // Lists actors in the given atespace (scoped scan), or across ALL atespaces if atespace is // empty. - ListActors(ctx context.Context, atespace string, opts ListOptions) (ListResponse[*ateapipb.Actor], error) + ListActors(ctx context.Context, atespace string, opts ListOptions) (ListResponse[*ateapi.Actor], error) // UpdateActor performs a transactional read-modify-write and returns the stored // actor with advanced metadata (version, update_time). @@ -98,45 +98,45 @@ type Interface interface { // exhausted, or the mutate's error verbatim otherwise. Immutable fields // are not checked here; the service layer enforces them via declarative // validation before the write. - UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition Precondition, mutate func(toUpdate *ateapipb.Actor) error) (*ateapipb.Actor, error) + UpdateActor(ctx context.Context, actorRef resources.ActorRef, precondition Precondition, mutate func(toUpdate *ateapi.Actor) error) (*ateapi.Actor, error) // MarkActorForDeletion initiates the deletion of an actor. It sets // metadata.delete_time if unset and applies mutate, if non-nil, so callers can // update the actor's status. Returns ErrNotFound if missing, // ErrUIDConflict/ErrVersionConflict if precondition fails or a concurrent // write wins, or mutate's error. - MarkActorForDeletion(ctx context.Context, actorRef resources.ActorRef, precondition DeletePreconditions, mutate func(toUpdate *ateapipb.Actor) error) (*ateapipb.Actor, error) + MarkActorForDeletion(ctx context.Context, actorRef resources.ActorRef, precondition DeletePreconditions, mutate func(toUpdate *ateapi.Actor) error) (*ateapi.Actor, error) // Removes an actor and returns the deleted resource. Returns ErrNotFound if // missing, or ErrUIDConflict/ErrVersionConflict if precondition does not // describe the actor the caller observed. - DeleteActor(ctx context.Context, actorRef resources.ActorRef, precondition DeletePreconditions) (*ateapipb.Actor, error) + DeleteActor(ctx context.Context, actorRef resources.ActorRef, precondition DeletePreconditions) (*ateapi.Actor, error) // Creates the 1:1 policy subresource for an existing Actor. - CreateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, policy *ateapipb.EgressPolicy) (*ateapipb.EgressPolicy, error) + CreateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, policy *ateapi.EgressPolicy) (*ateapi.EgressPolicy, error) // Fetches an Actor's policy subresource. - GetEgressPolicy(ctx context.Context, actorRef resources.ActorRef) (*ateapipb.EgressPolicy, error) + GetEgressPolicy(ctx context.Context, actorRef resources.ActorRef) (*ateapi.EgressPolicy, error) // Transactionally updates an Actor's policy when its current UID and version // match the precondition. - UpdateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition Precondition, mutate func(*ateapipb.EgressPolicy) error) (*ateapipb.EgressPolicy, error) + UpdateEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition Precondition, mutate func(*ateapi.EgressPolicy) error) (*ateapi.EgressPolicy, error) // Deletes and returns an Actor's policy subresource. Returns ErrNotFound if // missing, or ErrUIDConflict/ErrVersionConflict if precondition does not // describe the policy the caller observed. - DeleteEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition DeletePreconditions) (*ateapipb.EgressPolicy, error) + DeleteEgressPolicy(ctx context.Context, actorRef resources.ActorRef, precondition DeletePreconditions) (*ateapi.EgressPolicy, error) // CreateTag creates an immutable tag to an actor snapshot. // // Returns ErrAlreadyExists if the name is taken — including by the caller's // own unfinished attempt, which it can then read back and resume — or // ErrFailedPrecondition if the tag's atespace does not exist. - CreateTag(ctx context.Context, tag *ateapipb.Tag) (*ateapipb.Tag, error) + CreateTag(ctx context.Context, tag *ateapi.Tag) (*ateapi.Tag, error) // Fetches an Atespace-owned tag by reference. Returns ErrNotFound if // missing. - GetTag(ctx context.Context, tagRef resources.TagRef) (*ateapipb.Tag, error) + GetTag(ctx context.Context, tagRef resources.TagRef) (*ateapi.Tag, error) // Lists Tags in one atespace, or all atespaces when empty. - ListTags(ctx context.Context, atespace string, opts ListOptions) (ListResponse[*ateapipb.Tag], error) + ListTags(ctx context.Context, atespace string, opts ListOptions) (ListResponse[*ateapi.Tag], error) // UpdateTag performs a transactional read-modify-write on the tag // addressed by tagRef, and returns the stored Tag with @@ -159,69 +159,69 @@ type Interface interface { // immutable for its lifetime, or the mutate's error verbatim otherwise. // // status.snapshot is immutable once set - UpdateTag(ctx context.Context, tagRef resources.TagRef, precondition Precondition, mutate func(toUpdate *ateapipb.Tag) error) (*ateapipb.Tag, error) + UpdateTag(ctx context.Context, tagRef resources.TagRef, precondition Precondition, mutate func(toUpdate *ateapi.Tag) error) (*ateapi.Tag, error) // MarkTagForDeletion initiates the deletion of a tag. It sets // metadata.delete_time if unset and applies mutate, if non-nil, so callers can // update the tag's status. Returns ErrNotFound if missing, // ErrUIDConflict/ErrVersionConflict if precondition fails or a concurrent // write wins, or mutate's error. - MarkTagForDeletion(ctx context.Context, tagRef resources.TagRef, precondition DeletePreconditions, mutate func(toUpdate *ateapipb.Tag) error) (*ateapipb.Tag, error) + MarkTagForDeletion(ctx context.Context, tagRef resources.TagRef, precondition DeletePreconditions, mutate func(toUpdate *ateapi.Tag) error) (*ateapi.Tag, error) // Deletes and returns a tag. Returns ErrNotFound if missing, or // ErrUIDConflict/ErrVersionConflict if precondition does not describe the // tag the caller observed. - DeleteTag(ctx context.Context, tagRef resources.TagRef, precondition DeletePreconditions) (*ateapipb.Tag, error) + DeleteTag(ctx context.Context, tagRef resources.TagRef, precondition DeletePreconditions) (*ateapi.Tag, error) // Stores a new atespace and returns the stored resource with server-assigned // metadata (uid, version, timestamps). The input is not mutated. Returns // ErrAlreadyExists if the name is taken. - CreateAtespace(ctx context.Context, atespace *ateapipb.Atespace) (*ateapipb.Atespace, error) + CreateAtespace(ctx context.Context, atespace *ateapi.Atespace) (*ateapi.Atespace, error) // Fetches an atespace by name. Returns ErrNotFound if missing. - GetAtespace(ctx context.Context, name string) (*ateapipb.Atespace, error) + GetAtespace(ctx context.Context, name string) (*ateapi.Atespace, error) // Lists atespaces. - ListAtespaces(ctx context.Context, opts ListOptions) (ListResponse[*ateapipb.Atespace], error) + ListAtespaces(ctx context.Context, opts ListOptions) (ListResponse[*ateapi.Atespace], error) // Removes an empty atespace and returns the deleted resource. Returns // ErrNotFound if missing, ErrUIDConflict/ErrVersionConflict if precondition // does not describe the atespace the caller observed, or // ErrFailedPrecondition if the atespace is not empty (e.g. there are actors // in it). - DeleteAtespace(ctx context.Context, name string, precondition DeletePreconditions) (*ateapipb.Atespace, error) + DeleteAtespace(ctx context.Context, name string, precondition DeletePreconditions) (*ateapi.Atespace, error) // Creates the deployment-wide global access policy singleton. - CreateGlobalAccessPolicy(ctx context.Context, policy *ateapipb.AccessPolicy) (*ateapipb.AccessPolicy, error) + CreateGlobalAccessPolicy(ctx context.Context, policy *ateapi.AccessPolicy) (*ateapi.AccessPolicy, error) // Fetches the deployment-wide global access policy singleton. - GetGlobalAccessPolicy(ctx context.Context) (*ateapipb.AccessPolicy, error) + GetGlobalAccessPolicy(ctx context.Context) (*ateapi.AccessPolicy, error) // Transactionally updates the deployment-wide global access policy singleton // when its current UID and version match the precondition. - UpdateGlobalAccessPolicy(ctx context.Context, precondition Precondition, mutate func(*ateapipb.AccessPolicy) error) (*ateapipb.AccessPolicy, error) + UpdateGlobalAccessPolicy(ctx context.Context, precondition Precondition, mutate func(*ateapi.AccessPolicy) error) (*ateapi.AccessPolicy, error) // Creates the 1:1 access policy subresource for an existing Atespace. - CreateAtespaceAccessPolicy(ctx context.Context, name string, policy *ateapipb.AccessPolicy) (*ateapipb.AccessPolicy, error) + CreateAtespaceAccessPolicy(ctx context.Context, name string, policy *ateapi.AccessPolicy) (*ateapi.AccessPolicy, error) // Fetches an Atespace's access policy subresource. Returns ErrNotFound if missing. - GetAtespaceAccessPolicy(ctx context.Context, name string) (*ateapipb.AccessPolicy, error) + GetAtespaceAccessPolicy(ctx context.Context, name string) (*ateapi.AccessPolicy, error) // Transactionally updates an Atespace's access policy when its current UID // and version match the precondition. - UpdateAtespaceAccessPolicy(ctx context.Context, name string, precondition Precondition, mutate func(*ateapipb.AccessPolicy) error) (*ateapipb.AccessPolicy, error) + UpdateAtespaceAccessPolicy(ctx context.Context, name string, precondition Precondition, mutate func(*ateapi.AccessPolicy) error) (*ateapi.AccessPolicy, error) // Deletes and returns an Atespace's access policy subresource. Returns // ErrNotFound if missing, or ErrUIDConflict/ErrVersionConflict if // precondition does not describe the policy the caller observed. - DeleteAtespaceAccessPolicy(ctx context.Context, name string, precondition DeletePreconditions) (*ateapipb.AccessPolicy, error) + DeleteAtespaceAccessPolicy(ctx context.Context, name string, precondition DeletePreconditions) (*ateapi.AccessPolicy, error) // Stores a new ActorTemplate and returns the stored resource with // server-assigned metadata (uid, version, timestamps). The input is not // mutated. Returns ErrAlreadyExists if the (atespace, name) is taken. - CreateActorTemplate(ctx context.Context, template *ateapipb.ActorTemplate) (*ateapipb.ActorTemplate, error) + CreateActorTemplate(ctx context.Context, template *ateapi.ActorTemplate) (*ateapi.ActorTemplate, error) // Fetches an ActorTemplate by reference. Returns ErrNotFound if missing. - GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapipb.ActorTemplate, error) + GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapi.ActorTemplate, error) // Lists ActorTemplates in an atespace, or across all atespaces when // atespace is empty. - ListActorTemplates(ctx context.Context, atespace string, opts ListOptions) (ListResponse[*ateapipb.ActorTemplate], error) + ListActorTemplates(ctx context.Context, atespace string, opts ListOptions) (ListResponse[*ateapi.ActorTemplate], error) // UpdateActorTemplate performs a transactional read-modify-write and returns // the updated template with advanced metadata (version, update_time). @@ -229,30 +229,30 @@ type Interface interface { // precondition guards the write against landing on unexpected state: it is // checked against the stored template before mutate runs. Both the uid and // version guards are required. - UpdateActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition Precondition, mutate func(dbTemplate *ateapipb.ActorTemplate) error) (*ateapipb.ActorTemplate, error) + UpdateActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition Precondition, mutate func(dbTemplate *ateapi.ActorTemplate) error) (*ateapi.ActorTemplate, error) // MarkActorTemplateForDeletion initiates the deletion of an actor // template. It sets metadata.delete_time if unset and applies mutate, if // non-nil, so callers can update the template's status. Returns ErrNotFound // if missing, ErrUIDConflict/ErrVersionConflict if precondition fails or a // concurrent write wins, or mutate's error. - MarkActorTemplateForDeletion(ctx context.Context, templateRef resources.ActorTemplateRef, precondition DeletePreconditions, mutate func(toUpdate *ateapipb.ActorTemplate) error) (*ateapipb.ActorTemplate, error) + MarkActorTemplateForDeletion(ctx context.Context, templateRef resources.ActorTemplateRef, precondition DeletePreconditions, mutate func(toUpdate *ateapi.ActorTemplate) error) (*ateapi.ActorTemplate, error) // Removes an ActorTemplate and returns the deleted resource. Returns // ErrNotFound if missing, or ErrUIDConflict/ErrVersionConflict if // precondition does not describe the template the caller observed. - DeleteActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition DeletePreconditions) (*ateapipb.ActorTemplate, error) + DeleteActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition DeletePreconditions) (*ateapi.ActorTemplate, error) // Registers a new idle worker and returns the stored resource with // server-assigned metadata (uid, version, timestamps). The input is not // mutated. Returns ErrAlreadyExists if already registered. - CreateWorker(ctx context.Context, worker *ateapipb.Worker) (*ateapipb.Worker, error) + CreateWorker(ctx context.Context, worker *ateapi.Worker) (*ateapi.Worker, error) // Fetches worker state by name. Returns ErrNotFound if missing. - GetWorker(ctx context.Context, name string) (*ateapipb.Worker, error) + GetWorker(ctx context.Context, name string) (*ateapi.Worker, error) // Lists workers. - ListWorkers(ctx context.Context, opts ListOptions) (ListResponse[*ateapipb.Worker], error) + ListWorkers(ctx context.Context, opts ListOptions) (ListResponse[*ateapi.Worker], error) // UpdateWorker performs a transactional read-modify-write and returns the // stored worker with advanced metadata (version, update_time). @@ -265,20 +265,20 @@ type Interface interface { // ErrNotFound if missing, ErrUIDConflict or ErrVersionConflict if the // precondition no longer holds, ErrVersionConflict if the retry budget is // exhausted, or the mutate's error verbatim otherwise. - UpdateWorker(ctx context.Context, name string, precondition Precondition, mutate func(toUpdate *ateapipb.Worker) error) (*ateapipb.Worker, error) + UpdateWorker(ctx context.Context, name string, precondition Precondition, mutate func(toUpdate *ateapi.Worker) error) (*ateapi.Worker, error) // MarkWorkerForDeletion initiates the deletion of a worker. It sets // metadata.delete_time if unset and applies mutate, if non-nil, so callers can // update the worker's status. Returns ErrNotFound if missing, // ErrUIDConflict/ErrVersionConflict if precondition fails or a concurrent // write wins, or mutate's error. - MarkWorkerForDeletion(ctx context.Context, name string, precondition DeletePreconditions, mutate func(toUpdate *ateapipb.Worker) error) (*ateapipb.Worker, error) + MarkWorkerForDeletion(ctx context.Context, name string, precondition DeletePreconditions, mutate func(toUpdate *ateapi.Worker) error) (*ateapi.Worker, error) // Removes a worker by name, along with every assignment it holds, and // returns the deleted resource. Returns ErrNotFound if missing, or // ErrUIDConflict/ErrVersionConflict if precondition does not describe the // worker the caller observed. - DeleteWorker(ctx context.Context, name string, precondition DeletePreconditions) (*ateapipb.Worker, error) + DeleteWorker(ctx context.Context, name string, precondition DeletePreconditions) (*ateapi.Worker, error) // Assignments and Worker allocation are updated atomically. @@ -292,20 +292,20 @@ type Interface interface { // Actor already on this Worker is already counted against it. // // ErrNotFound if the Worker is gone. - BindActorToWorker(ctx context.Context, workerName string, assignment *ateapipb.ActorAssignment, admit func(*ateapipb.Worker) error) error + BindActorToWorker(ctx context.Context, workerName string, assignment *ateapi.ActorAssignment, admit func(*ateapi.Worker) error) error // ReleaseActorFromWorker removes an assignment and updates allocation, // returning the Worker as it now stands so the caller can feed the // watch-fed cache, which until then reports it full. It returns nil if the // assignment was already absent. - ReleaseActorFromWorker(ctx context.Context, workerName string, actorUID string) (*ateapipb.Worker, error) + ReleaseActorFromWorker(ctx context.Context, workerName string, actorUID string) (*ateapi.Worker, error) // GetWorkerAssignment returns a Worker's assignment for actorUID, or // ErrNotFound when the Worker is not hosting that Actor. - GetWorkerAssignment(ctx context.Context, workerName, actorUID string) (*ateapipb.ActorAssignment, error) + GetWorkerAssignment(ctx context.Context, workerName, actorUID string) (*ateapi.ActorAssignment, error) // ListWorkerAssignments returns a page of the Actors a Worker hosts. - ListWorkerAssignments(ctx context.Context, workerName string, opts ListOptions) (ListResponse[*ateapipb.ActorAssignment], error) + ListWorkerAssignments(ctx context.Context, workerName string, opts ListOptions) (ListResponse[*ateapi.ActorAssignment], error) // FindWorkerHostingActor names the Worker holding an assignment for // actorUID, or ErrNotFound if none does. @@ -353,7 +353,7 @@ type DeletePreconditions struct { // // Returns ErrUIDConflict or ErrVersionConflict, which the delete surfaces // verbatim. -func (p DeletePreconditions) Check(md *ateapipb.ResourceMetadata) error { +func (p DeletePreconditions) Check(md *ateapi.ResourceMetadata) error { if p.UID != "" && p.UID != md.GetUid() { return ErrUIDConflict } @@ -366,7 +366,7 @@ func (p DeletePreconditions) Check(md *ateapipb.ResourceMetadata) error { // hasResourceMetadata is an object the store addresses by atespace and name, // and whose identity a caller can guard with a Precondition. type hasResourceMetadata interface { - GetMetadata() *ateapipb.ResourceMetadata + GetMetadata() *ateapi.ResourceMetadata } // PreconditionFrom builds the guards from the object the caller observed: its @@ -391,7 +391,7 @@ func (p Precondition) Validate() error { // Check reports whether md still matches the guards p carries. The uid is reported // first: a new incarnation makes the version meaningless. -func (p Precondition) Check(md *ateapipb.ResourceMetadata) error { +func (p Precondition) Check(md *ateapi.ResourceMetadata) error { if p.UID != md.GetUid() { return ErrUIDConflict } @@ -413,7 +413,7 @@ const ( // WorkerEvent carries a single worker state change notification. type WorkerEvent struct { Type WorkerEventType - Worker *ateapipb.Worker + Worker *ateapi.Worker } // WorkerWatch is an active subscription to worker state changes. The caller diff --git a/cmd/ateapi/internal/store/store_test.go b/cmd/ateapi/internal/store/store_test.go index b5646d4dfc..a43e29af3a 100644 --- a/cmd/ateapi/internal/store/store_test.go +++ b/cmd/ateapi/internal/store/store_test.go @@ -18,7 +18,7 @@ import ( "errors" "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) const ( @@ -30,7 +30,7 @@ const ( // storedMetadata is the metadata of the object the transaction reads, which a // precondition is checked against. -var storedMetadata = &ateapipb.ResourceMetadata{ +var storedMetadata = &ateapi.ResourceMetadata{ Atespace: "test-atespace", Name: "actor-1", Uid: storedUID, @@ -116,31 +116,31 @@ func TestPreconditionValidate(t *testing.T) { func TestPreconditionFrom(t *testing.T) { tests := []struct { name string - observed *ateapipb.Actor + observed *ateapi.Actor want Precondition wantValidateErr error }{ { name: "the observed object supplies its uid and version as guards", - observed: &ateapipb.Actor{Metadata: storedMetadata}, + observed: &ateapi.Actor{Metadata: storedMetadata}, want: Precondition{UID: storedUID, Version: storedVer}, wantValidateErr: nil, }, { name: "an unguarded object with no uid or version is rejected", - observed: &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Atespace: "test-atespace", Name: "actor-1"}}, + observed: &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Atespace: "test-atespace", Name: "actor-1"}}, want: Precondition{}, wantValidateErr: ErrPreconditionRequired, }, { name: "an object carrying only a uid is rejected", - observed: &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Uid: storedUID}}, + observed: &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Uid: storedUID}}, want: Precondition{UID: storedUID}, wantValidateErr: ErrPreconditionRequired, }, { name: "an object carrying only a version is rejected", - observed: &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Version: storedVer}}, + observed: &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Version: storedVer}}, want: Precondition{Version: storedVer}, wantValidateErr: ErrPreconditionRequired, }, diff --git a/cmd/ateapi/internal/store/storecontract/contract.go b/cmd/ateapi/internal/store/storecontract/contract.go index 77cf92e241..7ff8970cf5 100644 --- a/cmd/ateapi/internal/store/storecontract/contract.go +++ b/cmd/ateapi/internal/store/storecontract/contract.go @@ -35,9 +35,9 @@ import ( "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/timestamppb" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // testAtespace is the atespace used by tests that create a single actor. @@ -75,41 +75,41 @@ const ( // Atomic cmp options to skip individual server-owned ResourceMetadata fields // in proto diffs. var ( - ignoreUID = protocmp.IgnoreFields(&ateapipb.ResourceMetadata{}, "uid") - ignoreVersion = protocmp.IgnoreFields(&ateapipb.ResourceMetadata{}, "version") - ignoreTimestamps = protocmp.IgnoreFields(&ateapipb.ResourceMetadata{}, "create_time", "update_time", "delete_time") + ignoreUID = protocmp.IgnoreFields(&ateapi.ResourceMetadata{}, "uid") + ignoreVersion = protocmp.IgnoreFields(&ateapi.ResourceMetadata{}, "version") + ignoreTimestamps = protocmp.IgnoreFields(&ateapi.ResourceMetadata{}, "create_time", "update_time", "delete_time") ) -func newTestAtespace(name string) *ateapipb.Atespace { - return &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: name}} +func newTestAtespace(name string) *ateapi.Atespace { + return &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: name}} } // The fixture populates the volume/env union fields so the round-trip covers // the plain-field union shape (issue #962), including presence of the // optional value and type fields (empty string != unset). -func newTestActorTemplate(atespace, name string) *ateapipb.ActorTemplate { - return &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: name}, - Containers: []*ateapipb.Container{{ +func newTestActorTemplate(atespace, name string) *ateapi.ActorTemplate { + return &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: name}, + Containers: []*ateapi.Container{{ Name: "main", Image: "example.com/app@sha256:0000000000000000000000000000000000000000000000000000000000000000", - Env: []*ateapipb.EnvVar{{Name: "MODE", Value: "VAL"}}, - VolumeMounts: []*ateapipb.VolumeMount{{Name: "data", MountPath: "/data"}}, + Env: []*ateapi.EnvVar{{Name: "MODE", Value: "VAL"}}, + VolumeMounts: []*ateapi.VolumeMount{{Name: "data", MountPath: "/data"}}, }}, - Volumes: []*ateapipb.Volume{{ + Volumes: []*ateapi.Volume{{ Name: "data", - DurableDir: &ateapipb.DurableDirVolumeSource{}, + DurableDir: &ateapi.DurableDirVolumeSource{}, }, { Name: "system-info", - SystemInfo: &ateapipb.SystemInfoVolumeSource{ - DataSources: []*ateapipb.SystemInfoDataSource{ - {ActorMetadata: &ateapipb.ActorMetadataDataSource{ - Items: []*ateapipb.ActorMetadataItem{{ - Field: ateapipb.ActorMetadataField_ACTOR_METADATA_FIELD_NAME, + SystemInfo: &ateapi.SystemInfoVolumeSource{ + DataSources: []*ateapi.SystemInfoDataSource{ + {ActorMetadata: &ateapi.ActorMetadataDataSource{ + Items: []*ateapi.ActorMetadataItem{{ + Field: ateapi.ActorMetadataField_ACTOR_METADATA_FIELD_NAME, Path: "actor-id", }}, }}, - {TrustBundle: &ateapipb.TrustBundleDataSource{ + {TrustBundle: &ateapi.TrustBundleDataSource{ Names: []string{"egress-mitm.ate.dev"}, Path: "trust-bundle.pem", }}, @@ -118,24 +118,24 @@ func newTestActorTemplate(atespace, name string) *ateapipb.ActorTemplate { }}, // Fully defaulted, as the RPC layer stores it, so a read that // backfills defaults returns what was created. - SnapshotConfig: &ateapipb.SnapshotConfig{ - PreferredFidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - GoldenSnapshotConfig: &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, + SnapshotConfig: &ateapi.SnapshotConfig{ + PreferredFidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + GoldenSnapshotConfig: &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_ENABLED}, }, } } // newTestWorker builds a global-scoped Worker. name is the resource name the // store keys the row by; it is unrelated to worker_pod_uid. -func newTestWorker(name, pod string) *ateapipb.Worker { - return &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: name}, +func newTestWorker(name, pod string) *ateapi.Worker { + return &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: name}, WorkerNamespace: "default", WorkerPool: "pool-1", WorkerPod: pod, WorkerPodUid: testWorkerPodUID, - Status: &ateapipb.WorkerStatus{ - Capacity: &ateapipb.WorkerResources{CpuMillicores: 2000, MemoryBytes: 4 << 30}, + Status: &ateapi.WorkerStatus{ + Capacity: &ateapi.WorkerResources{CpuMillicores: 2000, MemoryBytes: 4 << 30}, }, } } @@ -149,7 +149,7 @@ func mustCreateAtespace(t *testing.T, s store.Interface, name string) { } } -func actorNameSet(actors []*ateapipb.Actor) map[string]bool { +func actorNameSet(actors []*ateapi.Actor) map[string]bool { set := make(map[string]bool, len(actors)) for _, a := range actors { set[a.GetMetadata().GetName()] = true @@ -204,7 +204,7 @@ func assertPruned(t *testing.T, op string, want, got proto.Message) { // resourceMessage is a stored resource, which carries ResourceMetadata. type resourceMessage interface { proto.Message - GetMetadata() *ateapipb.ResourceMetadata + GetMetadata() *ateapi.ResourceMetadata } // markForDeletionCase binds one resource's store methods for @@ -350,18 +350,18 @@ func runEgressPolicyContractTests(t *testing.T, setup func(t *testing.T) store.I s := setup(t) ctx := context.Background() mustCreateAtespace(t, s, testAtespace) - actor, err := s.CreateActor(ctx, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "session-1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + actor, err := s.CreateActor(ctx, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "session-1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, }) if err != nil { t.Fatal(err) } actorRef := resources.ActorRefFromActor(actor) - policy := &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "default"}, - Rules: []*ateapipb.EgressRule{{ - Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{80}}}, + policy := &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "default"}, + Rules: []*ateapi.EgressRule{{ + Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{80}}}, }}, } @@ -379,19 +379,19 @@ func runEgressPolicyContractTests(t *testing.T, setup func(t *testing.T) store.I if err != nil || !proto.Equal(got, created) { t.Fatalf("GetEgressPolicy = %v, %v; want %v", got, err, created) } - if _, err := s.UpdateEgressPolicy(ctx, actorRef, store.Precondition{}, func(*ateapipb.EgressPolicy) error { return nil }); !errors.Is(err, store.ErrPreconditionRequired) { + if _, err := s.UpdateEgressPolicy(ctx, actorRef, store.Precondition{}, func(*ateapi.EgressPolicy) error { return nil }); !errors.Is(err, store.ErrPreconditionRequired) { t.Fatalf("unguarded update error = %v, want ErrPreconditionRequired", err) } - if _, err := s.UpdateEgressPolicy(ctx, actorRef, store.Precondition{UID: created.GetMetadata().GetUid(), Version: 99}, func(*ateapipb.EgressPolicy) error { return nil }); !errors.Is(err, store.ErrVersionConflict) { + if _, err := s.UpdateEgressPolicy(ctx, actorRef, store.Precondition{UID: created.GetMetadata().GetUid(), Version: 99}, func(*ateapi.EgressPolicy) error { return nil }); !errors.Is(err, store.ErrVersionConflict) { t.Fatalf("stale update error = %v, want ErrVersionConflict", err) } - if _, err := s.UpdateEgressPolicy(ctx, actorRef, store.Precondition{UID: "replacement-uid", Version: 1}, func(*ateapipb.EgressPolicy) error { return nil }); !errors.Is(err, store.ErrUIDConflict) { + if _, err := s.UpdateEgressPolicy(ctx, actorRef, store.Precondition{UID: "replacement-uid", Version: 1}, func(*ateapi.EgressPolicy) error { return nil }); !errors.Is(err, store.ErrUIDConflict) { t.Fatalf("wrong UID update error = %v, want ErrUIDConflict", err) } - updated, err := s.UpdateEgressPolicy(ctx, actorRef, store.PreconditionFrom(created), func(policy *ateapipb.EgressPolicy) error { + updated, err := s.UpdateEgressPolicy(ctx, actorRef, store.PreconditionFrom(created), func(policy *ateapi.EgressPolicy) error { policy.Metadata.Atespace = "other" policy.Metadata.Name = "other" - policy.Rules = []*ateapipb.EgressRule{{TlsPassthrough: &ateapipb.TlsPassthroughRule{Hostnames: []string{"*"}, Ports: &ateapipb.Ports{Numbers: []int32{443}}}}} + policy.Rules = []*ateapi.EgressRule{{TlsPassthrough: &ateapi.TlsPassthroughRule{Hostnames: []string{"*"}, Ports: &ateapi.Ports{Numbers: []int32{443}}}}} return nil }) if err != nil || updated.GetMetadata().GetAtespace() != testAtespace || updated.GetMetadata().GetName() != "default" || updated.GetMetadata().GetVersion() != 2 || updated.GetMetadata().GetUid() != created.GetMetadata().GetUid() { @@ -401,7 +401,7 @@ func runEgressPolicyContractTests(t *testing.T, setup func(t *testing.T) store.I if err != nil { t.Fatalf("DeleteEgressPolicy failed: %v", err) } - if diff := cmp.Diff(updated, deleted, protocmp.Transform(), protocmp.IgnoreFields(&ateapipb.ResourceMetadata{}, "delete_time")); diff != "" { + if diff := cmp.Diff(updated, deleted, protocmp.Transform(), protocmp.IgnoreFields(&ateapi.ResourceMetadata{}, "delete_time")); diff != "" { t.Fatalf("deleted policy mismatch (-updated +deleted):\n%s", diff) } if deleted.GetMetadata().GetDeleteTime() == nil { @@ -420,9 +420,9 @@ func runEgressPolicyContractTests(t *testing.T, setup func(t *testing.T) store.I if _, err := s.CreateActor(ctx, newTestSuspendedActor(testAtespace, actorRef.Name)); err != nil { t.Fatalf("CreateActor failed: %v", err) } - create := func() *ateapipb.EgressPolicy { - created, err := s.CreateEgressPolicy(ctx, actorRef, &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "default"}, + create := func() *ateapi.EgressPolicy { + created, err := s.CreateEgressPolicy(ctx, actorRef, &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "default"}, }) if err != nil { t.Fatalf("CreateEgressPolicy failed: %v", err) @@ -477,15 +477,15 @@ func runEgressPolicyContractTests(t *testing.T, setup func(t *testing.T) store.I ctx := context.Background() mustCreateAtespace(t, s, testAtespace) actorRef := resources.ActorRef{Atespace: testAtespace, Name: "session-1"} - policy := &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "default"}, + policy := &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "default"}, } if _, err := s.CreateEgressPolicy(ctx, actorRef, policy); !errors.Is(err, store.ErrFailedPrecondition) { t.Fatalf("policy without Actor error = %v, want ErrFailedPrecondition", err) } - actor, err := s.CreateActor(ctx, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: actorRef.Name}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_DELETING}, + actor, err := s.CreateActor(ctx, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: actorRef.Name}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_DELETING}, }) if err != nil { t.Fatal(err) @@ -499,9 +499,9 @@ func runEgressPolicyContractTests(t *testing.T, setup func(t *testing.T) store.I if _, err := s.GetEgressPolicy(ctx, actorRef); !errors.Is(err, store.ErrNotFound) { t.Fatalf("policy after Actor deletion error = %v, want ErrNotFound", err) } - replacement, err := s.CreateActor(ctx, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: actorRef.Name}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + replacement, err := s.CreateActor(ctx, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: actorRef.Name}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, }) if err != nil { t.Fatal(err) @@ -584,10 +584,10 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac ctx := context.Background() mustCreateAtespace(t, s, testAtespace) - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "session-1", Atespace: testAtespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "default", Name: "test-template"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "session-1", Atespace: testAtespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "default", Name: "test-template"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, } created, err := s.CreateActor(ctx, actor) @@ -617,7 +617,7 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac t.Errorf("CreateActor return does not match stored state (-created +got):\n%s", diff) } - expected := proto.Clone(actor).(*ateapipb.Actor) + expected := proto.Clone(actor).(*ateapi.Actor) expected.Metadata.Version = 1 if diff := cmp.Diff(expected, created, protocmp.Transform(), ignoreUID, ignoreTimestamps); diff != "" { t.Errorf("CreateActor returned unexpected actor (-want +got):\n%s", diff) @@ -629,10 +629,10 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac ctx := context.Background() mustCreateAtespace(t, s, testAtespace) - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "session-1", Atespace: testAtespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "default", Name: "test-template"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "session-1", Atespace: testAtespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "default", Name: "test-template"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, } if _, err := s.CreateActor(ctx, actor); err != nil { @@ -643,15 +643,39 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac } }) + t.Run("Actor_MalformedSnapshotURI", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + mustCreateAtespace(t, s, testAtespace) + const malformedURI = "gs://private/not-a-snapshot" + + actor := newTestSuspendedActor(testAtespace, "session-1") + actor.Status.Snapshots[0].DurableSnapshot.Object.SnapshotUri = malformedURI + if _, err := s.CreateActor(ctx, actor); err == nil { + t.Errorf("CreateActor with a malformed snapshot URI succeeded, want an error") + } + + created, err := s.CreateActor(ctx, newTestSuspendedActor(testAtespace, "session-2")) + if err != nil { + t.Fatalf("CreateActor failed: %v", err) + } + if _, err := s.UpdateActor(ctx, resources.ActorRefFromActor(created), store.PreconditionFrom(created), func(toUpdate *ateapi.Actor) error { + toUpdate.Status.Snapshots[0].DurableSnapshot.Object.SnapshotUri = malformedURI + return nil + }); err == nil { + t.Errorf("UpdateActor to a malformed snapshot URI succeeded, want an error") + } + }) + t.Run("UpdateActor_Success", func(t *testing.T) { s := setup(t) ctx := context.Background() mustCreateAtespace(t, s, testAtespace) - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "session-1", Atespace: testAtespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "default", Name: "test-template"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "session-1", Atespace: testAtespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "default", Name: "test-template"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, } created, err := s.CreateActor(ctx, actor) @@ -660,8 +684,8 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac } actorRef := resources.ActorRefFromActor(created) - updated, err := s.UpdateActor(ctx, actorRef, store.PreconditionFrom(created), func(dbActor *ateapipb.Actor) error { - dbActor.Status.State = ateapipb.ActorState_ACTOR_STATE_RUNNING + updated, err := s.UpdateActor(ctx, actorRef, store.PreconditionFrom(created), func(dbActor *ateapi.Actor) error { + dbActor.Status.State = ateapi.ActorState_ACTOR_STATE_RUNNING // Server-owned metadata must be derived from the stored resource, not // accepted from the mutation. dbActor.Metadata.Uid = "client-supplied-uid" @@ -673,7 +697,7 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac t.Fatalf("UpdateActor failed: %v", err) } - if updated.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if updated.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Errorf("UpdateActor returned state %v, want RUNNING", updated.GetStatus().GetState()) } if updated.GetMetadata().GetVersion() != 2 { @@ -704,10 +728,10 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac ctx := context.Background() mustCreateAtespace(t, s, testAtespace) - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "session-1", Atespace: testAtespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "default", Name: "test-template"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "session-1", Atespace: testAtespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "default", Name: "test-template"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, } if _, err := s.CreateActor(ctx, actor); err != nil { @@ -724,15 +748,15 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac } actorRef := resources.ActorRefFromActor(actor1) - if _, err := s.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor1), func(dbActor *ateapipb.Actor) error { - dbActor.Status.State = ateapipb.ActorState_ACTOR_STATE_RUNNING + if _, err := s.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor1), func(dbActor *ateapi.Actor) error { + dbActor.Status.State = ateapi.ActorState_ACTOR_STATE_RUNNING return nil }); err != nil { t.Fatalf("UpdateActor failed: %v", err) } - _, err = s.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor2), func(dbActor *ateapipb.Actor) error { - dbActor.Status.State = ateapipb.ActorState_ACTOR_STATE_SUSPENDED + _, err = s.UpdateActor(ctx, actorRef, store.PreconditionFrom(actor2), func(dbActor *ateapi.Actor) error { + dbActor.Status.State = ateapi.ActorState_ACTOR_STATE_SUSPENDED return nil }) if !errors.Is(err, store.ErrVersionConflict) { @@ -745,11 +769,11 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac ctx := context.Background() mustCreateAtespace(t, s, testAtespace) - newActor := func() *ateapipb.Actor { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "session-1", Atespace: testAtespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "default", Name: "test-template"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + newActor := func() *ateapi.Actor { + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "session-1", Atespace: testAtespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "default", Name: "test-template"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, } } @@ -759,8 +783,8 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac } actorRef := resources.ActorRefFromActor(original) - if _, err := s.UpdateActor(ctx, actorRef, store.PreconditionFrom(original), func(dbActor *ateapipb.Actor) error { - dbActor.Status.State = ateapipb.ActorState_ACTOR_STATE_DELETING + if _, err := s.UpdateActor(ctx, actorRef, store.PreconditionFrom(original), func(dbActor *ateapi.Actor) error { + dbActor.Status.State = ateapi.ActorState_ACTOR_STATE_DELETING return nil }); err != nil { t.Fatalf("marking actor deleting failed: %v", err) @@ -777,9 +801,9 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac } // original and recreated have different UIDs, so the mutation must never run - _, err = s.UpdateActor(ctx, actorRef, store.PreconditionFrom(original), func(dbActor *ateapipb.Actor) error { + _, err = s.UpdateActor(ctx, actorRef, store.PreconditionFrom(original), func(dbActor *ateapi.Actor) error { t.Error("mutate ran past its precondition once the guarded incarnation was gone") - dbActor.Status.State = ateapipb.ActorState_ACTOR_STATE_RUNNING + dbActor.Status.State = ateapi.ActorState_ACTOR_STATE_RUNNING return nil }) if !errors.Is(err, store.ErrUIDConflict) { @@ -800,18 +824,18 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac ctx := context.Background() mustCreateAtespace(t, s, testAtespace) - created, err := s.CreateActor(ctx, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "session-1", Atespace: testAtespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "default", Name: "test-template"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + created, err := s.CreateActor(ctx, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "session-1", Atespace: testAtespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "default", Name: "test-template"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) if err != nil { t.Fatalf("CreateActor failed: %v", err) } mutateErr := errors.New("mutation rejected") - if _, err := s.UpdateActor(ctx, resources.ActorRefFromActor(created), store.PreconditionFrom(created), func(dbActor *ateapipb.Actor) error { - dbActor.Status.State = ateapipb.ActorState_ACTOR_STATE_RUNNING + if _, err := s.UpdateActor(ctx, resources.ActorRefFromActor(created), store.PreconditionFrom(created), func(dbActor *ateapi.Actor) error { + dbActor.Status.State = ateapi.ActorState_ACTOR_STATE_RUNNING return fmt.Errorf("checking mutation: %w", mutateErr) }); !errors.Is(err, mutateErr) { t.Fatalf("UpdateActor error = %v, want one wrapping %v", err, mutateErr) @@ -831,10 +855,10 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac ctx := context.Background() mustCreateAtespace(t, s, testAtespace) - created, err := s.CreateActor(ctx, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "session-1", Atespace: testAtespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "default", Name: "test-template"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + created, err := s.CreateActor(ctx, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "session-1", Atespace: testAtespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "default", Name: "test-template"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) if err != nil { t.Fatalf("CreateActor failed: %v", err) @@ -865,7 +889,7 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - _, err := s.UpdateActor(ctx, tt.actorRef, tt.precondition, func(dbActor *ateapipb.Actor) error { + _, err := s.UpdateActor(ctx, tt.actorRef, tt.precondition, func(dbActor *ateapi.Actor) error { t.Fatal("mutate ran for a blind write") return nil }) @@ -879,19 +903,19 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac t.Run("MarkActorForDeletion", func(t *testing.T) { s := setup(t) mustCreateAtespace(t, s, testAtespace) - testMarkForDeletion(t, markForDeletionCase[resources.ActorRef, *ateapipb.Actor]{ + testMarkForDeletion(t, markForDeletionCase[resources.ActorRef, *ateapi.Actor]{ ref: resources.ActorRef{Atespace: testAtespace, Name: "session-1"}, input: newTestSuspendedActor(testAtespace, "session-1"), create: s.CreateActor, get: s.GetActor, update: s.UpdateActor, mark: s.MarkActorForDeletion, - mutate: func(toUpdate *ateapipb.Actor) error { - toUpdate.Status.State = ateapipb.ActorState_ACTOR_STATE_DELETING + mutate: func(toUpdate *ateapi.Actor) error { + toUpdate.Status.State = ateapi.ActorState_ACTOR_STATE_DELETING return nil }, - mutated: func(marked *ateapipb.Actor) bool { - return marked.GetStatus().GetState() == ateapipb.ActorState_ACTOR_STATE_DELETING + mutated: func(marked *ateapi.Actor) bool { + return marked.GetStatus().GetState() == ateapi.ActorState_ACTOR_STATE_DELETING }, }) }) @@ -899,11 +923,11 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac // The store does not gate the delete on state; the workflow does, and pins // the row delete to the uid it admitted. t.Run("DeleteActor", func(t *testing.T) { - for _, state := range []ateapipb.ActorState{ - ateapipb.ActorState_ACTOR_STATE_SUSPENDED, - ateapipb.ActorState_ACTOR_STATE_CRASHED, - ateapipb.ActorState_ACTOR_STATE_DELETING, - ateapipb.ActorState_ACTOR_STATE_RUNNING, + for _, state := range []ateapi.ActorState{ + ateapi.ActorState_ACTOR_STATE_SUSPENDED, + ateapi.ActorState_ACTOR_STATE_CRASHED, + ateapi.ActorState_ACTOR_STATE_DELETING, + ateapi.ActorState_ACTOR_STATE_RUNNING, } { t.Run(state.String(), func(t *testing.T) { s := setup(t) @@ -911,10 +935,10 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac mustCreateAtespace(t, s, testAtespace) actorRef := resources.ActorRef{Atespace: testAtespace, Name: "session-1"} - if _, err := s.CreateActor(ctx, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorRef.Name, Atespace: testAtespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "default", Name: "test-template"}, - Status: &ateapipb.ActorStatus{State: state}, + if _, err := s.CreateActor(ctx, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorRef.Name, Atespace: testAtespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "default", Name: "test-template"}, + Status: &ateapi.ActorStatus{State: state}, }); err != nil { t.Fatalf("CreateActor failed: %v", err) } @@ -947,7 +971,7 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac ctx := context.Background() mustCreateAtespace(t, s, testAtespace) actorRef := resources.ActorRef{Atespace: testAtespace, Name: "session-1"} - create := func() *ateapipb.Actor { + create := func() *ateapi.Actor { created, err := s.CreateActor(ctx, newTestSuspendedActor(testAtespace, actorRef.Name)) if err != nil { t.Fatalf("CreateActor failed: %v", err) @@ -1015,36 +1039,36 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac ctx := context.Background() mustCreateAtespace(t, s, testAtespace) - actor1 := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "id1", Atespace: testAtespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + actor1 := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "id1", Atespace: testAtespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{{ + Snapshots: []*ateapi.Snapshot{{ Generation: 1, - Owner: ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - DurableSnapshot: &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: testActorSnapshotURI("gs://bucket", testAtespace, "snapshot-1")}, + Owner: ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + DurableSnapshot: &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, + Object: &ateapi.ObjectSnapshot{SnapshotUri: testActorSnapshotURI("gs://bucket", testAtespace, "snapshot-1")}, }, }}, }, } - actor2 := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "id2", Atespace: testAtespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, + actor2 := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "id2", Atespace: testAtespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{{ + Snapshots: []*ateapi.Snapshot{{ Generation: 1, - Owner: ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - DurableSnapshot: &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: testActorSnapshotURI("gs://bucket", testAtespace, "snapshot-2")}, + Owner: ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + DurableSnapshot: &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, + Object: &ateapi.ObjectSnapshot{SnapshotUri: testActorSnapshotURI("gs://bucket", testAtespace, "snapshot-2")}, }, }}, }, @@ -1075,17 +1099,17 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac mustCreateAtespace(t, s, testAtespace) for i := 0; i < 5; i++ { - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: fmt.Sprintf("name%d", i), Atespace: testAtespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: fmt.Sprintf("name%d", i), Atespace: testAtespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, } if _, err := s.CreateActor(ctx, actor); err != nil { t.Fatalf("failed to create actor %d: %v", i, err) } } - var allActors []*ateapipb.Actor + var allActors []*ateapi.Actor pageToken := "" for { page, err := s.ListActors(ctx, "", store.ListOptions{PageSize: 2, PageToken: pageToken}) @@ -1117,14 +1141,14 @@ func runActorContractTests(t *testing.T, setup func(t *testing.T) store.Interfac mustCreateAtespace(t, s, "team-a") mustCreateAtespace(t, s, "team-b") - mkActor := func(atespace, name string) *ateapipb.Actor { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: name, Atespace: atespace}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + mkActor := func(atespace, name string) *ateapi.Actor { + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: name, Atespace: atespace}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, } } - for _, a := range []*ateapipb.Actor{mkActor("team-a", "a1"), mkActor("team-a", "a2"), mkActor("team-b", "b1")} { + for _, a := range []*ateapi.Actor{mkActor("team-a", "a1"), mkActor("team-a", "a2"), mkActor("team-b", "b1")} { if _, err := s.CreateActor(ctx, a); err != nil { t.Fatalf("CreateActor(%s/%s) failed: %v", a.GetMetadata().GetAtespace(), a.GetMetadata().GetName(), err) } @@ -1204,7 +1228,7 @@ func runActorTemplateContractTests(t *testing.T, setup func(t *testing.T) store. ctx := context.Background() mustCreateAtespace(t, s, testAtespace) ref := resources.ActorTemplateRef{Atespace: testAtespace, Name: "tmpl-a"} - create := func() *ateapipb.ActorTemplate { + create := func() *ateapi.ActorTemplate { created, err := s.CreateActorTemplate(ctx, newTestActorTemplate(testAtespace, ref.Name)) if err != nil { t.Fatalf("CreateActorTemplate failed: %v", err) @@ -1285,7 +1309,7 @@ func runActorTemplateContractTests(t *testing.T, setup func(t *testing.T) store. for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - _, err := s.UpdateActorTemplate(ctx, templateRef, tt.precondition, func(dbTemplate *ateapipb.ActorTemplate) error { + _, err := s.UpdateActorTemplate(ctx, templateRef, tt.precondition, func(dbTemplate *ateapi.ActorTemplate) error { t.Fatal("mutate ran for a blind write") return nil }) @@ -1299,7 +1323,7 @@ func runActorTemplateContractTests(t *testing.T, setup func(t *testing.T) store. t.Run("MarkActorTemplateForDeletion", func(t *testing.T) { s := setup(t) mustCreateAtespace(t, s, testAtespace) - testMarkForDeletion(t, markForDeletionCase[resources.ActorTemplateRef, *ateapipb.ActorTemplate]{ + testMarkForDeletion(t, markForDeletionCase[resources.ActorTemplateRef, *ateapi.ActorTemplate]{ ref: resources.ActorTemplateRef{Atespace: testAtespace, Name: "tmpl-a"}, input: newTestActorTemplate(testAtespace, "tmpl-a"), create: s.CreateActorTemplate, @@ -1324,20 +1348,20 @@ func runActorTemplateContractTests(t *testing.T, setup func(t *testing.T) store. // newTestSuspendedActor builds an actor that already holds a durable // snapshot, the state CreateTag tags from. -func newTestSuspendedActor(atespace, name string) *ateapipb.Actor { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, +func newTestSuspendedActor(atespace, name string) *ateapi.Actor { + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "ns1", Name: "tmpl1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{{ + Snapshots: []*ateapi.Snapshot{{ Generation: 1, - Owner: ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - DurableSnapshot: &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: testActorSnapshotURI("gs://private", atespace, name)}, + Owner: ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + DurableSnapshot: &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, + Object: &ateapi.ObjectSnapshot{SnapshotUri: testActorSnapshotURI("gs://private", atespace, name)}, }, }}, }, @@ -1347,20 +1371,20 @@ func newTestSuspendedActor(atespace, name string) *ateapipb.Actor { // newTestInProgressTag builds the row CreateTag reserves for a // tag of actor: ATESPACE-scoped, with a PENDING snapshot naming where the // copy is going. -func newTestInProgressTag(name string, actor *ateapipb.Actor) *ateapipb.Tag { +func newTestInProgressTag(name string, actor *ateapi.Actor) *ateapi.Tag { atespace := actor.GetMetadata().GetAtespace() - return &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: name}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - Status: &ateapipb.TagStatus{ + return &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: name}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + Status: &ateapi.TagStatus{ ActorTemplateUid: "template-uid", - Snapshot: &ateapipb.Snapshot{ + Snapshot: &ateapi.Snapshot{ Generation: 1, - Owner: ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - DurableSnapshot: &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING, - Object: &ateapipb.ObjectSnapshot{ + Owner: ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + DurableSnapshot: &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING, + Object: &ateapi.ObjectSnapshot{ SnapshotUri: testTagSnapshotURI("gs://private", atespace, name), }, }, @@ -1374,7 +1398,7 @@ func runTagContractTests(t *testing.T, setup func(t *testing.T) store.Interface) // seedSuspendedActor seeds an atespace and an actor holding a durable // snapshot, the precondition every tag test starts from. - seedSuspendedActor := func(t *testing.T, s store.Interface, atespace, name string) *ateapipb.Actor { + seedSuspendedActor := func(t *testing.T, s store.Interface, atespace, name string) *ateapi.Actor { t.Helper() mustCreateAtespace(t, s, atespace) actor, err := s.CreateActor(context.Background(), newTestSuspendedActor(atespace, name)) @@ -1407,7 +1431,7 @@ func runTagContractTests(t *testing.T, setup func(t *testing.T) store.Interface) } // A reserved tag has a PENDING snapshot storage entry and is not // usable until the copy lands and finalize marks it COMPLETED. - if got := tag.GetStatus().GetSnapshot().GetDurableSnapshot().GetStatus(); got != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING { + if got := tag.GetStatus().GetSnapshot().GetDurableSnapshot().GetStatus(); got != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING { t.Errorf("reserved tag snapshot storage status = %v, want PENDING", got) } if diff := cmp.Diff(inProgressTag, tag, protocmp.Transform(), ignoreUID, ignoreVersion, ignoreTimestamps); diff != "" { @@ -1429,21 +1453,21 @@ func runTagContractTests(t *testing.T, setup func(t *testing.T) store.Interface) if gotURI != wantURI { t.Errorf("finalized tag snapshot uri = %q, want %q", gotURI, wantURI) } - if got := ready.GetStatus().GetSnapshot().GetDurableSnapshot().GetStatus(); got != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { + if got := ready.GetStatus().GetSnapshot().GetDurableSnapshot().GetStatus(); got != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { t.Errorf("finalized tag snapshot storage status = %v, want COMPLETED", got) } - updated, err := s.UpdateTag(ctx, resources.TagRef{Atespace: "team-a", Name: "production"}, store.PreconditionFrom(ready), func(toUpdate *ateapipb.Tag) error { - toUpdate.Scope = ateapipb.TagScope_TAG_SCOPE_PUBLISHED + updated, err := s.UpdateTag(ctx, resources.TagRef{Atespace: "team-a", Name: "production"}, store.PreconditionFrom(ready), func(toUpdate *ateapi.Tag) error { + toUpdate.Scope = ateapi.TagScope_TAG_SCOPE_PUBLISHED return nil }) if err != nil { t.Fatalf("UpdateTag failed: %v", err) } - if updated.GetScope() != ateapipb.TagScope_TAG_SCOPE_PUBLISHED || updated.GetMetadata().GetVersion() != ready.GetMetadata().GetVersion()+1 { + if updated.GetScope() != ateapi.TagScope_TAG_SCOPE_PUBLISHED || updated.GetMetadata().GetVersion() != ready.GetMetadata().GetVersion()+1 { t.Errorf("updated tag = %v, want published scope and advanced version", updated) } - if _, err := s.UpdateTag(ctx, resources.TagRef{Atespace: "team-a", Name: "production"}, store.PreconditionFrom(ready), func(toUpdate *ateapipb.Tag) error { + if _, err := s.UpdateTag(ctx, resources.TagRef{Atespace: "team-a", Name: "production"}, store.PreconditionFrom(ready), func(toUpdate *ateapi.Tag) error { toUpdate.Scope = ready.GetScope() return nil }); !errors.Is(err, store.ErrVersionConflict) { @@ -1471,7 +1495,7 @@ func runTagContractTests(t *testing.T, setup func(t *testing.T) store.Interface) t.Fatalf("CreateActor failed: %v", err) } tagRef := resources.TagRef{Atespace: testAtespace, Name: "production"} - create := func() *ateapipb.Tag { + create := func() *ateapi.Tag { created, err := s.CreateTag(ctx, newTestInProgressTag(tagRef.Name, actor)) if err != nil { t.Fatalf("CreateTag failed: %v", err) @@ -1529,35 +1553,35 @@ func runTagContractTests(t *testing.T, setup func(t *testing.T) store.Interface) tests := []struct { name string - mutate func(*ateapipb.Tag) + mutate func(*ateapi.Tag) }{ { name: "snapshot uri", - mutate: func(toUpdate *ateapipb.Tag) { + mutate: func(toUpdate *ateapi.Tag) { toUpdate.Status.Snapshot.DurableSnapshot.Object.SnapshotUri = "gs://private/elsewhere" }, }, { name: "snapshot content scope", - mutate: func(toUpdate *ateapipb.Tag) { - toUpdate.Status.Snapshot.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES + mutate: func(toUpdate *ateapi.Tag) { + toUpdate.Status.Snapshot.Fidelity = ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES }, }, { name: "clearing the snapshot", - mutate: func(toUpdate *ateapipb.Tag) { + mutate: func(toUpdate *ateapi.Tag) { toUpdate.Status.Snapshot = nil }, }, { name: "actor template uid", - mutate: func(toUpdate *ateapipb.Tag) { toUpdate.Status.ActorTemplateUid = "other-template-uid" }, + mutate: func(toUpdate *ateapi.Tag) { toUpdate.Status.ActorTemplateUid = "other-template-uid" }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - _, err := s.UpdateTag(ctx, resources.TagRef{Atespace: "team-a", Name: "production"}, store.PreconditionFrom(tag), func(toUpdate *ateapipb.Tag) error { + _, err := s.UpdateTag(ctx, resources.TagRef{Atespace: "team-a", Name: "production"}, store.PreconditionFrom(tag), func(toUpdate *ateapi.Tag) error { tt.mutate(toUpdate) return nil }) @@ -1583,7 +1607,7 @@ func runTagContractTests(t *testing.T, setup func(t *testing.T) store.Interface) if err != nil { t.Fatalf("CreateTag without a snapshot failed: %v", err) } - recorded, err := s.UpdateTag(ctx, tagRef, store.PreconditionFrom(reserved), func(toUpdate *ateapipb.Tag) error { + recorded, err := s.UpdateTag(ctx, tagRef, store.PreconditionFrom(reserved), func(toUpdate *ateapi.Tag) error { toUpdate.Status.Snapshot = proto.CloneOf(pending) return nil }) @@ -1595,7 +1619,7 @@ func runTagContractTests(t *testing.T, setup func(t *testing.T) store.Interface) } // Once recorded, the snapshot is fixed like any other. - if _, err := s.UpdateTag(ctx, tagRef, store.PreconditionFrom(recorded), func(toUpdate *ateapipb.Tag) error { + if _, err := s.UpdateTag(ctx, tagRef, store.PreconditionFrom(recorded), func(toUpdate *ateapi.Tag) error { toUpdate.Status.Snapshot.DurableSnapshot.Object.SnapshotUri = "gs://private/elsewhere" return nil }); !errors.Is(err, store.ErrImmutableField) { @@ -1639,6 +1663,31 @@ func runTagContractTests(t *testing.T, setup func(t *testing.T) store.Interface) } }) + t.Run("Tag_MalformedSnapshotURI", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + actor := seedSuspendedActor(t, s, "team-a", "actor-1") + + malformed := newTestInProgressTag("production", actor) + malformed.Status.Snapshot.DurableSnapshot.Object.SnapshotUri = "gs://private/not-a-snapshot" + if _, err := s.CreateTag(ctx, malformed); err == nil { + t.Errorf("CreateTag with a malformed snapshot URI succeeded, want an error") + } + + input := newTestInProgressTag("staging", actor) + input.Status.Snapshot = nil + reserved, err := s.CreateTag(ctx, input) + if err != nil { + t.Fatalf("CreateTag without a snapshot failed: %v", err) + } + if _, err := s.UpdateTag(ctx, resources.TagRefFromTag(reserved), store.PreconditionFrom(reserved), func(toUpdate *ateapi.Tag) error { + toUpdate.Status.Snapshot = proto.CloneOf(malformed.Status.Snapshot) + return nil + }); err == nil { + t.Errorf("recording a malformed snapshot URI succeeded, want an error") + } + }) + t.Run("UpdateTag_MissingPrecondition", func(t *testing.T) { s := setup(t) ctx := context.Background() @@ -1665,7 +1714,7 @@ func runTagContractTests(t *testing.T, setup func(t *testing.T) store.Interface) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - _, err := s.UpdateTag(ctx, resources.TagRef{Atespace: "team-a", Name: "production"}, tt.precondition, func(toUpdate *ateapipb.Tag) error { + _, err := s.UpdateTag(ctx, resources.TagRef{Atespace: "team-a", Name: "production"}, tt.precondition, func(toUpdate *ateapi.Tag) error { t.Fatal("mutate ran for a blind write") return nil }) @@ -1683,7 +1732,7 @@ func runTagContractTests(t *testing.T, setup func(t *testing.T) store.Interface) if err != nil { t.Fatalf("CreateActor failed: %v", err) } - testMarkForDeletion(t, markForDeletionCase[resources.TagRef, *ateapipb.Tag]{ + testMarkForDeletion(t, markForDeletionCase[resources.TagRef, *ateapi.Tag]{ ref: resources.TagRef{Atespace: testAtespace, Name: "production"}, input: newTestInProgressTag("production", actor), create: s.CreateTag, @@ -1703,7 +1752,7 @@ func runTagContractTests(t *testing.T, setup func(t *testing.T) store.Interface) } } - var scoped []*ateapipb.Tag + var scoped []*ateapi.Tag for token := ""; ; { page, err := s.ListTags(ctx, "team-a", store.ListOptions{PageSize: 2, PageToken: token}) if err != nil { @@ -1719,7 +1768,7 @@ func runTagContractTests(t *testing.T, setup func(t *testing.T) store.Interface) t.Errorf("scoped ListTags returned %d tags, want 3", len(scoped)) } - var global []*ateapipb.Tag + var global []*ateapi.Tag for token := ""; ; { page, err := s.ListTags(ctx, "", store.ListOptions{PageSize: 2, PageToken: token}) if err != nil { @@ -1739,14 +1788,14 @@ func runTagContractTests(t *testing.T, setup func(t *testing.T) store.Interface) // finalizeTag mutates a reserved tag the way the tag workflow's second // transaction does: it marks the pending snapshot storage COMPLETED. -func finalizeTag(toUpdate *ateapipb.Tag) error { - toUpdate.Status.Snapshot.DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED +func finalizeTag(toUpdate *ateapi.Tag) error { + toUpdate.Status.Snapshot.DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED return nil } // storeTag reserves and finalizes tag, for tests whose subject is a usable tag // rather than the two-phase create itself. -func storeTag(t *testing.T, s store.Interface, tag *ateapipb.Tag) *ateapipb.Tag { +func storeTag(t *testing.T, s store.Interface, tag *ateapi.Tag) *ateapi.Tag { t.Helper() reserved, err := s.CreateTag(context.Background(), tag) if err != nil { @@ -1808,7 +1857,7 @@ func runWorkerContractTests(t *testing.T, setup func(t *testing.T) store.Interfa t.Errorf("CreateWorker stored unset create/update time") } - want := proto.Clone(worker).(*ateapipb.Worker) + want := proto.Clone(worker).(*ateapi.Worker) want.Metadata.Version = 1 if diff := cmp.Diff(want, got, protocmp.Transform(), ignoreUID, ignoreTimestamps); diff != "" { t.Errorf("GetWorker returned unexpected worker (-want +got):\n%s", diff) @@ -1853,8 +1902,8 @@ func runWorkerContractTests(t *testing.T, setup func(t *testing.T) store.Interfa } defer watch.Close() - updated, err := s.UpdateWorker(ctx, testWorkerName, store.PreconditionFrom(created), func(toUpdate *ateapipb.Worker) error { - toUpdate.Status.State = ateapipb.WorkerState_WORKER_STATE_DRAINING + updated, err := s.UpdateWorker(ctx, testWorkerName, store.PreconditionFrom(created), func(toUpdate *ateapi.Worker) error { + toUpdate.Status.State = ateapi.WorkerState_WORKER_STATE_DRAINING return nil }) if err != nil { @@ -1872,8 +1921,8 @@ func runWorkerContractTests(t *testing.T, setup func(t *testing.T) store.Interfa t.Errorf("expected version 2, got %d", got.GetMetadata().GetVersion()) } - want := proto.Clone(worker).(*ateapipb.Worker) - want.Status.State = ateapipb.WorkerState_WORKER_STATE_DRAINING + want := proto.Clone(worker).(*ateapi.Worker) + want.Status.State = ateapi.WorkerState_WORKER_STATE_DRAINING want.Metadata.Version = 2 if diff := cmp.Diff(want, got, protocmp.Transform(), ignoreUID, ignoreTimestamps); diff != "" { t.Errorf("UpdateWorker yielded unexpected state in DB (-want +got):\n%s", diff) @@ -1895,7 +1944,7 @@ func runWorkerContractTests(t *testing.T, setup func(t *testing.T) store.Interfa // A well-formed precondition, so it is the missing worker rather than the // guard that decides the error. precondition := store.Precondition{UID: otherTestWorkerName, Version: 1} - _, err := s.UpdateWorker(ctx, testWorkerName, precondition, func(*ateapipb.Worker) error { + _, err := s.UpdateWorker(ctx, testWorkerName, precondition, func(*ateapi.Worker) error { t.Error("mutate ran for a worker that does not exist") return nil }) @@ -1922,7 +1971,7 @@ func runWorkerContractTests(t *testing.T, setup func(t *testing.T) store.Interfa {"guarding on only a version", store.Precondition{Version: created.GetMetadata().GetVersion()}}, } { t.Run(tt.name, func(t *testing.T) { - _, err := s.UpdateWorker(ctx, testWorkerName, tt.precondition, func(*ateapipb.Worker) error { + _, err := s.UpdateWorker(ctx, testWorkerName, tt.precondition, func(*ateapi.Worker) error { t.Error("mutate ran for a blind write") return nil }) @@ -1935,19 +1984,19 @@ func runWorkerContractTests(t *testing.T, setup func(t *testing.T) store.Interfa t.Run("MarkWorkerForDeletion", func(t *testing.T) { s := setup(t) - testMarkForDeletion(t, markForDeletionCase[string, *ateapipb.Worker]{ + testMarkForDeletion(t, markForDeletionCase[string, *ateapi.Worker]{ ref: testWorkerName, input: newTestWorker(testWorkerName, "pod-1"), create: s.CreateWorker, get: s.GetWorker, update: s.UpdateWorker, mark: s.MarkWorkerForDeletion, - mutate: func(toUpdate *ateapipb.Worker) error { - toUpdate.Status = &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_DRAINING} + mutate: func(toUpdate *ateapi.Worker) error { + toUpdate.Status = &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_DRAINING} return nil }, - mutated: func(marked *ateapipb.Worker) bool { - return marked.GetStatus().GetState() == ateapipb.WorkerState_WORKER_STATE_DRAINING + mutated: func(marked *ateapi.Worker) bool { + return marked.GetStatus().GetState() == ateapi.WorkerState_WORKER_STATE_DRAINING }, }) }) @@ -2001,7 +2050,7 @@ func runWorkerContractTests(t *testing.T, setup func(t *testing.T) store.Interfa t.Fatalf("recreated worker reused uid %s, want a fresh one", recreated.GetMetadata().GetUid()) } - _, err = s.UpdateWorker(ctx, testWorkerName, store.PreconditionFrom(original), func(toUpdate *ateapipb.Worker) error { + _, err = s.UpdateWorker(ctx, testWorkerName, store.PreconditionFrom(original), func(toUpdate *ateapi.Worker) error { t.Error("mutate ran past its precondition once the guarded incarnation was gone") toUpdate.Labels = map[string]string{"tier": "edited-anyway"} return nil @@ -2033,15 +2082,15 @@ func runWorkerContractTests(t *testing.T, setup func(t *testing.T) store.Interfa if err != nil { t.Fatalf("GetWorker failed: %v", err) } - if _, err := s.UpdateWorker(ctx, testWorkerName, store.PreconditionFrom(observed), func(toUpdate *ateapipb.Worker) error { - toUpdate.Status.State = ateapipb.WorkerState_WORKER_STATE_DRAINING + if _, err := s.UpdateWorker(ctx, testWorkerName, store.PreconditionFrom(observed), func(toUpdate *ateapi.Worker) error { + toUpdate.Status.State = ateapi.WorkerState_WORKER_STATE_DRAINING return nil }); err != nil { t.Fatalf("UpdateWorker failed: %v", err) } - _, err = s.UpdateWorker(ctx, testWorkerName, store.PreconditionFrom(observed), func(toUpdate *ateapipb.Worker) error { - toUpdate.Status.State = ateapipb.WorkerState_WORKER_STATE_ACTIVE + _, err = s.UpdateWorker(ctx, testWorkerName, store.PreconditionFrom(observed), func(toUpdate *ateapi.Worker) error { + toUpdate.Status.State = ateapi.WorkerState_WORKER_STATE_ACTIVE return nil }) if !errors.Is(err, store.ErrVersionConflict) { @@ -2063,7 +2112,7 @@ func runWorkerContractTests(t *testing.T, setup func(t *testing.T) store.Interfa } sentinel := errors.New("nothing to do") - _, err = s.UpdateWorker(ctx, testWorkerName, store.PreconditionFrom(created), func(toUpdate *ateapipb.Worker) error { + _, err = s.UpdateWorker(ctx, testWorkerName, store.PreconditionFrom(created), func(toUpdate *ateapi.Worker) error { toUpdate.Labels = map[string]string{"tier": "edited-anyway"} return sentinel }) @@ -2109,11 +2158,11 @@ func runWorkerContractTests(t *testing.T, setup func(t *testing.T) store.Interfa // claim actually moves on the Worker record now that the // assignments themselves are separate records. The cpu limit carries // the claimant's number so the winner is identifiable. - _, err := s.UpdateWorker(ctx, testWorkerName, store.PreconditionFrom(created), func(toUpdate *ateapipb.Worker) error { + _, err := s.UpdateWorker(ctx, testWorkerName, store.PreconditionFrom(created), func(toUpdate *ateapi.Worker) error { if toUpdate.GetStatus().GetAllocated().GetActors() > 0 { return errTaken } - toUpdate.Status.Allocated = &ateapipb.WorkerResources{Actors: 1, CpuMillicores: int64(i) + 1, MemoryBytes: 0} + toUpdate.Status.Allocated = &ateapi.WorkerResources{Actors: 1, CpuMillicores: int64(i) + 1, MemoryBytes: 0} return nil }) switch { @@ -2200,7 +2249,7 @@ func runWorkerContractTests(t *testing.T, setup func(t *testing.T) store.Interfa t.Run("DeleteWorker_Preconditions", func(t *testing.T) { s := setup(t) ctx := context.Background() - create := func() *ateapipb.Worker { + create := func() *ateapi.Worker { created, err := s.CreateWorker(ctx, newTestWorker(testWorkerName, "pod-1")) if err != nil { t.Fatalf("CreateWorker failed: %v", err) @@ -2328,7 +2377,7 @@ func runWorkerContractTests(t *testing.T, setup func(t *testing.T) store.Interfa } } - var allWorkers []*ateapipb.Worker + var allWorkers []*ateapi.Worker pageToken := "" for { page, err := s.ListWorkers(ctx, store.ListOptions{PageSize: 2, PageToken: pageToken}) @@ -2362,9 +2411,9 @@ func runWorkerAssignmentContractTests(t *testing.T, setup func(t *testing.T) sto // newTestAssignment describes one Actor's placement, sized so that a total // over several of them is unambiguous about which were counted. - newTestAssignment := func(actorUID string, cpuMilli, memoryBytes int64) *ateapipb.ActorAssignment { - return &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "actor-" + actorUID}, + newTestAssignment := func(actorUID string, cpuMilli, memoryBytes int64) *ateapi.ActorAssignment { + return &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-" + actorUID}, ActorUid: actorUID, Resources: resources.CPUMemory(cpuMilli, memoryBytes), } @@ -2372,7 +2421,7 @@ func runWorkerAssignmentContractTests(t *testing.T, setup func(t *testing.T) sto // bind binds one assignment with no admission check, for the tests that care // about the outcome rather than about admission. - bind := func(t *testing.T, s store.Interface, workerName string, assignment *ateapipb.ActorAssignment) { + bind := func(t *testing.T, s store.Interface, workerName string, assignment *ateapi.ActorAssignment) { t.Helper() ctx := context.Background() if err := s.BindActorToWorker(ctx, workerName, assignment, nil); err != nil { @@ -2408,7 +2457,7 @@ func runWorkerAssignmentContractTests(t *testing.T, setup func(t *testing.T) sto if err != nil { t.Fatalf("GetWorker failed: %v", err) } - want := &ateapipb.WorkerResources{Actors: 1, CpuMillicores: 500, MemoryBytes: 1 << 20} + want := &ateapi.WorkerResources{Actors: 1, CpuMillicores: 500, MemoryBytes: 1 << 20} if diff := cmp.Diff(want, worker.GetStatus().GetAllocated(), protocmp.Transform()); diff != "" { t.Errorf("allocated mismatch (-want +got):\n%s", diff) } @@ -2441,7 +2490,7 @@ func runWorkerAssignmentContractTests(t *testing.T, setup func(t *testing.T) sto if err != nil { t.Fatalf("GetWorker failed: %v", err) } - want := &ateapipb.WorkerResources{Actors: 1, CpuMillicores: 250, MemoryBytes: 1 << 21} + want := &ateapi.WorkerResources{Actors: 1, CpuMillicores: 250, MemoryBytes: 1 << 21} if diff := cmp.Diff(want, worker.GetStatus().GetAllocated(), protocmp.Transform()); diff != "" { t.Errorf("allocated mismatch after rebinding the same actor (-want +got):\n%s", diff) } @@ -2498,7 +2547,7 @@ func runWorkerAssignmentContractTests(t *testing.T, setup func(t *testing.T) sto full := errors.New("worker is full") err := s.BindActorToWorker(ctx, testWorkerName, newTestAssignment("uid-1", 500, 0), - func(*ateapipb.Worker) error { return full }) + func(*ateapi.Worker) error { return full }) if !errors.Is(err, full) { t.Errorf("BindActorToWorker with a refusing admit = %v, want %v", err, full) } @@ -2532,10 +2581,10 @@ func runWorkerAssignmentContractTests(t *testing.T, setup func(t *testing.T) sto } bind(t, s, testWorkerName, newTestAssignment("uid-1", 500, 0)) - var admitted []*ateapipb.WorkerResources + var admitted []*ateapi.WorkerResources full := errors.New("worker is full") err := s.BindActorToWorker(ctx, testWorkerName, newTestAssignment("uid-1", 5000, 0), - func(fresh *ateapipb.Worker) error { + func(fresh *ateapi.Worker) error { admitted = append(admitted, fresh.GetStatus().GetAllocated()) return full }) @@ -2556,7 +2605,7 @@ func runWorkerAssignmentContractTests(t *testing.T, setup func(t *testing.T) sto if err != nil { t.Fatalf("GetWorker failed: %v", err) } - want := &ateapipb.WorkerResources{Actors: 1, CpuMillicores: 500, MemoryBytes: 0} + want := &ateapi.WorkerResources{Actors: 1, CpuMillicores: 500, MemoryBytes: 0} if diff := cmp.Diff(want, worker.GetStatus().GetAllocated(), protocmp.Transform()); diff != "" { t.Errorf("a refused replacement changed the allocation (-want +got):\n%s", diff) } @@ -2572,7 +2621,7 @@ func runWorkerAssignmentContractTests(t *testing.T, setup func(t *testing.T) sto const claims = 16 full := errors.New("worker is full") - roomForOne := func(w *ateapipb.Worker) error { + roomForOne := func(w *ateapi.Worker) error { if w.GetStatus().GetAllocated().GetActors() >= 1 { return full } @@ -2643,7 +2692,7 @@ func runWorkerAssignmentContractTests(t *testing.T, setup func(t *testing.T) sto if err != nil { t.Fatalf("GetWorker failed: %v", err) } - want := &ateapipb.WorkerResources{Actors: 1, CpuMillicores: 500, MemoryBytes: 1 << 20} + want := &ateapi.WorkerResources{Actors: 1, CpuMillicores: 500, MemoryBytes: 1 << 20} if diff := cmp.Diff(want, first.GetStatus().GetAllocated(), protocmp.Transform()); diff != "" { t.Errorf("first worker's allocation changed (-want +got):\n%s", diff) } @@ -2746,7 +2795,7 @@ func runWorkerAssignmentContractTests(t *testing.T, setup func(t *testing.T) sto } // The returned Worker is what the caller feeds the cache, so it has to // be the post-release state, not the copy that went in. - wantReleased := &ateapipb.WorkerResources{Actors: 1, CpuMillicores: 250, MemoryBytes: 1 << 21} + wantReleased := &ateapi.WorkerResources{Actors: 1, CpuMillicores: 250, MemoryBytes: 1 << 21} if diff := cmp.Diff(wantReleased, released.GetStatus().GetAllocated(), protocmp.Transform()); diff != "" { t.Errorf("returned worker's allocated mismatch (-want +got):\n%s", diff) } @@ -2762,7 +2811,7 @@ func runWorkerAssignmentContractTests(t *testing.T, setup func(t *testing.T) sto if err != nil { t.Fatalf("GetWorker failed: %v", err) } - want := &ateapipb.WorkerResources{Actors: 1, CpuMillicores: 250, MemoryBytes: 1 << 21} + want := &ateapi.WorkerResources{Actors: 1, CpuMillicores: 250, MemoryBytes: 1 << 21} if diff := cmp.Diff(want, worker.GetStatus().GetAllocated(), protocmp.Transform()); diff != "" { t.Errorf("allocated mismatch after release (-want +got):\n%s", diff) } @@ -3028,7 +3077,7 @@ func runAtespaceContractTests(t *testing.T, setup func(t *testing.T) store.Inter } } - var allAtespaces []*ateapipb.Atespace + var allAtespaces []*ateapi.Atespace pageToken := "" for { page, err := s.ListAtespaces(ctx, store.ListOptions{PageSize: 2, PageToken: pageToken}) @@ -3179,7 +3228,7 @@ func runAtespaceContractTests(t *testing.T, setup func(t *testing.T) store.Inter t.Run("DeleteAtespace_Preconditions", func(t *testing.T) { s := setup(t) ctx := context.Background() - create := func() *ateapipb.Atespace { + create := func() *ateapi.Atespace { created, err := s.CreateAtespace(ctx, newTestAtespace("team-a")) if err != nil { t.Fatalf("CreateAtespace failed: %v", err) @@ -3251,7 +3300,7 @@ func runAtespaceContractTests(t *testing.T, setup func(t *testing.T) store.Inter if _, err := s.CreateAtespace(ctx, newTestAtespace("team-a")); err != nil { t.Fatalf("CreateAtespace failed: %v", err) } - if _, err := s.CreateActor(ctx, &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Name: "id1", Atespace: "team-a"}, Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_DELETING}}); err != nil { + if _, err := s.CreateActor(ctx, &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Name: "id1", Atespace: "team-a"}, Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_DELETING}}); err != nil { t.Fatalf("CreateActor failed: %v", err) } if _, err := s.DeleteAtespace(ctx, "team-a", store.DeletePreconditions{}); !errors.Is(err, store.ErrFailedPrecondition) { @@ -3269,7 +3318,7 @@ func runAtespaceContractTests(t *testing.T, setup func(t *testing.T) store.Inter if _, err := s.CreateAtespace(ctx, newTestAtespace("team-a")); err != nil { t.Fatalf("CreateAtespace failed: %v", err) } - if _, err := s.CreateActor(ctx, &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Name: "id1", Atespace: "team-a"}, Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_DELETING}}); err != nil { + if _, err := s.CreateActor(ctx, &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Name: "id1", Atespace: "team-a"}, Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_DELETING}}); err != nil { t.Fatalf("CreateActor failed: %v", err) } if _, err := s.DeleteAtespace(ctx, "team-a", store.DeletePreconditions{}); !errors.Is(err, store.ErrFailedPrecondition) { @@ -3293,7 +3342,7 @@ func runAtespaceContractTests(t *testing.T, setup func(t *testing.T) store.Inter if _, err := s.CreateAtespace(ctx, newTestAtespace("team-b")); err != nil { t.Fatalf("CreateAtespace(team-b) failed: %v", err) } - if _, err := s.CreateActor(ctx, &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Name: "id1", Atespace: "team-b"}, Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}}); err != nil { + if _, err := s.CreateActor(ctx, &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Name: "id1", Atespace: "team-b"}, Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}}); err != nil { t.Fatalf("CreateActor failed: %v", err) } @@ -3399,10 +3448,10 @@ func runUnknownFieldContractTests(t *testing.T, setup func(t *testing.T) store.I s := setup(t) ctx := context.Background() mustCreateAtespace(t, s, testAtespace) - created, err := s.CreateActor(ctx, withUnknownField(&ateapipb.Actor{ - Metadata: withUnknownField(&ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "actor-1"}), - ActorTemplate: withUnknownField(&ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl-1"}), - Status: withUnknownField(&ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_DELETING}), + created, err := s.CreateActor(ctx, withUnknownField(&ateapi.Actor{ + Metadata: withUnknownField(&ateapi.ResourceMetadata{Atespace: testAtespace, Name: "actor-1"}), + ActorTemplate: withUnknownField(&ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-1"}), + Status: withUnknownField(&ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_DELETING}), })) if err != nil { t.Fatalf("CreateActor failed: %v", err) @@ -3421,7 +3470,7 @@ func runUnknownFieldContractTests(t *testing.T, setup func(t *testing.T) store.I } assertPruned(t, "ListActors", created, list.Items[0]) - updated, err := s.UpdateActor(ctx, ref, store.PreconditionFrom(got), func(toUpdate *ateapipb.Actor) error { + updated, err := s.UpdateActor(ctx, ref, store.PreconditionFrom(got), func(toUpdate *ateapi.Actor) error { requireNoUnknownFields(t, "UpdateActor mutation input", toUpdate) return nil }) @@ -3441,18 +3490,18 @@ func runUnknownFieldContractTests(t *testing.T, setup func(t *testing.T) store.I s := setup(t) ctx := context.Background() mustCreateAtespace(t, s, testAtespace) - actor, err := s.CreateActor(ctx, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "actor-1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + actor, err := s.CreateActor(ctx, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "actor-1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, }) if err != nil { t.Fatalf("CreateActor failed: %v", err) } ref := resources.ActorRefFromActor(actor) - created, err := s.CreateEgressPolicy(ctx, ref, withUnknownField(&ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "default"}, - Rules: []*ateapipb.EgressRule{withUnknownField(&ateapipb.EgressRule{ - Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{80}}}, + created, err := s.CreateEgressPolicy(ctx, ref, withUnknownField(&ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "default"}, + Rules: []*ateapi.EgressRule{withUnknownField(&ateapi.EgressRule{ + Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{80}}}, })}, })) if err != nil { @@ -3465,7 +3514,7 @@ func runUnknownFieldContractTests(t *testing.T, setup func(t *testing.T) store.I } assertPruned(t, "GetEgressPolicy", created, got) - updated, err := s.UpdateEgressPolicy(ctx, ref, store.PreconditionFrom(got), func(toUpdate *ateapipb.EgressPolicy) error { + updated, err := s.UpdateEgressPolicy(ctx, ref, store.PreconditionFrom(got), func(toUpdate *ateapi.EgressPolicy) error { requireNoUnknownFields(t, "UpdateEgressPolicy mutation input", toUpdate) return nil }) @@ -3511,7 +3560,7 @@ func runUnknownFieldContractTests(t *testing.T, setup func(t *testing.T) store.I } assertPruned(t, "ListTags", created, list.Items[0]) - updated, err := s.UpdateTag(ctx, tagRef, store.PreconditionFrom(got), func(toUpdate *ateapipb.Tag) error { + updated, err := s.UpdateTag(ctx, tagRef, store.PreconditionFrom(got), func(toUpdate *ateapi.Tag) error { requireNoUnknownFields(t, "UpdateTag mutation input", toUpdate) return nil }) @@ -3530,8 +3579,8 @@ func runUnknownFieldContractTests(t *testing.T, setup func(t *testing.T) store.I t.Run("UnknownFields_Atespace", func(t *testing.T) { s := setup(t) ctx := context.Background() - created, err := s.CreateAtespace(ctx, withUnknownField(&ateapipb.Atespace{ - Metadata: withUnknownField(&ateapipb.ResourceMetadata{Name: testAtespace}), + created, err := s.CreateAtespace(ctx, withUnknownField(&ateapi.Atespace{ + Metadata: withUnknownField(&ateapi.ResourceMetadata{Name: testAtespace}), })) if err != nil { t.Fatalf("CreateAtespace failed: %v", err) @@ -3581,7 +3630,7 @@ func runUnknownFieldContractTests(t *testing.T, setup func(t *testing.T) store.I } assertPruned(t, "ListActorTemplates", created, list.Items[0]) - updated, err := s.UpdateActorTemplate(ctx, ref, store.PreconditionFrom(got), func(toUpdate *ateapipb.ActorTemplate) error { + updated, err := s.UpdateActorTemplate(ctx, ref, store.PreconditionFrom(got), func(toUpdate *ateapi.ActorTemplate) error { requireNoUnknownFields(t, "UpdateActorTemplate mutation input", toUpdate) return nil }) @@ -3632,7 +3681,7 @@ func runUnknownFieldContractTests(t *testing.T, setup func(t *testing.T) store.I } assertPruned(t, "ListWorkers", created, list.Items[0]) - updated, err := s.UpdateWorker(ctx, testWorkerName, store.PreconditionFrom(got), func(toUpdate *ateapipb.Worker) error { + updated, err := s.UpdateWorker(ctx, testWorkerName, store.PreconditionFrom(got), func(toUpdate *ateapi.Worker) error { requireNoUnknownFields(t, "UpdateWorker mutation input", toUpdate) return nil }) @@ -3651,6 +3700,6 @@ func runUnknownFieldContractTests(t *testing.T, setup func(t *testing.T) store.I // sameAllocation compares two allocation totals by what they hold, so an // absent total and a zeroed one are the same. -func sameAllocation(a, b *ateapipb.WorkerResources) bool { +func sameAllocation(a, b *ateapi.WorkerResources) bool { return a.GetActors() == b.GetActors() && a.GetCpuMillicores() == b.GetCpuMillicores() && a.GetMemoryBytes() == b.GetMemoryBytes() } diff --git a/cmd/ateapi/internal/store/storetest/storetest.go b/cmd/ateapi/internal/store/storetest/storetest.go index 3ed744c6a7..7bc219b3d2 100644 --- a/cmd/ateapi/internal/store/storetest/storetest.go +++ b/cmd/ateapi/internal/store/storetest/storetest.go @@ -31,12 +31,12 @@ import ( "github.com/jackc/pgx/v5/pgxpool" "github.com/testcontainers/testcontainers-go/modules/postgres" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/authz" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/atepg" "go.ate.dev/substrate/cmd/ateapi/internal/store/dockerenv" "go.ate.dev/substrate/internal/installdefaults" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) var ( @@ -113,7 +113,7 @@ func DefaultSystemPrincipals() authz.SystemPrincipals { // this before seeding those resources. func MustCreateAtespace(t *testing.T, ctx context.Context, s store.Interface, name string) { t.Helper() - _, err := s.CreateAtespace(ctx, &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: name}}) + _, err := s.CreateAtespace(ctx, &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: name}}) if err != nil && !errors.Is(err, store.ErrAlreadyExists) { t.Fatalf("creating test atespace %q: %v", name, err) } @@ -122,7 +122,7 @@ func MustCreateAtespace(t *testing.T, ctx context.Context, s store.Interface, na // MustCreateActor ensures actor's parent atespace exists, then creates actor. // Use the store method directly only in tests that exercise missing-parent // behavior. -func MustCreateActor(t *testing.T, ctx context.Context, s store.Interface, actor *ateapipb.Actor) *ateapipb.Actor { +func MustCreateActor(t *testing.T, ctx context.Context, s store.Interface, actor *ateapi.Actor) *ateapi.Actor { t.Helper() atespace := actor.GetMetadata().GetAtespace() MustCreateAtespace(t, ctx, s, atespace) @@ -137,7 +137,7 @@ func MustCreateActor(t *testing.T, ctx context.Context, s store.Interface, actor // tag as given — ready or still pending, whichever state the test needs to // start from. Use the store method directly only in tests that exercise // missing-parent behavior. -func MustCreateTag(t *testing.T, ctx context.Context, s store.Interface, tag *ateapipb.Tag) *ateapipb.Tag { +func MustCreateTag(t *testing.T, ctx context.Context, s store.Interface, tag *ateapi.Tag) *ateapi.Tag { t.Helper() atespace := tag.GetMetadata().GetAtespace() name := tag.GetMetadata().GetName() diff --git a/cmd/ateapi/internal/workercache/workercache.go b/cmd/ateapi/internal/workercache/workercache.go index 8ab910b4b1..f631fca6a0 100644 --- a/cmd/ateapi/internal/workercache/workercache.go +++ b/cmd/ateapi/internal/workercache/workercache.go @@ -26,8 +26,8 @@ import ( "sync/atomic" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" - "go.ate.dev/substrate/pkg/proto/ateapipb" "k8s.io/apimachinery/pkg/util/wait" ) @@ -43,8 +43,8 @@ type Cache struct { relistInterval time.Duration mu sync.RWMutex - workers map[string]*ateapipb.Worker - handlers []func(*ateapipb.Worker) + workers map[string]*ateapi.Worker + handlers []func(*ateapi.Worker) ready atomic.Bool } @@ -54,10 +54,10 @@ type Cache struct { // finds new or at a different version, so a change a missed event carried // still reaches it. It runs on the goroutine applying the change and must not // block. -func (c *Cache) AddHandler(handler func(*ateapipb.Worker)) { +func (c *Cache) AddHandler(handler func(*ateapi.Worker)) { c.mu.Lock() c.handlers = append(c.handlers, handler) - current := make([]*ateapipb.Worker, 0, len(c.workers)) + current := make([]*ateapi.Worker, 0, len(c.workers)) for _, w := range c.workers { current = append(current, w) } @@ -68,7 +68,7 @@ func (c *Cache) AddHandler(handler func(*ateapipb.Worker)) { } // notify calls handlers with each of workers. -func notify(handlers []func(*ateapipb.Worker), workers ...*ateapipb.Worker) { +func notify(handlers []func(*ateapi.Worker), workers ...*ateapi.Worker) { for _, h := range handlers { for _, w := range workers { h(w) @@ -83,7 +83,7 @@ func New(store workerListWatcher, relistInterval time.Duration) *Cache { return &Cache{ store: store, relistInterval: relistInterval, - workers: make(map[string]*ateapipb.Worker), + workers: make(map[string]*ateapi.Worker), } } @@ -91,7 +91,7 @@ func New(store workerListWatcher, relistInterval time.Duration) *Cache { // package and nothing more. type workerListWatcher interface { WatchWorkers(ctx context.Context) (*store.WorkerWatch, error) - ListWorkers(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapipb.Worker], error) + ListWorkers(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapi.Worker], error) } // Start syncs the cache synchronously, then spawns a background goroutine @@ -111,13 +111,13 @@ func (c *Cache) Start(ctx context.Context) error { // slice and its elements must not be modified by the caller. Returns an error // if the cache is not ready (brief window during reconnect); callers are // expected to retry. -func (c *Cache) Workers() ([]*ateapipb.Worker, error) { +func (c *Cache) Workers() ([]*ateapi.Worker, error) { if !c.ready.Load() { return nil, fmt.Errorf("worker cache not ready") } c.mu.RLock() defer c.mu.RUnlock() - out := make([]*ateapipb.Worker, 0, len(c.workers)) + out := make([]*ateapi.Worker, 0, len(c.workers)) for _, w := range c.workers { out = append(out, w) } @@ -125,7 +125,7 @@ func (c *Cache) Workers() ([]*ateapipb.Worker, error) { } // Worker returns the worker with the given name. -func (c *Cache) Worker(name string) (*ateapipb.Worker, error) { +func (c *Cache) Worker(name string) (*ateapi.Worker, error) { if !c.ready.Load() { return nil, fmt.Errorf("worker cache not ready") } @@ -150,7 +150,7 @@ func (c *Cache) Forget(name string) { // Observe applies a worker returned by a successful store write immediately, // without waiting for the corresponding watch event. -func (c *Cache) Observe(worker *ateapipb.Worker) { +func (c *Cache) Observe(worker *ateapi.Worker) { c.applyEvent(store.WorkerEvent{Type: store.WorkerEventUpdated, Worker: worker}) } @@ -167,7 +167,7 @@ func (c *Cache) sync(ctx context.Context) (*store.WorkerWatch, error) { } func (c *Cache) relist(ctx context.Context) error { - var workers []*ateapipb.Worker + var workers []*ateapi.Worker pageToken := "" for { page, err := c.store.ListWorkers(ctx, store.ListOptions{PageSize: relistPageSize, PageToken: pageToken}) @@ -180,12 +180,12 @@ func (c *Cache) relist(ctx context.Context) error { } pageToken = page.NextPageToken } - newMap := make(map[string]*ateapipb.Worker, len(workers)) + newMap := make(map[string]*ateapi.Worker, len(workers)) for _, w := range workers { newMap[workerKey(w)] = w } c.mu.Lock() - var changed []*ateapipb.Worker + var changed []*ateapi.Worker for key, w := range newMap { old, ok := c.workers[key] if !ok || old.GetMetadata().GetVersion() != w.GetMetadata().GetVersion() { @@ -256,7 +256,7 @@ func (c *Cache) resync(ctx context.Context) *store.WorkerWatch { func (c *Cache) applyEvent(event store.WorkerEvent) { key := workerKey(event.Worker) c.mu.Lock() - var handlers []func(*ateapipb.Worker) + var handlers []func(*ateapi.Worker) switch event.Type { case store.WorkerEventDeleted: delete(c.workers, key) @@ -271,6 +271,6 @@ func (c *Cache) applyEvent(event store.WorkerEvent) { notify(handlers, event.Worker) } -func workerKey(w *ateapipb.Worker) string { +func workerKey(w *ateapi.Worker) string { return w.GetMetadata().GetName() } diff --git a/cmd/ateapi/internal/workercache/workercache_test.go b/cmd/ateapi/internal/workercache/workercache_test.go index bc6d69ad2f..43a08eb7de 100644 --- a/cmd/ateapi/internal/workercache/workercache_test.go +++ b/cmd/ateapi/internal/workercache/workercache_test.go @@ -23,9 +23,9 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/workercache" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/testing/protocmp" "k8s.io/apimachinery/pkg/util/wait" ) @@ -56,7 +56,7 @@ func TestCache_SyncsOnStart(t *testing.T) { if err != nil { t.Fatalf("Workers: %v", err) } - if diff := cmp.Diff([]*ateapipb.Worker{w1, w2}, got, protocmp.Transform(), workerSortOpt); diff != "" { + if diff := cmp.Diff([]*ateapi.Worker{w1, w2}, got, protocmp.Transform(), workerSortOpt); diff != "" { t.Errorf("workers mismatch (-want +got):\n%s", diff) } } @@ -97,7 +97,7 @@ func TestCache_CreatedEvent(t *testing.T) { }, 2*time.Second) got, _ := c.Workers() - if diff := cmp.Diff([]*ateapipb.Worker{w}, got, protocmp.Transform(), workerSortOpt); diff != "" { + if diff := cmp.Diff([]*ateapi.Worker{w}, got, protocmp.Transform(), workerSortOpt); diff != "" { t.Errorf("workers mismatch (-want +got):\n%s", diff) } } @@ -113,7 +113,7 @@ func TestCache_UpdatedEvent_NewerVersionApplied(t *testing.T) { } updated := makeWorker("ns", "pod1", 2) - updated.Status.Allocated = &ateapipb.WorkerResources{Actors: 1} + updated.Status.Allocated = &ateapi.WorkerResources{Actors: 1} fs.send(store.WorkerEvent{Type: store.WorkerEventUpdated, Worker: updated}) eventually(t, func() bool { @@ -125,7 +125,7 @@ func TestCache_UpdatedEvent_NewerVersionApplied(t *testing.T) { }, 2*time.Second) got, _ := c.Workers() - if diff := cmp.Diff([]*ateapipb.Worker{updated}, got, protocmp.Transform(), workerSortOpt); diff != "" { + if diff := cmp.Diff([]*ateapi.Worker{updated}, got, protocmp.Transform(), workerSortOpt); diff != "" { t.Errorf("workers mismatch (-want +got):\n%s", diff) } } @@ -142,7 +142,7 @@ func TestCache_UpdatedEvent_OlderVersionIgnored(t *testing.T) { // Send a stale update followed by a sentinel we can detect. stale := makeWorker("ns", "pod1", 3) - stale.Status.Allocated = &ateapipb.WorkerResources{Actors: 7} + stale.Status.Allocated = &ateapi.WorkerResources{Actors: 7} fs.send(store.WorkerEvent{Type: store.WorkerEventUpdated, Worker: stale}) sentinel := makeWorker("ns", "pod2", 1) @@ -155,7 +155,7 @@ func TestCache_UpdatedEvent_OlderVersionIgnored(t *testing.T) { }, 2*time.Second) got, _ := c.Workers() - if diff := cmp.Diff([]*ateapipb.Worker{w, sentinel}, got, protocmp.Transform(), workerSortOpt); diff != "" { + if diff := cmp.Diff([]*ateapi.Worker{w, sentinel}, got, protocmp.Transform(), workerSortOpt); diff != "" { t.Errorf("workers mismatch (-want +got):\n%s", diff) } } @@ -173,7 +173,7 @@ func TestCache_DeletedEvent(t *testing.T) { // Delete events carry only the name. fs.send(store.WorkerEvent{ Type: store.WorkerEventDeleted, - Worker: &ateapipb.Worker{Metadata: &ateapipb.ResourceMetadata{Name: workerName("ns", "pod1")}}, + Worker: &ateapi.Worker{Metadata: &ateapi.ResourceMetadata{Name: workerName("ns", "pod1")}}, }) eventually(t, func() bool { @@ -204,7 +204,7 @@ func TestCache_Disconnect_ResyncsWithFreshSnapshot(t *testing.T) { }, 2*time.Second) got, _ := c.Workers() - if diff := cmp.Diff([]*ateapipb.Worker{w1, w2}, got, protocmp.Transform(), workerSortOpt); diff != "" { + if diff := cmp.Diff([]*ateapi.Worker{w1, w2}, got, protocmp.Transform(), workerSortOpt); diff != "" { t.Errorf("workers after resync (-want +got):\n%s", diff) } } @@ -313,7 +313,7 @@ func TestCache_Relist_RecoversFromMissedCreate(t *testing.T) { }, 2*time.Second) got, _ := c.Workers() - if diff := cmp.Diff([]*ateapipb.Worker{w1, w2}, got, protocmp.Transform(), workerSortOpt); diff != "" { + if diff := cmp.Diff([]*ateapi.Worker{w1, w2}, got, protocmp.Transform(), workerSortOpt); diff != "" { t.Errorf("workers after relist (-want +got):\n%s", diff) } } @@ -338,7 +338,7 @@ func TestCache_Relist_RecoversFromMissedDelete(t *testing.T) { }, 2*time.Second) got, _ := c.Workers() - if diff := cmp.Diff([]*ateapipb.Worker{w1}, got, protocmp.Transform(), workerSortOpt); diff != "" { + if diff := cmp.Diff([]*ateapi.Worker{w1}, got, protocmp.Transform(), workerSortOpt); diff != "" { t.Errorf("workers after relist (-want +got):\n%s", diff) } } @@ -369,7 +369,7 @@ func TestCache_Relist_FailureIsNonFatal(t *testing.T) { if err != nil { t.Fatalf("Workers: %v", err) } - if diff := cmp.Diff([]*ateapipb.Worker{w1}, workers, protocmp.Transform(), workerSortOpt); diff != "" { + if diff := cmp.Diff([]*ateapi.Worker{w1}, workers, protocmp.Transform(), workerSortOpt); diff != "" { t.Errorf("workers mismatch (-want +got):\n%s", diff) } } @@ -378,13 +378,13 @@ type fakeStore struct { store.Interface mu sync.Mutex - workers []*ateapipb.Worker + workers []*ateapi.Worker watchCh chan store.WorkerEvent listErr error // if set, ListWorkers returns it closes int // number of times a returned watch was Closed } -func newFakeStore(workers ...*ateapipb.Worker) *fakeStore { +func newFakeStore(workers ...*ateapi.Worker) *fakeStore { return &fakeStore{ workers: workers, watchCh: make(chan store.WorkerEvent, 16), @@ -401,15 +401,15 @@ func (f *fakeStore) WatchWorkers(_ context.Context) (*store.WorkerWatch, error) }), nil } -func (f *fakeStore) ListWorkers(_ context.Context, _ store.ListOptions) (store.ListResponse[*ateapipb.Worker], error) { +func (f *fakeStore) ListWorkers(_ context.Context, _ store.ListOptions) (store.ListResponse[*ateapi.Worker], error) { f.mu.Lock() defer f.mu.Unlock() if f.listErr != nil { - return store.ListResponse[*ateapipb.Worker]{}, f.listErr + return store.ListResponse[*ateapi.Worker]{}, f.listErr } - out := make([]*ateapipb.Worker, len(f.workers)) + out := make([]*ateapi.Worker, len(f.workers)) copy(out, f.workers) - return store.ListResponse[*ateapipb.Worker]{Items: out}, nil + return store.ListResponse[*ateapi.Worker]{Items: out}, nil } func (f *fakeStore) send(event store.WorkerEvent) { @@ -419,7 +419,7 @@ func (f *fakeStore) send(event store.WorkerEvent) { ch <- event } -func (f *fakeStore) setWorkers(workers ...*ateapipb.Worker) { +func (f *fakeStore) setWorkers(workers ...*ateapi.Worker) { f.mu.Lock() f.workers = workers f.mu.Unlock() @@ -439,21 +439,21 @@ func workerName(namespace, pod string) string { return "uid-" + namespace + "-" + pod } -func makeWorker(namespace, pod string, version int64) *ateapipb.Worker { - return &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{ +func makeWorker(namespace, pod string, version int64) *ateapi.Worker { + return &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{ Name: workerName(namespace, pod), Version: version, }, WorkerNamespace: namespace, WorkerPod: pod, WorkerPodUid: workerName(namespace, pod), - Status: &ateapipb.WorkerStatus{}, + Status: &ateapi.WorkerStatus{}, } } // workerSortOpt compares workers ignoring ordering. -var workerSortOpt = cmpopts.SortSlices(func(a, b *ateapipb.Worker) bool { +var workerSortOpt = cmpopts.SortSlices(func(a, b *ateapi.Worker) bool { if a.GetWorkerNamespace() != b.GetWorkerNamespace() { return a.GetWorkerNamespace() < b.GetWorkerNamespace() } @@ -482,7 +482,7 @@ func TestCache_WatchEventsAreFenced(t *testing.T) { } updated := makeWorker("ns", "pod1", 2) - updated.Status.Allocated = &ateapipb.WorkerResources{Actors: 1} + updated.Status.Allocated = &ateapi.WorkerResources{Actors: 1} fs.send(store.WorkerEvent{Type: store.WorkerEventUpdated, Worker: updated}) eventually(t, func() bool { w, err := c.Worker(workerName("ns", "pod1")) @@ -512,10 +512,10 @@ func TestCache_WatchEventsAreFenced(t *testing.T) { // handlerRecorder records the Workers a Cache handler is called with. type handlerRecorder struct { mu sync.Mutex - seen []*ateapipb.Worker + seen []*ateapi.Worker } -func (h *handlerRecorder) handle(w *ateapipb.Worker) { +func (h *handlerRecorder) handle(w *ateapi.Worker) { h.mu.Lock() defer h.mu.Unlock() h.seen = append(h.seen, w) diff --git a/cmd/ateapi/internal/workerservice/certificate.go b/cmd/ateapi/internal/workerservice/certificate.go index e0433346aa..c0592fcecb 100644 --- a/cmd/ateapi/internal/workerservice/certificate.go +++ b/cmd/ateapi/internal/workerservice/certificate.go @@ -24,18 +24,18 @@ import ( "path" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/ateletauth" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/substratex509" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // MintWorkerActorCertificate mints a Substrate-issued SPIFFE certificate that asserts // a worker acting on behalf of a particular actor. -func (s *Server) MintWorkerActorCertificate(ctx context.Context, req *ateapipb.MintWorkerActorCertificateRequest) (*ateapipb.MintWorkerActorCertificateResponse, error) { +func (s *Server) MintWorkerActorCertificate(ctx context.Context, req *ateapi.MintWorkerActorCertificateRequest) (*ateapi.MintWorkerActorCertificateResponse, error) { if errs := apivalidation.ValidateMintWorkerActorCertificateRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -123,7 +123,7 @@ func (s *Server) MintWorkerActorCertificate(ctx context.Context, req *ateapipb.M return nil, fmt.Errorf("while signing certificate: %w", err) } - return &ateapipb.MintWorkerActorCertificateResponse{ + return &ateapi.MintWorkerActorCertificateResponse{ ActorCertificates: chain, }, nil } diff --git a/cmd/ateapi/internal/workerservice/certificate_test.go b/cmd/ateapi/internal/workerservice/certificate_test.go index a112c964ae..8ef41ecd51 100644 --- a/cmd/ateapi/internal/workerservice/certificate_test.go +++ b/cmd/ateapi/internal/workerservice/certificate_test.go @@ -25,37 +25,37 @@ import ( "time" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/ateletauth/ateletauthtest" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/localca" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/substratex509" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" ) type fakeActorStore struct { store.Interface - actors map[resources.ActorRef]*ateapipb.Actor - workers map[string]*ateapipb.Worker + actors map[resources.ActorRef]*ateapi.Actor + workers map[string]*ateapi.Worker // assignments maps an actor UID to the worker holding its assignment. assignments map[string]string // assignmentErr, when set, fails every GetWorkerAssignment. assignmentErr error } -func (f *fakeActorStore) GetWorkerAssignment(_ context.Context, workerName, actorUID string) (*ateapipb.ActorAssignment, error) { +func (f *fakeActorStore) GetWorkerAssignment(_ context.Context, workerName, actorUID string) (*ateapi.ActorAssignment, error) { if f.assignmentErr != nil { return nil, f.assignmentErr } if holder, ok := f.assignments[actorUID]; !ok || holder != workerName { return nil, store.ErrNotFound } - return &ateapipb.ActorAssignment{ActorUid: actorUID}, nil + return &ateapi.ActorAssignment{ActorUid: actorUID}, nil } -func (f *fakeActorStore) GetWorker(_ context.Context, name string) (*ateapipb.Worker, error) { +func (f *fakeActorStore) GetWorker(_ context.Context, name string) (*ateapi.Worker, error) { w, ok := f.workers[name] if !ok { return nil, store.ErrNotFound @@ -63,7 +63,7 @@ func (f *fakeActorStore) GetWorker(_ context.Context, name string) (*ateapipb.Wo return w, nil } -func (f *fakeActorStore) GetActor(_ context.Context, actorRef resources.ActorRef) (*ateapipb.Actor, error) { +func (f *fakeActorStore) GetActor(_ context.Context, actorRef resources.ActorRef) (*ateapi.Actor, error) { a, ok := f.actors[actorRef] if !ok { return nil, store.ErrNotFound @@ -71,29 +71,29 @@ func (f *fakeActorStore) GetActor(_ context.Context, actorRef resources.ActorRef return a, nil } -func newFakeStoreWithActor(atespace, name, uid string) (*fakeActorStore, *ateapipb.Actor) { - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ +func newFakeStoreWithActor(atespace, name, uid string) (*fakeActorStore, *ateapi.Actor) { + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: atespace, Name: name, Uid: uid, }, - ActorTemplate: &ateapipb.ObjectRef{ + ActorTemplate: &ateapi.ObjectRef{ Atespace: atespace, Name: "template-1", }, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{Worker: &ateapipb.ObjectRef{Name: "worker-1"}}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{Worker: &ateapi.ObjectRef{Name: "worker-1"}}, }, } return &fakeActorStore{ - actors: map[resources.ActorRef]*ateapipb.Actor{ + actors: map[resources.ActorRef]*ateapi.Actor{ {Atespace: atespace, Name: name}: actor, }, // worker-1 runs on node-1, the node the tests' atelet certificate names. - workers: map[string]*ateapipb.Worker{ - "worker-1": {Metadata: &ateapipb.ResourceMetadata{Name: "worker-1"}, NodeName: "node-1"}, + workers: map[string]*ateapi.Worker{ + "worker-1": {Metadata: &ateapi.ResourceMetadata{Name: "worker-1"}, NodeName: "node-1"}, }, assignments: map[string]string{uid: "worker-1"}, }, actor @@ -132,14 +132,14 @@ func TestMintWorkerActorCertificate(t *testing.T) { csr, key := generateTestCSR(t) ctx := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, "node-1")) - resp, err := s.MintWorkerActorCertificate(ctx, &ateapipb.MintWorkerActorCertificateRequest{ - Actor: &ateapipb.ObjectRef{ + resp, err := s.MintWorkerActorCertificate(ctx, &ateapi.MintWorkerActorCertificateRequest{ + Actor: &ateapi.ObjectRef{ Atespace: "team-a", Name: "my-actor", }, ActorUid: actor.GetMetadata().GetUid(), CertificateSigningRequest: csr, - Worker: &ateapipb.ObjectRef{Name: "worker-1"}, + Worker: &ateapi.ObjectRef{Name: "worker-1"}, }) if err != nil { t.Fatalf("MintWorkerActorCertificate() failed: %v", err) @@ -186,12 +186,12 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { authed := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, "node-1")) otherNode := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, "node-2")) - valid := func() *ateapipb.MintWorkerActorCertificateRequest { - return &ateapipb.MintWorkerActorCertificateRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "my-actor"}, + valid := func() *ateapi.MintWorkerActorCertificateRequest { + return &ateapi.MintWorkerActorCertificateRequest{ + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "my-actor"}, ActorUid: actor.GetMetadata().GetUid(), CertificateSigningRequest: csr, - Worker: &ateapipb.ObjectRef{Name: "worker-1"}, + Worker: &ateapi.ObjectRef{Name: "worker-1"}, } } const ( @@ -199,16 +199,16 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { otherActorUID = "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d" ) // onWorker is an actor status naming worker-1, which runs on node-1. - onWorker := func(state ateapipb.ActorState) *ateapipb.ActorStatus { - return &ateapipb.ActorStatus{State: state, WorkerAssignment: &ateapipb.WorkerAssignment{Worker: &ateapipb.ObjectRef{Name: "worker-1"}}} + onWorker := func(state ateapi.ActorState) *ateapi.ActorStatus { + return &ateapi.ActorStatus{State: state, WorkerAssignment: &ateapi.WorkerAssignment{Worker: &ateapi.ObjectRef{Name: "worker-1"}}} } // pausingOnWorker is an async suspend in progress: SUSPENDING on worker-1 // with a latest snapshot that is not yet captured. - pausingOnWorker := func() *ateapipb.ActorStatus { - status := onWorker(ateapipb.ActorState_ACTOR_STATE_SUSPENDING) + pausingOnWorker := func() *ateapi.ActorStatus { + status := onWorker(ateapi.ActorState_ACTOR_STATE_SUSPENDING) status.AssignedNode = "node-1" status.LastAssignedGeneration = 1 - status.Snapshots = []*ateapipb.Snapshot{{Uuid: "snap-1", Generation: 1, Owner: ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR}} + status.Snapshots = []*ateapi.Snapshot{{Uuid: "snap-1", Generation: 1, Owner: ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR}} return status } released := map[string]string{} @@ -216,9 +216,9 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { tests := []struct { name string ctx context.Context - mutate func(*ateapipb.MintWorkerActorCertificateRequest) + mutate func(*ateapi.MintWorkerActorCertificateRequest) // status, when set, replaces the actor's status for the case. - status *ateapipb.ActorStatus + status *ateapi.ActorStatus // assignments, when set, replaces the store's worker assignments // (actor UID to worker) for the case. By default worker-1 holds the // actor. @@ -231,20 +231,20 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { { name: "running actor on its worker's node", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RUNNING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RUNNING), want: codes.OK, }, { // atunnel mints while the actor resumes, before it runs. name: "resuming actor on its worker's node", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RESUMING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RESUMING), want: codes.OK, }, { name: "running actor being suspended on its worker's node", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_SUSPENDING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_SUSPENDING), want: codes.OK, }, { @@ -258,7 +258,7 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { // actor's status, which keeps naming the worker until they do. name: "running actor whose worker was released", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RUNNING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RUNNING), assignments: released, want: codes.NotFound, }, @@ -267,14 +267,14 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { // crashes the actor. name: "resuming actor whose worker was released", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RESUMING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RESUMING), assignments: released, want: codes.NotFound, }, { name: "suspending actor whose worker was released", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_SUSPENDING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_SUSPENDING), assignments: released, want: codes.NotFound, }, @@ -290,21 +290,21 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { // not this one. name: "running actor whose worker was rebooked for another actor", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RUNNING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RUNNING), assignments: rebooked, want: codes.NotFound, }, { name: "resuming actor whose worker was rebooked for another actor", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RESUMING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RESUMING), assignments: rebooked, want: codes.NotFound, }, { name: "suspending actor whose worker was rebooked for another actor", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_SUSPENDING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_SUSPENDING), assignments: rebooked, want: codes.NotFound, }, @@ -320,7 +320,7 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { // names, so the status's worker does not host it. name: "actor held by a worker other than the one its status names", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RUNNING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RUNNING), assignments: map[string]string{actor.GetMetadata().GetUid(): "worker-2"}, want: codes.NotFound, }, @@ -328,7 +328,7 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { // A failed lookup refuses the mint rather than trusting the status. name: "worker assignment lookup fails", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RUNNING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RUNNING), assignmentErr: errors.New("connection reset"), want: codes.Internal, }, @@ -343,21 +343,21 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { // check answering Aborted: the node check runs first. name: "actor hosted on another node, stale uid", ctx: otherNode, - mutate: func(r *ateapipb.MintWorkerActorCertificateRequest) { r.ActorUid = staleUID }, + mutate: func(r *ateapi.MintWorkerActorCertificateRequest) { r.ActorUid = staleUID }, want: codes.NotFound, }, { // worker-2 runs on the actor's node, but the actor is not its own. name: "another worker on the actor's node", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorCertificateRequest) { r.Worker.Name = "worker-2" }, + mutate: func(r *ateapi.MintWorkerActorCertificateRequest) { r.Worker.Name = "worker-2" }, want: codes.NotFound, }, { // The worker check also runs before the UID check. name: "another worker on the actor's node, stale uid", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorCertificateRequest) { + mutate: func(r *ateapi.MintWorkerActorCertificateRequest) { r.Worker.Name = "worker-2" r.ActorUid = staleUID }, @@ -368,7 +368,7 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { // worker runs a SUSPENDED actor, so no worker gets its certificate. name: "paused actor on this node", ctx: authed, - status: pausedStatus(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), + status: pausedStatus(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), assignments: released, want: codes.NotFound, }, @@ -387,14 +387,14 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { // reading the store, so only the status comparison refuses. name: "paused actor bound to a worker on this node before its status names the worker", ctx: authed, - status: pausedStatus(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), + status: pausedStatus(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), assignments: map[string]string{actor.GetMetadata().GetUid(): "worker-1"}, want: codes.NotFound, }, { name: "paused actor on another node", ctx: authed, - status: pausedStatus(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-2"), + status: pausedStatus(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-2"), assignments: released, want: codes.NotFound, }, @@ -403,9 +403,9 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { // assignment. name: "paused actor, empty worker name", ctx: authed, - status: pausedStatus(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), + status: pausedStatus(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), assignments: released, - mutate: func(r *ateapipb.MintWorkerActorCertificateRequest) { r.Worker.Name = "" }, + mutate: func(r *ateapi.MintWorkerActorCertificateRequest) { r.Worker.Name = "" }, want: codes.InvalidArgument, }, { @@ -413,7 +413,7 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { // node. Nothing is hosted there, so nothing may be minted. name: "crashed actor on its last node", ctx: authed, - status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_CRASHED, AssignedNode: "node-1"}, + status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_CRASHED, AssignedNode: "node-1"}, want: codes.NotFound, }, { @@ -421,13 +421,13 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { // finalizes. The node no longer runs the actor. name: "reverting actor with a stale assignment", ctx: authed, - status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_REVERTING, WorkerAssignment: &ateapipb.WorkerAssignment{Worker: &ateapipb.ObjectRef{Name: "worker-1"}}}, + status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_REVERTING, WorkerAssignment: &ateapi.WorkerAssignment{Worker: &ateapi.ObjectRef{Name: "worker-1"}}}, want: codes.NotFound, }, { name: "actor hosted by no node", ctx: authed, - status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, want: codes.NotFound, }, { @@ -435,7 +435,7 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { // is gone. name: "actor assigned to a worker the store has lost", ctx: authed, - status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapipb.WorkerAssignment{Worker: &ateapipb.ObjectRef{Name: "worker-gone"}}}, + status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapi.WorkerAssignment{Worker: &ateapi.ObjectRef{Name: "worker-gone"}}}, assignments: map[string]string{actor.GetMetadata().GetUid(): "worker-gone"}, want: codes.NotFound, }, @@ -447,37 +447,37 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { { name: "missing actor", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorCertificateRequest) { r.Actor = nil }, + mutate: func(r *ateapi.MintWorkerActorCertificateRequest) { r.Actor = nil }, want: codes.InvalidArgument, }, { name: "missing actor uid", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorCertificateRequest) { r.ActorUid = "" }, + mutate: func(r *ateapi.MintWorkerActorCertificateRequest) { r.ActorUid = "" }, want: codes.InvalidArgument, }, { name: "missing csr", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorCertificateRequest) { r.CertificateSigningRequest = nil }, + mutate: func(r *ateapi.MintWorkerActorCertificateRequest) { r.CertificateSigningRequest = nil }, want: codes.InvalidArgument, }, { name: "missing worker", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorCertificateRequest) { r.Worker = nil }, + mutate: func(r *ateapi.MintWorkerActorCertificateRequest) { r.Worker = nil }, want: codes.InvalidArgument, }, { name: "worker with an atespace", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorCertificateRequest) { r.Worker.Atespace = "team-a" }, + mutate: func(r *ateapi.MintWorkerActorCertificateRequest) { r.Worker.Atespace = "team-a" }, want: codes.InvalidArgument, }, { name: "actor not found", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorCertificateRequest) { r.Actor.Name = "nonexistent" }, + mutate: func(r *ateapi.MintWorkerActorCertificateRequest) { r.Actor.Name = "nonexistent" }, want: codes.NotFound, }, { @@ -485,7 +485,7 @@ func TestMintWorkerActorCertificate_Errors(t *testing.T) { // recreated. name: "stale actor uid", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorCertificateRequest) { r.ActorUid = staleUID }, + mutate: func(r *ateapi.MintWorkerActorCertificateRequest) { r.ActorUid = staleUID }, want: codes.Aborted, }, } diff --git a/cmd/ateapi/internal/workerservice/crash.go b/cmd/ateapi/internal/workerservice/crash.go index da4e0cfb59..0dae4d1142 100644 --- a/cmd/ateapi/internal/workerservice/crash.go +++ b/cmd/ateapi/internal/workerservice/crash.go @@ -18,16 +18,16 @@ import ( "context" "log/slog" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/ateletauth" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // ReportActorCrashed crashes a RUNNING Actor whose sandbox died, on behalf of // the Worker hosting it. The caller must be an atelet running on the Worker's // node. -func (s *Server) ReportActorCrashed(ctx context.Context, req *ateapipb.ReportActorCrashedRequest) (*ateapipb.ReportActorCrashedResponse, error) { +func (s *Server) ReportActorCrashed(ctx context.Context, req *ateapi.ReportActorCrashedRequest) (*ateapi.ReportActorCrashedResponse, error) { caller, err := ateletauth.Authenticate(ctx, s.ateletSPIFFEID) if err != nil { return nil, err @@ -51,5 +51,5 @@ func (s *Server) ReportActorCrashed(ctx context.Context, req *ateapipb.ReportAct slog.String("actor_uid", req.GetActorUid()), slog.String("node", caller.NodeName), slog.String("message", req.GetMessage())) - return &ateapipb.ReportActorCrashedResponse{Actor: actor}, nil + return &ateapi.ReportActorCrashedResponse{Actor: actor}, nil } diff --git a/cmd/ateapi/internal/workerservice/crash_test.go b/cmd/ateapi/internal/workerservice/crash_test.go index f279a2780a..84f90afaee 100644 --- a/cmd/ateapi/internal/workerservice/crash_test.go +++ b/cmd/ateapi/internal/workerservice/crash_test.go @@ -22,17 +22,17 @@ import ( "github.com/google/go-cmp/cmp" "google.golang.org/grpc/codes" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/ateletauth/ateletauthtest" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) -func crashRequest(actorUID string) *ateapipb.ReportActorCrashedRequest { - return &ateapipb.ReportActorCrashedRequest{ - Worker: &ateapipb.ObjectRef{Name: testWorkerName}, - Actor: &ateapipb.ObjectRef{Atespace: suspendAtespace, Name: suspendActor}, +func crashRequest(actorUID string) *ateapi.ReportActorCrashedRequest { + return &ateapi.ReportActorCrashedRequest{ + Worker: &ateapi.ObjectRef{Name: testWorkerName}, + Actor: &ateapi.ObjectRef{Atespace: suspendAtespace, Name: suspendActor}, ActorUid: actorUID, Message: "cloud-hypervisor exited: signal: killed", } @@ -41,7 +41,7 @@ func crashRequest(actorUID string) *ateapipb.ReportActorCrashedRequest { func TestReportActorCrashed(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() - seedReportedWorker(t, st, testNode, &ateapipb.WorkerResources{Actors: 1}) + seedReportedWorker(t, st, testNode, &ateapi.WorkerResources{Actors: 1}) actor := seedHostedActor(t, st, testWorkerName) uid := actor.GetMetadata().GetUid() control := &fakeControl{crashResp: actor} @@ -64,7 +64,7 @@ func TestReportActorCrashed(t *testing.T) { func TestReportActorCrashed_Refused(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() - seedReportedWorker(t, st, testNode, &ateapipb.WorkerResources{Actors: 1}) + seedReportedWorker(t, st, testNode, &ateapi.WorkerResources{Actors: 1}) actor := seedHostedActor(t, st, testWorkerName) uid := actor.GetMetadata().GetUid() authed := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, testNode)) @@ -77,7 +77,7 @@ func TestReportActorCrashed_Refused(t *testing.T) { tests := []struct { name string ctx context.Context - req *ateapipb.ReportActorCrashedRequest + req *ateapi.ReportActorCrashedRequest want codes.Code }{ {"unauthenticated", ateletauthtest.ContextWith(nil), crashRequest(uid), codes.Unauthenticated}, diff --git a/cmd/ateapi/internal/workerservice/jwt.go b/cmd/ateapi/internal/workerservice/jwt.go index ca678eddeb..459041bf07 100644 --- a/cmd/ateapi/internal/workerservice/jwt.go +++ b/cmd/ateapi/internal/workerservice/jwt.go @@ -22,6 +22,7 @@ import ( "log/slog" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/ateletauth" "go.ate.dev/substrate/cmd/ateapi/internal/controlapi" @@ -29,7 +30,6 @@ import ( "go.ate.dev/substrate/internal/actoridjwt" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -38,7 +38,7 @@ import ( // plugins that exchange it for short-lived credentials. const workerActorJWTLifetime = time.Hour -func (s *Server) MintWorkerActorJwt(ctx context.Context, req *ateapipb.MintWorkerActorJwtRequest) (*ateapipb.MintWorkerActorJwtResponse, error) { +func (s *Server) MintWorkerActorJwt(ctx context.Context, req *ateapi.MintWorkerActorJwtRequest) (*ateapi.MintWorkerActorJwtResponse, error) { if errs := apivalidation.ValidateMintWorkerActorJwtRequest(ctx, req); len(errs) > 0 { return nil, resources.ToAPIError(errs) } @@ -93,7 +93,7 @@ func (s *Server) MintWorkerActorJwt(ctx context.Context, req *ateapipb.MintWorke if err != nil { return nil, fmt.Errorf("while signing worker-for-actor JWT: %w", err) } - return &ateapipb.MintWorkerActorJwtResponse{ + return &ateapi.MintWorkerActorJwtResponse{ ActorJwt: token, ExpireTime: timestamppb.New(expiresAt), }, nil @@ -103,7 +103,7 @@ func (s *Server) MintWorkerActorJwt(ctx context.Context, req *ateapipb.MintWorke // actor, as RequestActorSuspend does. Authoritative state decides, never the // request. The refusal is NotFound, so a node learns nothing about actors it // does not host. credential names what the caller mints, for the refusal log. -func (s *Server) checkActorOnNode(ctx context.Context, actor *ateapipb.Actor, callerNode, credential string) error { +func (s *Server) checkActorOnNode(ctx context.Context, actor *ateapi.Actor, callerNode, credential string) error { hostingNode, err := controlapi.HostingNode(ctx, s.store, actor) if err != nil { return err diff --git a/cmd/ateapi/internal/workerservice/jwt_test.go b/cmd/ateapi/internal/workerservice/jwt_test.go index 40ea33db01..355594142a 100644 --- a/cmd/ateapi/internal/workerservice/jwt_test.go +++ b/cmd/ateapi/internal/workerservice/jwt_test.go @@ -25,11 +25,11 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/ateletauth/ateletauthtest" "go.ate.dev/substrate/internal/actoridjwt" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/localjwtauthority" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" ) @@ -69,8 +69,8 @@ func TestMintWorkerActorJwt(t *testing.T) { ctx := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, "node-1")) before := time.Now().Truncate(time.Second) - resp, err := s.MintWorkerActorJwt(ctx, &ateapipb.MintWorkerActorJwtRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "my-actor"}, + resp, err := s.MintWorkerActorJwt(ctx, &ateapi.MintWorkerActorJwtRequest{ + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "my-actor"}, ActorUid: actor.GetMetadata().GetUid(), Audiences: []string{"snapshot-plugin"}, }) @@ -117,23 +117,23 @@ func TestMintWorkerActorJwt(t *testing.T) { // worker, assigned_node on the node holding its local snapshot, and a latest // generation that is local-only. The latest generation is the one // last_assigned_generation names. -func pausedStatus(state ateapipb.ActorState, node string) *ateapipb.ActorStatus { - return &ateapipb.ActorStatus{ +func pausedStatus(state ateapi.ActorState, node string) *ateapi.ActorStatus { + return &ateapi.ActorStatus{ State: state, AssignedNode: node, LastAssignedGeneration: 1, - Snapshots: []*ateapipb.Snapshot{{Uuid: "snap-1", Generation: 1, Owner: ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, Locality: node}}, + Snapshots: []*ateapi.Snapshot{{Uuid: "snap-1", Generation: 1, Owner: ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, Locality: node}}, } } // uploadPendingStatus is how an asynchronously suspended actor looks until // atelet's background upload of its local snapshot is recorded: SUSPENDED, no // worker, and the latest generation's durable copy PENDING. -func uploadPendingStatus(node string) *ateapipb.ActorStatus { - status := pausedStatus(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, node) - status.Snapshots[0].DurableSnapshot = &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: "gs://snaps/root/atespaces/team-a/actors/uid/snap-1"}, +func uploadPendingStatus(node string) *ateapi.ActorStatus { + status := pausedStatus(ateapi.ActorState_ACTOR_STATE_SUSPENDED, node) + status.Snapshots[0].DurableSnapshot = &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING, + Object: &ateapi.ObjectSnapshot{SnapshotUri: "gs://snaps/root/atespaces/team-a/actors/uid/snap-1"}, } return status } @@ -143,25 +143,25 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { s := New(st, &fakeControl{}, testAteletSPIFFEID, nil, testActorJWTIssuer, newTestJWTPool(t)) authed := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, "node-1")) - valid := func() *ateapipb.MintWorkerActorJwtRequest { - return &ateapipb.MintWorkerActorJwtRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "my-actor"}, + valid := func() *ateapi.MintWorkerActorJwtRequest { + return &ateapi.MintWorkerActorJwtRequest{ + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "my-actor"}, ActorUid: actor.GetMetadata().GetUid(), Audiences: []string{"snapshot-plugin"}, } } const otherActorUID = "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d" // onWorker is an actor status naming worker-1, which runs on node-1. - onWorker := func(state ateapipb.ActorState) *ateapipb.ActorStatus { - return &ateapipb.ActorStatus{State: state, WorkerAssignment: &ateapipb.WorkerAssignment{Worker: &ateapipb.ObjectRef{Name: "worker-1"}}} + onWorker := func(state ateapi.ActorState) *ateapi.ActorStatus { + return &ateapi.ActorStatus{State: state, WorkerAssignment: &ateapi.WorkerAssignment{Worker: &ateapi.ObjectRef{Name: "worker-1"}}} } // pausingOnWorker is an async suspend in progress: SUSPENDING on worker-1 // with a latest snapshot that is not yet captured. - pausingOnWorker := func() *ateapipb.ActorStatus { - status := onWorker(ateapipb.ActorState_ACTOR_STATE_SUSPENDING) + pausingOnWorker := func() *ateapi.ActorStatus { + status := onWorker(ateapi.ActorState_ACTOR_STATE_SUSPENDING) status.AssignedNode = "node-1" status.LastAssignedGeneration = 1 - status.Snapshots = []*ateapipb.Snapshot{{Uuid: "snap-1", Generation: 1, Owner: ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR}} + status.Snapshots = []*ateapi.Snapshot{{Uuid: "snap-1", Generation: 1, Owner: ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR}} return status } released := map[string]string{} @@ -169,9 +169,9 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { tests := []struct { name string ctx context.Context - mutate func(*ateapipb.MintWorkerActorJwtRequest) + mutate func(*ateapi.MintWorkerActorJwtRequest) // status, when set, replaces the actor's status for the case. - status *ateapipb.ActorStatus + status *ateapi.ActorStatus // assignments, when set, replaces the store's worker assignments // (actor UID to worker) for the case. By default worker-1 holds the // actor. @@ -184,20 +184,20 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { { name: "running actor on its worker's node", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RUNNING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RUNNING), want: codes.OK, }, { name: "resuming actor on its worker's node", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RESUMING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RESUMING), want: codes.OK, }, { // Suspending a running actor uploads its checkpoint from its worker. name: "running actor being suspended on its worker's node", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_SUSPENDING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_SUSPENDING), want: codes.OK, }, { @@ -211,7 +211,7 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { // actor's status, which keeps naming the worker until they do. name: "running actor whose worker was released", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RUNNING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RUNNING), assignments: released, want: codes.NotFound, }, @@ -220,14 +220,14 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { // crashes the actor. name: "resuming actor whose worker was released", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RESUMING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RESUMING), assignments: released, want: codes.NotFound, }, { name: "suspending actor whose worker was released", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_SUSPENDING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_SUSPENDING), assignments: released, want: codes.NotFound, }, @@ -243,21 +243,21 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { // not this one. name: "running actor whose worker was rebooked for another actor", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RUNNING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RUNNING), assignments: rebooked, want: codes.NotFound, }, { name: "resuming actor whose worker was rebooked for another actor", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RESUMING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RESUMING), assignments: rebooked, want: codes.NotFound, }, { name: "suspending actor whose worker was rebooked for another actor", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_SUSPENDING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_SUSPENDING), assignments: rebooked, want: codes.NotFound, }, @@ -273,7 +273,7 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { // names, so the status's worker does not host it. name: "actor held by a worker other than the one its status names", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RUNNING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RUNNING), assignments: map[string]string{actor.GetMetadata().GetUid(): "worker-2"}, want: codes.NotFound, }, @@ -281,7 +281,7 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { // A failed lookup refuses the mint rather than trusting the status. name: "worker assignment lookup fails", ctx: authed, - status: onWorker(ateapipb.ActorState_ACTOR_STATE_RUNNING), + status: onWorker(ateapi.ActorState_ACTOR_STATE_RUNNING), assignmentErr: errors.New("connection reset"), want: codes.Internal, }, @@ -293,25 +293,25 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { { name: "missing actor", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorJwtRequest) { r.Actor = nil }, + mutate: func(r *ateapi.MintWorkerActorJwtRequest) { r.Actor = nil }, want: codes.InvalidArgument, }, { name: "missing actor uid", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorJwtRequest) { r.ActorUid = "" }, + mutate: func(r *ateapi.MintWorkerActorJwtRequest) { r.ActorUid = "" }, want: codes.InvalidArgument, }, { name: "missing audiences", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorJwtRequest) { r.Audiences = nil }, + mutate: func(r *ateapi.MintWorkerActorJwtRequest) { r.Audiences = nil }, want: codes.InvalidArgument, }, { name: "empty audience", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorJwtRequest) { r.Audiences = []string{""} }, + mutate: func(r *ateapi.MintWorkerActorJwtRequest) { r.Audiences = []string{""} }, want: codes.InvalidArgument, }, { @@ -325,19 +325,19 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { // check answering Aborted: the node check runs first. name: "actor hosted on another node, stale uid", ctx: ateletauthtest.ContextWith(ateletauthtest.CertOn(t, "node-2")), - mutate: func(r *ateapipb.MintWorkerActorJwtRequest) { r.ActorUid = "7d1c0b2a-9e4f-4c3d-8a6b-5f2e1d0c9b8a" }, + mutate: func(r *ateapi.MintWorkerActorJwtRequest) { r.ActorUid = "7d1c0b2a-9e4f-4c3d-8a6b-5f2e1d0c9b8a" }, want: codes.NotFound, }, { name: "paused actor on this node", ctx: authed, - status: pausedStatus(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), + status: pausedStatus(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), want: codes.OK, }, { name: "paused actor on another node", ctx: authed, - status: pausedStatus(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-2"), + status: pausedStatus(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-2"), want: codes.NotFound, }, { @@ -359,9 +359,9 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { // clears the locality, so it still acts for the actor. name: "paused actor whose snapshot is uploaded, local copy kept", ctx: authed, - status: func() *ateapipb.ActorStatus { + status: func() *ateapi.ActorStatus { status := uploadPendingStatus("node-1") - status.Snapshots[0].DurableSnapshot.Status = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + status.Snapshots[0].DurableSnapshot.Status = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED return status }(), want: codes.OK, @@ -370,9 +370,9 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { // Only a SUSPENDED actor is hosted by a node with no worker. name: "suspending actor with no worker", ctx: authed, - status: func() *ateapipb.ActorStatus { + status: func() *ateapi.ActorStatus { status := uploadPendingStatus("node-1") - status.State = ateapipb.ActorState_ACTOR_STATE_SUSPENDING + status.State = ateapi.ActorState_ACTOR_STATE_SUSPENDING return status }(), want: codes.NotFound, @@ -382,7 +382,7 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { // node. Nothing is hosted there, so nothing may be minted. name: "crashed actor on its last node", ctx: authed, - status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_CRASHED, AssignedNode: "node-1"}, + status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_CRASHED, AssignedNode: "node-1"}, want: codes.NotFound, }, { @@ -390,26 +390,26 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { // finalizes. The node no longer runs the actor. name: "reverting actor with a stale assignment", ctx: authed, - status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_REVERTING, WorkerAssignment: &ateapipb.WorkerAssignment{Worker: &ateapipb.ObjectRef{Name: "worker-1"}}}, + status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_REVERTING, WorkerAssignment: &ateapi.WorkerAssignment{Worker: &ateapi.ObjectRef{Name: "worker-1"}}}, want: codes.NotFound, }, { // A suspended actor is hosted nowhere, so no node may mint for it. name: "actor hosted by no node", ctx: authed, - status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, want: codes.NotFound, }, { name: "actor assigned to a worker the store has lost", ctx: authed, - status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapipb.WorkerAssignment{Worker: &ateapipb.ObjectRef{Name: "worker-gone"}}}, + status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapi.WorkerAssignment{Worker: &ateapi.ObjectRef{Name: "worker-gone"}}}, want: codes.NotFound, }, { name: "actor not found", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorJwtRequest) { r.Actor.Name = "nonexistent" }, + mutate: func(r *ateapi.MintWorkerActorJwtRequest) { r.Actor.Name = "nonexistent" }, want: codes.NotFound, }, { @@ -417,7 +417,7 @@ func TestMintWorkerActorJwt_Errors(t *testing.T) { // for the old incarnation. Aborted, as MintWorkerActorCertificate answers. name: "stale actor uid", ctx: authed, - mutate: func(r *ateapipb.MintWorkerActorJwtRequest) { r.ActorUid = "7d1c0b2a-9e4f-4c3d-8a6b-5f2e1d0c9b8a" }, + mutate: func(r *ateapi.MintWorkerActorJwtRequest) { r.ActorUid = "7d1c0b2a-9e4f-4c3d-8a6b-5f2e1d0c9b8a" }, want: codes.Aborted, }, } @@ -459,7 +459,7 @@ func TestNodeRefusalLogNamesCredential(t *testing.T) { s := New(st, &fakeControl{}, testAteletSPIFFEID, newTestCAPool(t), testActorJWTIssuer, newTestJWTPool(t)) // The actor's worker runs on node-1. otherNode := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, "node-2")) - actorRef := &ateapipb.ObjectRef{Atespace: "team-a", Name: "my-actor"} + actorRef := &ateapi.ObjectRef{Atespace: "team-a", Name: "my-actor"} tests := []struct { name string @@ -469,7 +469,7 @@ func TestNodeRefusalLogNamesCredential(t *testing.T) { { name: "MintWorkerActorJwt", mint: func() error { - _, err := s.MintWorkerActorJwt(otherNode, &ateapipb.MintWorkerActorJwtRequest{ + _, err := s.MintWorkerActorJwt(otherNode, &ateapi.MintWorkerActorJwtRequest{ Actor: actorRef, ActorUid: actor.GetMetadata().GetUid(), Audiences: []string{"snapshot-plugin"}, @@ -481,11 +481,11 @@ func TestNodeRefusalLogNamesCredential(t *testing.T) { { name: "MintWorkerActorCertificate", mint: func() error { - _, err := s.MintWorkerActorCertificate(otherNode, &ateapipb.MintWorkerActorCertificateRequest{ + _, err := s.MintWorkerActorCertificate(otherNode, &ateapi.MintWorkerActorCertificateRequest{ Actor: actorRef, ActorUid: actor.GetMetadata().GetUid(), CertificateSigningRequest: csr, - Worker: &ateapipb.ObjectRef{Name: "worker-1"}, + Worker: &ateapi.ObjectRef{Name: "worker-1"}, }) return err }, diff --git a/cmd/ateapi/internal/workerservice/register.go b/cmd/ateapi/internal/workerservice/register.go index fd58852eeb..7fa2b25e3c 100644 --- a/cmd/ateapi/internal/workerservice/register.go +++ b/cmd/ateapi/internal/workerservice/register.go @@ -22,19 +22,19 @@ import ( "log/slog" "slices" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/ateletauth" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/hardware" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/proto" ) // AcquireWorkerEpoch hands out the next epoch of a Worker. As with MintCert, // the caller must be an atelet running on the Worker's node. -func (s *Server) AcquireWorkerEpoch(ctx context.Context, req *ateapipb.AcquireWorkerEpochRequest) (*ateapipb.AcquireWorkerEpochResponse, error) { +func (s *Server) AcquireWorkerEpoch(ctx context.Context, req *ateapi.AcquireWorkerEpochRequest) (*ateapi.AcquireWorkerEpochResponse, error) { caller, err := ateletauth.Authenticate(ctx, s.ateletSPIFFEID) if err != nil { return nil, err @@ -48,7 +48,7 @@ func (s *Server) AcquireWorkerEpoch(ctx context.Context, req *ateapipb.AcquireWo return nil, err } - updated, err := s.store.UpdateWorker(ctx, name, store.PreconditionFrom(worker), func(toUpdate *ateapipb.Worker) error { + updated, err := s.store.UpdateWorker(ctx, name, store.PreconditionFrom(worker), func(toUpdate *ateapi.Worker) error { toUpdate.Status.IssuedEpoch++ return nil }) @@ -60,13 +60,13 @@ func (s *Server) AcquireWorkerEpoch(ctx context.Context, req *ateapipb.AcquireWo slog.String("worker", name), slog.Int64("epoch", epoch), slog.Int64("registered_epoch", updated.GetStatus().GetRegisteredEpoch())) - return &ateapipb.AcquireWorkerEpochResponse{Epoch: epoch}, nil + return &ateapi.AcquireWorkerEpochResponse{Epoch: epoch}, nil } // RegisterWorker activates the epoch a worker process acquired and records its // pod IPs and capacity in one write. As with MintCert, the caller must be an // atelet running on the Worker's node. -func (s *Server) RegisterWorker(ctx context.Context, req *ateapipb.RegisterWorkerRequest) (*ateapipb.RegisterWorkerResponse, error) { +func (s *Server) RegisterWorker(ctx context.Context, req *ateapi.RegisterWorkerRequest) (*ateapi.RegisterWorkerResponse, error) { // TODO(identity): This check should be handled by OpenFGA. caller, err := ateletauth.Authenticate(ctx, s.ateletSPIFFEID) if err != nil { @@ -93,14 +93,14 @@ func (s *Server) RegisterWorker(ctx context.Context, req *ateapipb.RegisterWorke // does not change: an identical one is a retry of the registration // that landed, and any other is refused. if slices.Equal(status.GetIps(), req.GetIps()) && proto.Equal(status.GetCapacity(), req.GetCapacity()) { - return &ateapipb.RegisterWorkerResponse{Worker: worker}, nil + return &ateapi.RegisterWorkerResponse{Worker: worker}, nil } return nil, apierror.FailedPrecondition("epoch %d of Worker %s is already registered with other IPs or capacity", epoch, name) } // The precondition holds this write to the Worker read above, so epoch is // above its registered epoch. - updated, err := s.store.UpdateWorker(ctx, name, store.PreconditionFrom(worker), func(toUpdate *ateapipb.Worker) error { + updated, err := s.store.UpdateWorker(ctx, name, store.PreconditionFrom(worker), func(toUpdate *ateapi.Worker) error { toUpdate.Status.RegisteredEpoch = epoch // The sandbox classes were the previous worker process's. This one // reports its own, and the Worker takes no Actors until it does. @@ -120,13 +120,13 @@ func (s *Server) RegisterWorker(ctx context.Context, req *ateapipb.RegisterWorke slog.Int64("previous_epoch", status.GetRegisteredEpoch()), slog.Any("ips", req.GetIps()), slog.String("capacity", req.GetCapacity().String())) - return &ateapipb.RegisterWorkerResponse{Worker: updated}, nil + return &ateapi.RegisterWorkerResponse{Worker: updated}, nil } // SetWorkerSandboxRuntimes records the sandbox classes and runtimes of the // registered worker process. As with MintCert, the caller must be an atelet // running on the Worker's node. -func (s *Server) SetWorkerSandboxRuntimes(ctx context.Context, req *ateapipb.SetWorkerSandboxRuntimesRequest) (*ateapipb.SetWorkerSandboxRuntimesResponse, error) { +func (s *Server) SetWorkerSandboxRuntimes(ctx context.Context, req *ateapi.SetWorkerSandboxRuntimesRequest) (*ateapi.SetWorkerSandboxRuntimesResponse, error) { caller, err := ateletauth.Authenticate(ctx, s.ateletSPIFFEID) if err != nil { return nil, err @@ -155,10 +155,10 @@ func (s *Server) SetWorkerSandboxRuntimes(ctx context.Context, req *ateapipb.Set return nil, err } if sameClasses(status.GetSandboxClasses(), classes) { - return &ateapipb.SetWorkerSandboxRuntimesResponse{Worker: worker}, nil + return &ateapi.SetWorkerSandboxRuntimesResponse{Worker: worker}, nil } - updated, err := s.store.UpdateWorker(ctx, name, store.PreconditionFrom(worker), func(toUpdate *ateapipb.Worker) error { + updated, err := s.store.UpdateWorker(ctx, name, store.PreconditionFrom(worker), func(toUpdate *ateapi.Worker) error { // Replaces rather than merges: a Worker reports every runtime it has. toUpdate.Status.SandboxClasses = classes return nil @@ -170,12 +170,12 @@ func (s *Server) SetWorkerSandboxRuntimes(ctx context.Context, req *ateapipb.Set slog.String("worker", name), slog.Int64("epoch", req.GetEpoch()), slog.String("sandbox_classes", fmt.Sprint(updated.GetStatus().GetSandboxClasses()))) - return &ateapipb.SetWorkerSandboxRuntimesResponse{Worker: updated}, nil + return &ateapi.SetWorkerSandboxRuntimesResponse{Worker: updated}, nil } // workerOnCallerNode reads the named Worker, authorized by authoritative state: // a Worker on another node than the calling atelet's is reported as not found. -func (s *Server) workerOnCallerNode(ctx context.Context, name string, caller *ateletauth.Caller) (*ateapipb.Worker, error) { +func (s *Server) workerOnCallerNode(ctx context.Context, name string, caller *ateletauth.Caller) (*ateapi.Worker, error) { worker, err := s.store.GetWorker(ctx, name) if err != nil { if errors.Is(err, store.ErrNotFound) { @@ -193,7 +193,7 @@ func (s *Server) workerOnCallerNode(ctx context.Context, name string, caller *at return nil, apierror.NotFound("Worker %s not found", name) } if worker.GetStatus() == nil { - worker.Status = &ateapipb.WorkerStatus{} + worker.Status = &ateapi.WorkerStatus{} } return worker, nil } @@ -218,7 +218,7 @@ func workerWriteError(name, doing string, err error) error { // later report of another class contradicts the recorded state. A Worker // whose worker process has not reported yet has nothing for a report to // contradict. -func validateSandboxClasses(recorded string, classes []*ateapipb.WorkerSandboxClass) error { +func validateSandboxClasses(recorded string, classes []*ateapi.WorkerSandboxClass) error { if recorded == "" { return nil } @@ -233,16 +233,16 @@ func validateSandboxClasses(recorded string, classes []*ateapipb.WorkerSandboxCl // sameClasses reports whether two class lists are identical entry for entry, // in order, restorable runtimes included. A report is compared as sent, so a // Worker that reorders its runtimes between reports is recorded again. -func sameClasses(a, b []*ateapipb.WorkerSandboxClass) bool { - return slices.EqualFunc(a, b, func(x, y *ateapipb.WorkerSandboxClass) bool { return proto.Equal(x, y) }) +func sameClasses(a, b []*ateapi.WorkerSandboxClass) bool { + return slices.EqualFunc(a, b, func(x, y *ateapi.WorkerSandboxClass) bool { return proto.Equal(x, y) }) } // sortAttributes orders a runtime's compatibility attributes by key, in place. // Attribute order carries no meaning, but proto equality is order-sensitive, so // a report is canonicalized before it is compared with what is stored: the same // attributes in another order are the same runtime and write nothing. -func sortAttributes(compat *ateapipb.VersionedSandboxCompat) { - slices.SortFunc(compat.GetAttributes(), func(a, b *ateapipb.AttributeEntry) int { +func sortAttributes(compat *ateapi.VersionedSandboxCompat) { + slices.SortFunc(compat.GetAttributes(), func(a, b *ateapi.AttributeEntry) int { return cmp.Compare(a.GetKey(), b.GetKey()) }) } diff --git a/cmd/ateapi/internal/workerservice/register_test.go b/cmd/ateapi/internal/workerservice/register_test.go index 1fff45aa07..53af477e94 100644 --- a/cmd/ateapi/internal/workerservice/register_test.go +++ b/cmd/ateapi/internal/workerservice/register_test.go @@ -22,54 +22,54 @@ import ( "github.com/google/go-cmp/cmp" "google.golang.org/protobuf/testing/protocmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/ateletauth/ateletauthtest" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" ) // testCompat is a compatibility version whose identity is a single // architecture attribute, which is enough to tell two runtimes apart. -func testCompat(arch string) *ateapipb.VersionedSandboxCompat { - return &ateapipb.VersionedSandboxCompat{ +func testCompat(arch string) *ateapi.VersionedSandboxCompat { + return &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{{Key: "architecture", Value: arch}}, + Attributes: []*ateapi.AttributeEntry{{Key: "architecture", Value: arch}}, } } // testClass is one reported sandbox class: def as its default runtime and // restorable as the others. -func testClass(name string, def *ateapipb.VersionedSandboxCompat, restorable ...*ateapipb.VersionedSandboxCompat) *ateapipb.WorkerSandboxClass { - c := &ateapipb.WorkerSandboxClass{SandboxClass: name, DefaultRuntime: &ateapipb.WorkerSandboxRuntime{Version: def}} +func testClass(name string, def *ateapi.VersionedSandboxCompat, restorable ...*ateapi.VersionedSandboxCompat) *ateapi.WorkerSandboxClass { + c := &ateapi.WorkerSandboxClass{SandboxClass: name, DefaultRuntime: &ateapi.WorkerSandboxRuntime{Version: def}} for _, r := range restorable { - c.RestorableRuntimes = append(c.RestorableRuntimes, &ateapipb.WorkerSandboxRuntime{Version: r}) + c.RestorableRuntimes = append(c.RestorableRuntimes, &ateapi.WorkerSandboxRuntime{Version: r}) } return c } // testSandboxClasses is what seedReportedWorker records as already reported: // the class it gives the Worker. -var testSandboxClasses = []*ateapipb.WorkerSandboxClass{testClass("gvisor", testCompat("amd64"))} +var testSandboxClasses = []*ateapi.WorkerSandboxClass{testClass("gvisor", testCompat("amd64"))} -func registerRequest(epoch int64, actors int32) *ateapipb.RegisterWorkerRequest { - return &ateapipb.RegisterWorkerRequest{ - Worker: &ateapipb.ObjectRef{Name: testWorkerName}, +func registerRequest(epoch int64, actors int32) *ateapi.RegisterWorkerRequest { + return &ateapi.RegisterWorkerRequest{ + Worker: &ateapi.ObjectRef{Name: testWorkerName}, Epoch: epoch, Ips: testIPs, - Capacity: &ateapipb.WorkerResources{Actors: actors}, + Capacity: &ateapi.WorkerResources{Actors: actors}, } } -func runtimesRequest(epoch int64) *ateapipb.SetWorkerSandboxRuntimesRequest { - return &ateapipb.SetWorkerSandboxRuntimesRequest{ - Worker: &ateapipb.ObjectRef{Name: testWorkerName}, +func runtimesRequest(epoch int64) *ateapi.SetWorkerSandboxRuntimesRequest { + return &ateapi.SetWorkerSandboxRuntimesRequest{ + Worker: &ateapi.ObjectRef{Name: testWorkerName}, Epoch: epoch, SandboxClasses: testSandboxClasses, } } -func mustGetWorker(t *testing.T, s *Server, name string) *ateapipb.Worker { +func mustGetWorker(t *testing.T, s *Server, name string) *ateapi.Worker { t.Helper() w, err := s.store.GetWorker(context.Background(), name) if err != nil { @@ -85,11 +85,11 @@ func TestAcquireWorkerEpoch(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() s := New(st, &fakeControl{}, testAteletSPIFFEID, nil, "", nil) - seedReportedWorker(t, st, testNode, &ateapipb.WorkerResources{Actors: 1}) + seedReportedWorker(t, st, testNode, &ateapi.WorkerResources{Actors: 1}) authed := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, testNode)) for want := int64(testEpoch + 1); want <= testEpoch+2; want++ { - got, err := s.AcquireWorkerEpoch(authed, &ateapipb.AcquireWorkerEpochRequest{Worker: &ateapipb.ObjectRef{Name: testWorkerName}}) + got, err := s.AcquireWorkerEpoch(authed, &ateapi.AcquireWorkerEpochRequest{Worker: &ateapi.ObjectRef{Name: testWorkerName}}) if err != nil { t.Fatalf("AcquireWorkerEpoch() failed: %v", err) } @@ -110,10 +110,10 @@ func TestAcquireWorkerEpoch_NewWorker(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() s := New(st, &fakeControl{}, testAteletSPIFFEID, nil, "", nil) - seedWorker(t, st, testWorkerName, testNode, &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE}) + seedWorker(t, st, testWorkerName, testNode, &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_UNAVAILABLE}) authed := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, testNode)) - got, err := s.AcquireWorkerEpoch(authed, &ateapipb.AcquireWorkerEpochRequest{Worker: &ateapipb.ObjectRef{Name: testWorkerName}}) + got, err := s.AcquireWorkerEpoch(authed, &ateapi.AcquireWorkerEpochRequest{Worker: &ateapi.ObjectRef{Name: testWorkerName}}) if err != nil { t.Fatalf("AcquireWorkerEpoch() failed: %v", err) } @@ -126,20 +126,20 @@ func TestAcquireWorkerEpoch_Errors(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() s := New(st, &fakeControl{}, testAteletSPIFFEID, nil, "", nil) - seedReportedWorker(t, st, testNode, &ateapipb.WorkerResources{Actors: 1}) + seedReportedWorker(t, st, testNode, &ateapi.WorkerResources{Actors: 1}) authed := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, testNode)) - ref := &ateapipb.ObjectRef{Name: testWorkerName} + ref := &ateapi.ObjectRef{Name: testWorkerName} tests := []struct { name string ctx context.Context - req *ateapipb.AcquireWorkerEpochRequest + req *ateapi.AcquireWorkerEpochRequest want codes.Code }{ - {"unauthenticated", ateletauthtest.ContextWith(nil), &ateapipb.AcquireWorkerEpochRequest{Worker: ref}, codes.Unauthenticated}, - {"no worker ref", authed, &ateapipb.AcquireWorkerEpochRequest{}, codes.InvalidArgument}, - {"other node", ateletauthtest.ContextWith(ateletauthtest.CertOn(t, "some-other-node")), &ateapipb.AcquireWorkerEpochRequest{Worker: ref}, codes.NotFound}, - {"absent worker", authed, &ateapipb.AcquireWorkerEpochRequest{Worker: &ateapipb.ObjectRef{Name: "3b9f1e77-2c4d-4a80-91be-6d5c8f0a7e21"}}, codes.NotFound}, + {"unauthenticated", ateletauthtest.ContextWith(nil), &ateapi.AcquireWorkerEpochRequest{Worker: ref}, codes.Unauthenticated}, + {"no worker ref", authed, &ateapi.AcquireWorkerEpochRequest{}, codes.InvalidArgument}, + {"other node", ateletauthtest.ContextWith(ateletauthtest.CertOn(t, "some-other-node")), &ateapi.AcquireWorkerEpochRequest{Worker: ref}, codes.NotFound}, + {"absent worker", authed, &ateapi.AcquireWorkerEpochRequest{Worker: &ateapi.ObjectRef{Name: "3b9f1e77-2c4d-4a80-91be-6d5c8f0a7e21"}}, codes.NotFound}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { @@ -161,10 +161,10 @@ func TestRegisterWorker(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() s := New(st, &fakeControl{}, testAteletSPIFFEID, nil, "", nil) - seedReportedWorker(t, st, testNode, &ateapipb.WorkerResources{Actors: 1, CpuMillicores: 2000, MemoryBytes: 0}) + seedReportedWorker(t, st, testNode, &ateapi.WorkerResources{Actors: 1, CpuMillicores: 2000, MemoryBytes: 0}) authed := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, testNode)) - acquired, err := s.AcquireWorkerEpoch(authed, &ateapipb.AcquireWorkerEpochRequest{Worker: &ateapipb.ObjectRef{Name: testWorkerName}}) + acquired, err := s.AcquireWorkerEpoch(authed, &ateapi.AcquireWorkerEpochRequest{Worker: &ateapi.ObjectRef{Name: testWorkerName}}) if err != nil { t.Fatalf("AcquireWorkerEpoch() failed: %v", err) } @@ -207,13 +207,13 @@ func TestRegisterWorker_Epochs(t *testing.T) { defer cleanup() s := New(st, &fakeControl{}, testAteletSPIFFEID, nil, "", nil) authed := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, testNode)) - seeded := func() *ateapipb.WorkerStatus { - return &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, + seeded := func() *ateapi.WorkerStatus { + return &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, IssuedEpoch: testEpoch + 2, RegisteredEpoch: testEpoch, Ips: testIPs, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Capacity: &ateapi.WorkerResources{Actors: 1}, SandboxClasses: testSandboxClasses, } } @@ -274,11 +274,11 @@ func TestRegisterWorker_Epochs(t *testing.T) { name := fmt.Sprintf("1a7e4c83-6d20-4f95-b3c8-%012d", i) before := seedWorker(t, st, name, testNode, seeded()) - _, err := s.RegisterWorker(authed, &ateapipb.RegisterWorkerRequest{ - Worker: &ateapipb.ObjectRef{Name: name}, + _, err := s.RegisterWorker(authed, &ateapi.RegisterWorkerRequest{ + Worker: &ateapi.ObjectRef{Name: name}, Epoch: tt.epoch, Ips: tt.ips, - Capacity: &ateapipb.WorkerResources{Actors: 1}, + Capacity: &ateapi.WorkerResources{Actors: 1}, }) if code := apierror.Code(err); code != tt.wantCode { t.Fatalf("code = %v (err %v), want %v", code, err, tt.wantCode) @@ -309,7 +309,7 @@ func TestRegisterWorker_OtherNodeIsNotFound(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() s := New(st, &fakeControl{}, testAteletSPIFFEID, nil, "", nil) - seedReportedWorker(t, st, testNode, &ateapipb.WorkerResources{Actors: 1}) + seedReportedWorker(t, st, testNode, &ateapi.WorkerResources{Actors: 1}) _, err := s.RegisterWorker(ateletauthtest.ContextWith(ateletauthtest.CertOn(t, "some-other-node")), registerRequest(testEpoch, 4094)) if got := apierror.Code(err); got != codes.NotFound { @@ -330,9 +330,9 @@ func TestRegisterWorker_Errors(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() s := New(st, &fakeControl{}, testAteletSPIFFEID, nil, "", nil) - seedReportedWorker(t, st, testNode, &ateapipb.WorkerResources{Actors: 1}) + seedReportedWorker(t, st, testNode, &ateapi.WorkerResources{Actors: 1}) authed := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, testNode)) - without := func(mutate func(*ateapipb.RegisterWorkerRequest)) *ateapipb.RegisterWorkerRequest { + without := func(mutate func(*ateapi.RegisterWorkerRequest)) *ateapi.RegisterWorkerRequest { req := registerRequest(testEpoch, 2) mutate(req) return req @@ -341,16 +341,16 @@ func TestRegisterWorker_Errors(t *testing.T) { tests := []struct { name string ctx context.Context - req *ateapipb.RegisterWorkerRequest + req *ateapi.RegisterWorkerRequest want codes.Code }{ {"unauthenticated", ateletauthtest.ContextWith(nil), registerRequest(testEpoch, 2), codes.Unauthenticated}, - {"no worker ref", authed, without(func(r *ateapipb.RegisterWorkerRequest) { r.Worker = nil }), codes.InvalidArgument}, - {"no epoch", authed, without(func(r *ateapipb.RegisterWorkerRequest) { r.Epoch = 0 }), codes.InvalidArgument}, - {"no ips", authed, without(func(r *ateapipb.RegisterWorkerRequest) { r.Ips = nil }), codes.InvalidArgument}, - {"no capacity", authed, without(func(r *ateapipb.RegisterWorkerRequest) { r.Capacity = nil }), codes.InvalidArgument}, - {"absent worker", authed, without(func(r *ateapipb.RegisterWorkerRequest) { - r.Worker = &ateapipb.ObjectRef{Name: "3b9f1e77-2c4d-4a80-91be-6d5c8f0a7e21"} + {"no worker ref", authed, without(func(r *ateapi.RegisterWorkerRequest) { r.Worker = nil }), codes.InvalidArgument}, + {"no epoch", authed, without(func(r *ateapi.RegisterWorkerRequest) { r.Epoch = 0 }), codes.InvalidArgument}, + {"no ips", authed, without(func(r *ateapi.RegisterWorkerRequest) { r.Ips = nil }), codes.InvalidArgument}, + {"no capacity", authed, without(func(r *ateapi.RegisterWorkerRequest) { r.Capacity = nil }), codes.InvalidArgument}, + {"absent worker", authed, without(func(r *ateapi.RegisterWorkerRequest) { + r.Worker = &ateapi.ObjectRef{Name: "3b9f1e77-2c4d-4a80-91be-6d5c8f0a7e21"} }), codes.NotFound}, } for _, tc := range tests { @@ -370,16 +370,16 @@ func TestRegisterWorker_RejectsNonsense(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() s := New(st, &fakeControl{}, testAteletSPIFFEID, nil, "", nil) - seeded := seedReportedWorker(t, st, testNode, &ateapipb.WorkerResources{Actors: 4094}) + seeded := seedReportedWorker(t, st, testNode, &ateapi.WorkerResources{Actors: 4094}) authed := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, testNode)) for _, tc := range []struct { name string - capacity *ateapipb.WorkerResources + capacity *ateapi.WorkerResources }{ - {"negative ceiling", &ateapipb.WorkerResources{Actors: -1}}, - {"int32 underflow", &ateapipb.WorkerResources{Actors: -2147483648}}, - {"negative quantity", &ateapipb.WorkerResources{CpuMillicores: -1, MemoryBytes: 0}}, + {"negative ceiling", &ateapi.WorkerResources{Actors: -1}}, + {"int32 underflow", &ateapi.WorkerResources{Actors: -2147483648}}, + {"negative quantity", &ateapi.WorkerResources{CpuMillicores: -1, MemoryBytes: 0}}, } { t.Run(tc.name, func(t *testing.T) { req := registerRequest(testEpoch, 0) @@ -413,13 +413,13 @@ func TestSetWorkerSandboxRuntimes(t *testing.T) { v8, v9 := testCompat("arm64-v8"), testCompat("arm64-v9") // Every Worker here has registered testEpoch and reported gvisor with // amd64 as its default and v8 and v9 restorable, in that order. - seeded := func() *ateapipb.WorkerStatus { - return &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, + seeded := func() *ateapi.WorkerStatus { + return &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, IssuedEpoch: testEpoch + 1, RegisteredEpoch: testEpoch, - Capacity: &ateapipb.WorkerResources{Actors: 1}, - SandboxClasses: []*ateapipb.WorkerSandboxClass{testClass("gvisor", amd64, v8, v9)}, + Capacity: &ateapi.WorkerResources{Actors: 1}, + SandboxClasses: []*ateapi.WorkerSandboxClass{testClass("gvisor", amd64, v8, v9)}, } } @@ -430,26 +430,26 @@ func TestSetWorkerSandboxRuntimes(t *testing.T) { unreported bool // epoch defaults to testEpoch. epoch int64 - classes []*ateapipb.WorkerSandboxClass + classes []*ateapi.WorkerSandboxClass wantCode codes.Code // wantWrite is whether the report changes the record. wantWrite bool }{{ name: "identical report writes nothing", - classes: []*ateapipb.WorkerSandboxClass{testClass("gvisor", amd64, v8, v9)}, + classes: []*ateapi.WorkerSandboxClass{testClass("gvisor", amd64, v8, v9)}, }, { name: "changed default runtime writes", - classes: []*ateapipb.WorkerSandboxClass{testClass("gvisor", arm64, v8, v9)}, + classes: []*ateapi.WorkerSandboxClass{testClass("gvisor", arm64, v8, v9)}, wantWrite: true, }, { name: "changed restorable runtime writes", - classes: []*ateapipb.WorkerSandboxClass{testClass("gvisor", amd64, v8, arm64)}, + classes: []*ateapi.WorkerSandboxClass{testClass("gvisor", amd64, v8, arm64)}, wantWrite: true, }, { // A report is compared as sent: the list is atomic, so a new order // is a new report. name: "reordered restorable runtimes write", - classes: []*ateapipb.WorkerSandboxClass{testClass("gvisor", amd64, v9, v8)}, + classes: []*ateapi.WorkerSandboxClass{testClass("gvisor", amd64, v9, v8)}, wantWrite: true, }, { // Runtimes are replaced like capacity: a report that lists no @@ -457,38 +457,38 @@ func TestSetWorkerSandboxRuntimes(t *testing.T) { // default, as when a version is disabled, and the record must not // keep advertising them. name: "dropped restorable runtimes write", - classes: []*ateapipb.WorkerSandboxClass{testClass("gvisor", amd64)}, + classes: []*ateapi.WorkerSandboxClass{testClass("gvisor", amd64)}, wantWrite: true, }, { // A report from a worker process that has since been replaced, or // one that has not registered yet, describes no running process. name: "older epoch is refused", epoch: testEpoch - 1, - classes: []*ateapipb.WorkerSandboxClass{testClass("gvisor", arm64)}, + classes: []*ateapi.WorkerSandboxClass{testClass("gvisor", arm64)}, wantCode: codes.FailedPrecondition, }, { name: "acquired but unregistered epoch is refused", epoch: testEpoch + 1, - classes: []*ateapipb.WorkerSandboxClass{testClass("gvisor", arm64)}, + classes: []*ateapi.WorkerSandboxClass{testClass("gvisor", arm64)}, wantCode: codes.FailedPrecondition, }, { // Once the worker process has reported a sandbox class, an entry of // another class contradicts its recorded state and is refused. name: "another class is refused", - classes: []*ateapipb.WorkerSandboxClass{testClass("microvm", amd64, v8, v9)}, + classes: []*ateapi.WorkerSandboxClass{testClass("microvm", amd64, v8, v9)}, wantCode: codes.FailedPrecondition, }, { // A pool declares one class, so does a Worker: the list's size is an // API rule, checked before the recorded class is. name: "a second class is refused", - classes: []*ateapipb.WorkerSandboxClass{testClass("gvisor", amd64, v8, v9), testClass("microvm", amd64)}, + classes: []*ateapi.WorkerSandboxClass{testClass("gvisor", amd64, v8, v9), testClass("microvm", amd64)}, wantCode: codes.InvalidArgument, }, { // A worker process that has not reported yet sets the class on its // first report. name: "unreported Worker takes a class of any name", unreported: true, - classes: []*ateapipb.WorkerSandboxClass{testClass("microvm", amd64)}, + classes: []*ateapi.WorkerSandboxClass{testClass("microvm", amd64)}, wantWrite: true, }, { name: "a report of no classes is refused", @@ -507,8 +507,8 @@ func TestSetWorkerSandboxRuntimes(t *testing.T) { epoch = testEpoch } - got, err := s.SetWorkerSandboxRuntimes(authed, &ateapipb.SetWorkerSandboxRuntimesRequest{ - Worker: &ateapipb.ObjectRef{Name: name}, + got, err := s.SetWorkerSandboxRuntimes(authed, &ateapi.SetWorkerSandboxRuntimesRequest{ + Worker: &ateapi.ObjectRef{Name: name}, Epoch: epoch, SandboxClasses: tt.classes, }) @@ -542,20 +542,20 @@ func TestSetWorkerSandboxRuntimes_SortsAttributes(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() s := New(st, &fakeControl{}, testAteletSPIFFEID, nil, "", nil) - seedReportedWorker(t, st, testNode, &ateapipb.WorkerResources{Actors: 1}) + seedReportedWorker(t, st, testNode, &ateapi.WorkerResources{Actors: 1}) authed := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, testNode)) - compatWith := func(keys ...string) *ateapipb.VersionedSandboxCompat { - c := &ateapipb.VersionedSandboxCompat{SchemaVersion: "v1"} + compatWith := func(keys ...string) *ateapi.VersionedSandboxCompat { + c := &ateapi.VersionedSandboxCompat{SchemaVersion: "v1"} for _, k := range keys { - c.Attributes = append(c.Attributes, &ateapipb.AttributeEntry{Key: k, Value: "v"}) + c.Attributes = append(c.Attributes, &ateapi.AttributeEntry{Key: k, Value: "v"}) } return c } - report := func(def, restorable *ateapipb.VersionedSandboxCompat) *ateapipb.Worker { + report := func(def, restorable *ateapi.VersionedSandboxCompat) *ateapi.Worker { t.Helper() req := runtimesRequest(testEpoch) - req.SandboxClasses = []*ateapipb.WorkerSandboxClass{testClass("gvisor", def, restorable)} + req.SandboxClasses = []*ateapi.WorkerSandboxClass{testClass("gvisor", def, restorable)} got, err := s.SetWorkerSandboxRuntimes(authed, req) if err != nil { t.Fatalf("SetWorkerSandboxRuntimes() failed: %v", err) @@ -564,7 +564,7 @@ func TestSetWorkerSandboxRuntimes_SortsAttributes(t *testing.T) { } first := report(compatWith("cpu_features", "architecture"), compatWith("sandbox_bundle_hash", "architecture")) - want := []*ateapipb.WorkerSandboxClass{testClass("gvisor", compatWith("architecture", "cpu_features"), compatWith("architecture", "sandbox_bundle_hash"))} + want := []*ateapi.WorkerSandboxClass{testClass("gvisor", compatWith("architecture", "cpu_features"), compatWith("architecture", "sandbox_bundle_hash"))} if diff := cmp.Diff(want, first.GetStatus().GetSandboxClasses(), protocmp.Transform()); diff != "" { t.Errorf("sandbox_classes not stored sorted by key (-want +got):\n%s", diff) } @@ -579,9 +579,9 @@ func TestSetWorkerSandboxRuntimes_Errors(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() s := New(st, &fakeControl{}, testAteletSPIFFEID, nil, "", nil) - seedReportedWorker(t, st, testNode, &ateapipb.WorkerResources{Actors: 1}) + seedReportedWorker(t, st, testNode, &ateapi.WorkerResources{Actors: 1}) authed := ateletauthtest.ContextWith(ateletauthtest.CertOn(t, testNode)) - without := func(mutate func(*ateapipb.SetWorkerSandboxRuntimesRequest)) *ateapipb.SetWorkerSandboxRuntimesRequest { + without := func(mutate func(*ateapi.SetWorkerSandboxRuntimesRequest)) *ateapi.SetWorkerSandboxRuntimesRequest { req := runtimesRequest(testEpoch) mutate(req) return req @@ -590,22 +590,22 @@ func TestSetWorkerSandboxRuntimes_Errors(t *testing.T) { tests := []struct { name string ctx context.Context - req *ateapipb.SetWorkerSandboxRuntimesRequest + req *ateapi.SetWorkerSandboxRuntimesRequest want codes.Code }{ {"unauthenticated", ateletauthtest.ContextWith(nil), runtimesRequest(testEpoch), codes.Unauthenticated}, - {"no worker ref", authed, without(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { r.Worker = nil }), codes.InvalidArgument}, - {"no epoch", authed, without(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { r.Epoch = 0 }), codes.InvalidArgument}, - {"no sandbox classes", authed, without(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses = nil }), codes.InvalidArgument}, - {"class without a default runtime", authed, without(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { - r.SandboxClasses = []*ateapipb.WorkerSandboxClass{{SandboxClass: "gvisor"}} + {"no worker ref", authed, without(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.Worker = nil }), codes.InvalidArgument}, + {"no epoch", authed, without(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.Epoch = 0 }), codes.InvalidArgument}, + {"no sandbox classes", authed, without(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { r.SandboxClasses = nil }), codes.InvalidArgument}, + {"class without a default runtime", authed, without(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { + r.SandboxClasses = []*ateapi.WorkerSandboxClass{{SandboxClass: "gvisor"}} }), codes.InvalidArgument}, - {"class that is not a sandbox class", authed, without(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { - r.SandboxClasses = []*ateapipb.WorkerSandboxClass{testClass("plain", testCompat("amd64"))} + {"class that is not a sandbox class", authed, without(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { + r.SandboxClasses = []*ateapi.WorkerSandboxClass{testClass("plain", testCompat("amd64"))} }), codes.InvalidArgument}, {"other node", ateletauthtest.ContextWith(ateletauthtest.CertOn(t, "some-other-node")), runtimesRequest(testEpoch), codes.NotFound}, - {"absent worker", authed, without(func(r *ateapipb.SetWorkerSandboxRuntimesRequest) { - r.Worker = &ateapipb.ObjectRef{Name: "3b9f1e77-2c4d-4a80-91be-6d5c8f0a7e21"} + {"absent worker", authed, without(func(r *ateapi.SetWorkerSandboxRuntimesRequest) { + r.Worker = &ateapi.ObjectRef{Name: "3b9f1e77-2c4d-4a80-91be-6d5c8f0a7e21"} }), codes.NotFound}, } for _, tc := range tests { diff --git a/cmd/ateapi/internal/workerservice/report.go b/cmd/ateapi/internal/workerservice/report.go index 979bbe3cb5..3b17a3883d 100644 --- a/cmd/ateapi/internal/workerservice/report.go +++ b/cmd/ateapi/internal/workerservice/report.go @@ -17,15 +17,15 @@ package workerservice import ( "context" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/ateletauth" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // ReportActorSnapshotState records the snapshot state that the calling atelet // reports for an Actor on its node. -func (s *Server) ReportActorSnapshotState(ctx context.Context, req *ateapipb.ReportActorSnapshotStateRequest) (*ateapipb.ReportActorSnapshotStateResponse, error) { +func (s *Server) ReportActorSnapshotState(ctx context.Context, req *ateapi.ReportActorSnapshotStateRequest) (*ateapi.ReportActorSnapshotStateResponse, error) { // Authz doesn't cover WorkerService, so authenticate before reading the // request. caller, err := ateletauth.Authenticate(ctx, s.ateletSPIFFEID) @@ -39,5 +39,5 @@ func (s *Server) ReportActorSnapshotState(ctx context.Context, req *ateapipb.Rep if err := s.control.ApplyActorSnapshotState(ctx, actorRef, req.GetActorUid(), caller.NodeName, req.GetState()); err != nil { return nil, err } - return &ateapipb.ReportActorSnapshotStateResponse{}, nil + return &ateapi.ReportActorSnapshotStateResponse{}, nil } diff --git a/cmd/ateapi/internal/workerservice/report_test.go b/cmd/ateapi/internal/workerservice/report_test.go index c2f6c5204f..5f0ec32008 100644 --- a/cmd/ateapi/internal/workerservice/report_test.go +++ b/cmd/ateapi/internal/workerservice/report_test.go @@ -22,26 +22,26 @@ import ( "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/ateletauth/ateletauthtest" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const reportActorUID = "5f2c1a90-7b34-4e6d-8a11-0c3e9d5b7f42" -func reportRequest() *ateapipb.ReportActorSnapshotStateRequest { - durable := &ateapipb.SnapshotReport{ +func reportRequest() *ateapi.ReportActorSnapshotStateRequest { + durable := &ateapi.SnapshotReport{ Uuid: "snap-1", Generation: 1, - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: "gs://bucket/actors/a/snap-1"}, + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + Object: &ateapi.ObjectSnapshot{SnapshotUri: "gs://bucket/actors/a/snap-1"}, LocalCommitTime: timestamppb.Now(), } - return &ateapipb.ReportActorSnapshotStateRequest{ - Actor: &ateapipb.ObjectRef{Atespace: suspendAtespace, Name: suspendActor}, + return &ateapi.ReportActorSnapshotStateRequest{ + Actor: &ateapi.ObjectRef{Atespace: suspendAtespace, Name: suspendActor}, ActorUid: reportActorUID, - State: &ateapipb.ActorSnapshotState{LatestDurable: durable}, + State: &ateapi.ActorSnapshotState{LatestDurable: durable}, } } @@ -80,7 +80,7 @@ func TestReportActorSnapshotState_Refused(t *testing.T) { tests := []struct { name string ctx context.Context - req *ateapipb.ReportActorSnapshotStateRequest + req *ateapi.ReportActorSnapshotStateRequest controlErr error want codes.Code wantApplied bool diff --git a/cmd/ateapi/internal/workerservice/service.go b/cmd/ateapi/internal/workerservice/service.go index f295fbf86d..36758491b9 100644 --- a/cmd/ateapi/internal/workerservice/service.go +++ b/cmd/ateapi/internal/workerservice/service.go @@ -19,16 +19,16 @@ package workerservice import ( "context" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/localca" "go.ate.dev/substrate/internal/localjwtauthority" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) -// Server implements ateapipb.WorkerServiceServer. +// Server implements ateapi.WorkerServiceServer. type Server struct { - ateapipb.UnimplementedWorkerServiceServer + ateapi.UnimplementedWorkerServiceServer // store is where a Worker's reports are recorded, and the authoritative // state every request is authorized against. @@ -54,12 +54,12 @@ type Server struct { // actorControl is the in-process slice of the Control service this package // drives. *controlapi.RPCService satisfies it. type actorControl interface { - SuspendActor(ctx context.Context, req *ateapipb.SuspendActorRequest) (*ateapipb.SuspendActorResponse, error) - ApplyActorSnapshotState(ctx context.Context, actorRef resources.ActorRef, actorUID, node string, state *ateapipb.ActorSnapshotState) error - CrashActorReportedByWorker(ctx context.Context, actorRef resources.ActorRef, actorUID, workerName, message string) (*ateapipb.Actor, error) + SuspendActor(ctx context.Context, req *ateapi.SuspendActorRequest) (*ateapi.SuspendActorResponse, error) + ApplyActorSnapshotState(ctx context.Context, actorRef resources.ActorRef, actorUID, node string, state *ateapi.ActorSnapshotState) error + CrashActorReportedByWorker(ctx context.Context, actorRef resources.ActorRef, actorUID, workerName, message string) (*ateapi.Actor, error) } -var _ ateapipb.WorkerServiceServer = (*Server)(nil) +var _ ateapi.WorkerServiceServer = (*Server)(nil) func New(store store.Interface, control actorControl, ateletSPIFFEID string, actorIDCAPool localca.Pool, actorJWTIssuer string, actorIDJWTPool localjwtauthority.Pool) *Server { return &Server{ diff --git a/cmd/ateapi/internal/workerservice/service_test.go b/cmd/ateapi/internal/workerservice/service_test.go index 915dc30962..4c537ee47e 100644 --- a/cmd/ateapi/internal/workerservice/service_test.go +++ b/cmd/ateapi/internal/workerservice/service_test.go @@ -18,10 +18,10 @@ import ( "context" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/installdefaults" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // The Worker every test in this package calls about, and the node its atelet @@ -39,22 +39,22 @@ var testAteletSPIFFEID = installdefaults.SPIFFEID(installdefaults.SystemNamespac // point of most of the tests: whether the request reached the operation at // all. type fakeControl struct { - calls []*ateapipb.SuspendActorRequest - resp *ateapipb.SuspendActorResponse + calls []*ateapi.SuspendActorRequest + resp *ateapi.SuspendActorResponse err error reports []appliedReport reportErr error crashCalls []crashCall - crashResp *ateapipb.Actor + crashResp *ateapi.Actor } -func (f *fakeControl) SuspendActor(_ context.Context, req *ateapipb.SuspendActorRequest) (*ateapipb.SuspendActorResponse, error) { +func (f *fakeControl) SuspendActor(_ context.Context, req *ateapi.SuspendActorRequest) (*ateapi.SuspendActorResponse, error) { f.calls = append(f.calls, req) return f.resp, f.err } -func (f *fakeControl) ApplyActorSnapshotState(_ context.Context, actorRef resources.ActorRef, actorUID, node string, state *ateapipb.ActorSnapshotState) error { +func (f *fakeControl) ApplyActorSnapshotState(_ context.Context, actorRef resources.ActorRef, actorUID, node string, state *ateapi.ActorSnapshotState) error { f.reports = append(f.reports, appliedReport{actorRef: actorRef, actorUID: actorUID, node: node, state: state}) return f.reportErr } @@ -64,7 +64,7 @@ type appliedReport struct { actorRef resources.ActorRef actorUID string node string - state *ateapipb.ActorSnapshotState + state *ateapi.ActorSnapshotState } // crashCall is one CrashActorReportedByWorker call. @@ -73,7 +73,7 @@ type crashCall struct { ActorUID, WorkerName, Message string } -func (f *fakeControl) CrashActorReportedByWorker(_ context.Context, actorRef resources.ActorRef, actorUID, workerName, message string) (*ateapipb.Actor, error) { +func (f *fakeControl) CrashActorReportedByWorker(_ context.Context, actorRef resources.ActorRef, actorUID, workerName, message string) (*ateapi.Actor, error) { f.crashCalls = append(f.crashCalls, crashCall{actorRef, actorUID, workerName, message}) return f.crashResp, f.err } @@ -88,10 +88,10 @@ var testIPs = []string{"10.1.2.3"} // already registered with testEpoch, testIPs and capacity, and reported its // default runtime: identity from the pod, the way the syncer writes it, plus // the result of an earlier registration. -func seedReportedWorker(t *testing.T, st store.Interface, nodeName string, capacity *ateapipb.WorkerResources) *ateapipb.Worker { +func seedReportedWorker(t *testing.T, st store.Interface, nodeName string, capacity *ateapi.WorkerResources) *ateapi.Worker { t.Helper() - return seedWorker(t, st, testWorkerName, nodeName, &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, + return seedWorker(t, st, testWorkerName, nodeName, &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, IssuedEpoch: testEpoch, RegisteredEpoch: testEpoch, Ips: testIPs, @@ -102,10 +102,10 @@ func seedReportedWorker(t *testing.T, st store.Interface, nodeName string, capac // seedWorker registers a Worker named name on nodeName, with status already // recorded. name doubles as the pod UID, so it must be UUID-shaped. -func seedWorker(t *testing.T, st store.Interface, name, nodeName string, status *ateapipb.WorkerStatus) *ateapipb.Worker { +func seedWorker(t *testing.T, st store.Interface, name, nodeName string, status *ateapi.WorkerStatus) *ateapi.Worker { t.Helper() - created, err := st.CreateWorker(context.Background(), &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: name}, + created, err := st.CreateWorker(context.Background(), &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: name}, WorkerNamespace: "ate-system", WorkerPool: "pool-1", WorkerPod: "worker-pod-1", diff --git a/cmd/ateapi/internal/workerservice/suspend.go b/cmd/ateapi/internal/workerservice/suspend.go index 4c58c44319..8af6ea1386 100644 --- a/cmd/ateapi/internal/workerservice/suspend.go +++ b/cmd/ateapi/internal/workerservice/suspend.go @@ -20,17 +20,17 @@ import ( "fmt" "log/slog" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" "go.ate.dev/substrate/cmd/ateapi/internal/ateletauth" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // RequestActorSuspend suspends an Actor on behalf of the Worker hosting it. The // caller must be an atelet running on the Worker's node. -func (s *Server) RequestActorSuspend(ctx context.Context, req *ateapipb.RequestActorSuspendRequest) (*ateapipb.RequestActorSuspendResponse, error) { +func (s *Server) RequestActorSuspend(ctx context.Context, req *ateapi.RequestActorSuspendRequest) (*ateapi.RequestActorSuspendResponse, error) { caller, err := ateletauth.Authenticate(ctx, s.ateletSPIFFEID) if err != nil { return nil, err @@ -55,7 +55,7 @@ func (s *Server) RequestActorSuspend(ctx context.Context, req *ateapipb.RequestA // the workflow to acquire the lease, the Actor can be resumed onto another // Worker, or deleted and recreated under the same name, and the workflow // suspends whatever the reference resolves to by then. See #1773. - resp, err := s.control.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: req.GetActor()}) + resp, err := s.control.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: req.GetActor()}) if err != nil { return nil, err } @@ -64,7 +64,7 @@ func (s *Server) RequestActorSuspend(ctx context.Context, req *ateapipb.RequestA slog.String("actor", actorRef.String()), slog.String("actor_uid", req.GetActorUid()), slog.String("node", caller.NodeName)) - return &ateapipb.RequestActorSuspendResponse{Actor: resp.GetActor()}, nil + return &ateapi.RequestActorSuspendResponse{Actor: resp.GetActor()}, nil } // authorizeHostedActor checks that the calling atelet may speak for actorRef: @@ -106,7 +106,7 @@ func (s *Server) authorizeHostedActor(ctx context.Context, caller *ateletauth.Ca // Both failures are NotFound rather than PermissionDenied, as for a Worker on // another node: an atelet learns nothing about Actors it does not host, not // even that they exist. -func checkActorHostedBy(ctx context.Context, actor *ateapipb.Actor, workerName, actorUID string) error { +func checkActorHostedBy(ctx context.Context, actor *ateapi.Actor, workerName, actorUID string) error { actorRef := resources.ActorRefFromActor(actor) if got := actor.GetMetadata().GetUid(); got != actorUID { // The named Actor was deleted and recreated, and the caller never diff --git a/cmd/ateapi/internal/workerservice/suspend_test.go b/cmd/ateapi/internal/workerservice/suspend_test.go index 1a7425a642..ec276ebe4f 100644 --- a/cmd/ateapi/internal/workerservice/suspend_test.go +++ b/cmd/ateapi/internal/workerservice/suspend_test.go @@ -22,11 +22,11 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/protobuf/testing/protocmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/ateletauth/ateletauthtest" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const ( @@ -37,14 +37,14 @@ const ( // seedHostedActor stores an actor assigned to workerName, as the placement // path leaves one that is RUNNING. An empty workerName seeds an actor with no // assignment at all, which is how a SUSPENDED or CRASHED one looks. -func seedHostedActor(t *testing.T, st store.Interface, workerName string) *ateapipb.Actor { +func seedHostedActor(t *testing.T, st store.Interface, workerName string) *ateapi.Actor { t.Helper() - actorStatus := &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED} + actorStatus := &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED} if workerName != "" { - actorStatus = &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{ - Worker: &ateapipb.ObjectRef{Name: workerName}, + actorStatus = &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{ + Worker: &ateapi.ObjectRef{Name: workerName}, WorkerNamespace: "ate-system", WorkerPool: "pool-1", WorkerPod: "worker-pod-1", @@ -52,16 +52,16 @@ func seedHostedActor(t *testing.T, st store.Interface, workerName string) *ateap }, } } - return storetest.MustCreateActor(t, context.Background(), st, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: suspendAtespace, Name: suspendActor}, + return storetest.MustCreateActor(t, context.Background(), st, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: suspendAtespace, Name: suspendActor}, Status: actorStatus, }) } -func suspendRequest(actorUID string) *ateapipb.RequestActorSuspendRequest { - return &ateapipb.RequestActorSuspendRequest{ - Worker: &ateapipb.ObjectRef{Name: testWorkerName}, - Actor: &ateapipb.ObjectRef{Atespace: suspendAtespace, Name: suspendActor}, +func suspendRequest(actorUID string) *ateapi.RequestActorSuspendRequest { + return &ateapi.RequestActorSuspendRequest{ + Worker: &ateapi.ObjectRef{Name: testWorkerName}, + Actor: &ateapi.ObjectRef{Atespace: suspendAtespace, Name: suspendActor}, ActorUid: actorUID, } } @@ -71,13 +71,13 @@ func suspendRequest(actorUID string) *ateapipb.RequestActorSuspendRequest { func TestRequestActorSuspend(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() - seedReportedWorker(t, st, testNode, &ateapipb.WorkerResources{Actors: 1}) + seedReportedWorker(t, st, testNode, &ateapi.WorkerResources{Actors: 1}) actor := seedHostedActor(t, st, testWorkerName) - suspended := &ateapipb.Actor{ + suspended := &ateapi.Actor{ Metadata: actor.GetMetadata(), - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, } - control := &fakeControl{resp: &ateapipb.SuspendActorResponse{Actor: suspended}} + control := &fakeControl{resp: &ateapi.SuspendActorResponse{Actor: suspended}} s := New(st, control, testAteletSPIFFEID, nil, "", nil) got, err := s.RequestActorSuspend( @@ -86,8 +86,8 @@ func TestRequestActorSuspend(t *testing.T) { if err != nil { t.Fatalf("RequestActorSuspend() failed: %v", err) } - want := []*ateapipb.SuspendActorRequest{{ - Actor: &ateapipb.ObjectRef{Atespace: suspendAtespace, Name: suspendActor}, + want := []*ateapi.SuspendActorRequest{{ + Actor: &ateapi.ObjectRef{Atespace: suspendAtespace, Name: suspendActor}, }} if diff := cmp.Diff(want, control.calls, protocmp.Transform()); diff != "" { t.Errorf("suspend calls mismatch (-want +got):\n%s", diff) @@ -123,7 +123,7 @@ func TestRequestActorSuspend_OnlyForHostedActors(t *testing.T) { t.Run(tc.name, func(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() - seedReportedWorker(t, st, testNode, &ateapipb.WorkerResources{Actors: 1}) + seedReportedWorker(t, st, testNode, &ateapi.WorkerResources{Actors: 1}) actor := seedHostedActor(t, st, tc.assignedWorker) control := &fakeControl{} s := New(st, control, testAteletSPIFFEID, nil, "", nil) @@ -148,7 +148,7 @@ func TestRequestActorSuspend_OnlyForHostedActors(t *testing.T) { func TestRequestActorSuspend_Errors(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() - seedReportedWorker(t, st, testNode, &ateapipb.WorkerResources{Actors: 1}) + seedReportedWorker(t, st, testNode, &ateapi.WorkerResources{Actors: 1}) actor := seedHostedActor(t, st, testWorkerName) uid := actor.GetMetadata().GetUid() control := &fakeControl{} @@ -158,40 +158,40 @@ func TestRequestActorSuspend_Errors(t *testing.T) { tests := []struct { name string ctx context.Context - req *ateapipb.RequestActorSuspendRequest + req *ateapi.RequestActorSuspendRequest want codes.Code }{ {"unauthenticated", ateletauthtest.ContextWith(nil), suspendRequest(uid), codes.Unauthenticated}, - {"no worker ref", authed, &ateapipb.RequestActorSuspendRequest{ - Actor: &ateapipb.ObjectRef{Atespace: suspendAtespace, Name: suspendActor}, + {"no worker ref", authed, &ateapi.RequestActorSuspendRequest{ + Actor: &ateapi.ObjectRef{Atespace: suspendAtespace, Name: suspendActor}, ActorUid: uid, }, codes.InvalidArgument}, - {"atespaced worker ref", authed, &ateapipb.RequestActorSuspendRequest{ - Worker: &ateapipb.ObjectRef{Atespace: suspendAtespace, Name: testWorkerName}, - Actor: &ateapipb.ObjectRef{Atespace: suspendAtespace, Name: suspendActor}, + {"atespaced worker ref", authed, &ateapi.RequestActorSuspendRequest{ + Worker: &ateapi.ObjectRef{Atespace: suspendAtespace, Name: testWorkerName}, + Actor: &ateapi.ObjectRef{Atespace: suspendAtespace, Name: suspendActor}, ActorUid: uid, }, codes.InvalidArgument}, - {"no actor ref", authed, &ateapipb.RequestActorSuspendRequest{ - Worker: &ateapipb.ObjectRef{Name: testWorkerName}, + {"no actor ref", authed, &ateapi.RequestActorSuspendRequest{ + Worker: &ateapi.ObjectRef{Name: testWorkerName}, ActorUid: uid, }, codes.InvalidArgument}, - {"actor ref without atespace", authed, &ateapipb.RequestActorSuspendRequest{ - Worker: &ateapipb.ObjectRef{Name: testWorkerName}, - Actor: &ateapipb.ObjectRef{Name: suspendActor}, + {"actor ref without atespace", authed, &ateapi.RequestActorSuspendRequest{ + Worker: &ateapi.ObjectRef{Name: testWorkerName}, + Actor: &ateapi.ObjectRef{Name: suspendActor}, ActorUid: uid, }, codes.InvalidArgument}, // Without a UID the request could outlive the actor it was made about // and suspend whatever took its name, so an absent one is refused // rather than treated as "whichever is there now". {"no actor uid", authed, suspendRequest(""), codes.InvalidArgument}, - {"absent worker", authed, &ateapipb.RequestActorSuspendRequest{ - Worker: &ateapipb.ObjectRef{Name: "5c7e2a91-3d4b-4f60-8a1c-2e9b7d0f4a63"}, - Actor: &ateapipb.ObjectRef{Atespace: suspendAtespace, Name: suspendActor}, + {"absent worker", authed, &ateapi.RequestActorSuspendRequest{ + Worker: &ateapi.ObjectRef{Name: "5c7e2a91-3d4b-4f60-8a1c-2e9b7d0f4a63"}, + Actor: &ateapi.ObjectRef{Atespace: suspendAtespace, Name: suspendActor}, ActorUid: uid, }, codes.NotFound}, - {"absent actor", authed, &ateapipb.RequestActorSuspendRequest{ - Worker: &ateapipb.ObjectRef{Name: testWorkerName}, - Actor: &ateapipb.ObjectRef{Atespace: suspendAtespace, Name: "no-such-actor"}, + {"absent actor", authed, &ateapi.RequestActorSuspendRequest{ + Worker: &ateapi.ObjectRef{Name: testWorkerName}, + Actor: &ateapi.ObjectRef{Atespace: suspendAtespace, Name: "no-such-actor"}, ActorUid: uid, }, codes.NotFound}, } @@ -214,7 +214,7 @@ func TestRequestActorSuspend_Errors(t *testing.T) { func TestRequestActorSuspend_PassesThroughTheWorkflowsRefusal(t *testing.T) { st, cleanup := storetest.SetupTestStore(t) defer cleanup() - seedReportedWorker(t, st, testNode, &ateapipb.WorkerResources{Actors: 1}) + seedReportedWorker(t, st, testNode, &ateapi.WorkerResources{Actors: 1}) actor := seedHostedActor(t, st, testWorkerName) control := &fakeControl{err: apierror.FailedPrecondition("Actor is RESUMING")} s := New(st, control, testAteletSPIFFEID, nil, "", nil) diff --git a/cmd/ateapi/main.go b/cmd/ateapi/main.go index 5658a10ab1..7b715e7cc9 100644 --- a/cmd/ateapi/main.go +++ b/cmd/ateapi/main.go @@ -31,6 +31,8 @@ import ( "github.com/jackc/pgx/v5/pgconn" "github.com/spf13/pflag" + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/cmd/ateapi/internal/apiauthn" "go.ate.dev/substrate/cmd/ateapi/internal/apiconfig" "go.ate.dev/substrate/cmd/ateapi/internal/authz" @@ -52,8 +54,6 @@ import ( "go.ate.dev/substrate/internal/volume" "go.ate.dev/substrate/pkg/client/clientset/versioned" "go.ate.dev/substrate/pkg/client/informers/externalversions" - "go.ate.dev/substrate/pkg/proto/ateapipb" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "go.opentelemetry.io/otel" "google.golang.org/grpc" @@ -285,8 +285,8 @@ func main() { } ateFactory := externalversions.NewSharedInformerFactory(ateClient, 0) - workerPoolLister := ateFactory.Api().V1alpha1().WorkerPools().Lister() - csiDriverConfigLister := ateFactory.Api().V1alpha1().CSIDriverConfigs().Lister() + workerPoolLister := ateFactory.Ate().V1().WorkerPools().Lister() + csiDriverConfigLister := ateFactory.Ate().V1().CSIDriverConfigs().Lister() ateletPodInformerFactory, ateletPodInformer := controlapi.AteletInformer(clientset, ateletNamespace) scInformerFactory := informers.NewSharedInformerFactory(clientset, 0) @@ -360,7 +360,7 @@ func main() { *defaultEgressGatewayAddress, *actorWorkflowDeadline, volPlugins, - objectstorev1.NewControlProviderClient(objectStorePluginConn), + objectstore.NewControlProviderClient(objectStorePluginConn), *actorJWTIssuer, actorIDJWTAuthorityPool, actorIDCAPool, @@ -411,8 +411,8 @@ func main() { ), ) reflection.Register(mux) - ateapipb.RegisterControlServer(mux, controlSrv) - ateapipb.RegisterWorkerServiceServer(mux, workerservice.New(persistence, controlSrv, ateletSPIFFEID, actorIDCAPool, *actorJWTIssuer, actorIDJWTAuthorityPool)) + ateapi.RegisterControlServer(mux, controlSrv) + ateapi.RegisterWorkerServiceServer(mux, workerservice.New(persistence, controlSrv, ateletSPIFFEID, actorIDCAPool, *actorJWTIssuer, actorIDJWTAuthorityPool)) // Every RPC needs the store, so a replica that cannot reach it leaves the // Service until it can. Liveness stays green: the pool reconnects on its own. diff --git a/cmd/atecontroller/internal/controllers/egressmitmtrust_controller.go b/cmd/atecontroller/internal/controllers/egressmitmtrust_controller.go index 2829539756..ba5c366c64 100644 --- a/cmd/atecontroller/internal/controllers/egressmitmtrust_controller.go +++ b/cmd/atecontroller/internal/controllers/egressmitmtrust_controller.go @@ -57,7 +57,12 @@ func EgressMITMCAPoolRef(systemNamespace string) types.NamespacedName { return types.NamespacedName{Namespace: systemNamespace, Name: egressMITMCAPoolSecret} } -//+kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch +// resourceNames covers list and watch because the manager's cache selects the +// Secret by metadata.name (managerOptions in main.go), which the apiserver +// authorizes as a request for that one name. Without the selector the grant +// would deny them. +// +//+kubebuilder:rbac:groups=core,resources=secrets,resourceNames=egress-mitm-ca-pool,verbs=get;list;watch,namespace=ate-system //+kubebuilder:rbac:groups=certificates.k8s.io,resources=clustertrustbundles,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=certificates.k8s.io,resources=signers,resourceNames=egress-mitm.ate.dev/*,verbs=attest diff --git a/cmd/atecontroller/internal/controllers/networkpolicy_controller.go b/cmd/atecontroller/internal/controllers/networkpolicy_controller.go index a1f6b13a19..210539a458 100644 --- a/cmd/atecontroller/internal/controllers/networkpolicy_controller.go +++ b/cmd/atecontroller/internal/controllers/networkpolicy_controller.go @@ -27,8 +27,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/resources" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" ) const ( @@ -52,7 +52,7 @@ type NetworkPolicyReconciler struct { func (r *NetworkPolicyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { log := log.FromContext(ctx) - wp := &atev1alpha1.WorkerPool{} + wp := &atev1.WorkerPool{} if err := r.Get(ctx, req.NamespacedName, wp); err != nil { if k8errors.IsNotFound(err) { return ctrl.Result{}, nil @@ -75,7 +75,7 @@ func (r *NetworkPolicyReconciler) Reconcile(ctx context.Context, req ctrl.Reques return ctrl.Result{}, nil } -func (r *NetworkPolicyReconciler) reconcileImpl(ctx context.Context, wp *atev1alpha1.WorkerPool) error { +func (r *NetworkPolicyReconciler) reconcileImpl(ctx context.Context, wp *atev1.WorkerPool) error { log := log.FromContext(ctx) npAC := r.buildNetworkPolicyApplyConfig(wp) @@ -90,13 +90,13 @@ func (r *NetworkPolicyReconciler) reconcileImpl(ctx context.Context, wp *atev1al return nil } -func (r *NetworkPolicyReconciler) buildNetworkPolicyApplyConfig(wp *atev1alpha1.WorkerPool) *networkingv1ac.NetworkPolicyApplyConfiguration { +func (r *NetworkPolicyReconciler) buildNetworkPolicyApplyConfig(wp *atev1.WorkerPool) *networkingv1ac.NetworkPolicyApplyConfiguration { np := networkingv1ac.NetworkPolicy(resources.NetworkPolicyName(wp.Name), wp.Namespace). WithLabels(map[string]string{ "ate.dev/worker-pool": wp.Name, }). WithOwnerReferences(metav1ac.OwnerReference(). - WithAPIVersion(atev1alpha1.GroupVersion.String()). + WithAPIVersion(atev1.GroupVersion.String()). WithKind("WorkerPool"). WithName(wp.Name). WithUID(wp.UID). @@ -130,7 +130,7 @@ func (r *NetworkPolicyReconciler) buildNetworkPolicyApplyConfig(wp *atev1alpha1. func (r *NetworkPolicyReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). Named("networkpolicy"). - For(&atev1alpha1.WorkerPool{}). + For(&atev1.WorkerPool{}). Owns(&networkingv1.NetworkPolicy{}). Complete(r) } diff --git a/cmd/atecontroller/internal/controllers/sandboxconfig_protection_controller.go b/cmd/atecontroller/internal/controllers/sandboxconfig_protection_controller.go index 355caeb90c..b435c54524 100644 --- a/cmd/atecontroller/internal/controllers/sandboxconfig_protection_controller.go +++ b/cmd/atecontroller/internal/controllers/sandboxconfig_protection_controller.go @@ -25,7 +25,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/reconcile" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" ) // workerPoolSandboxConfigIndex names the cache index from a SandboxConfig's @@ -59,12 +59,12 @@ type SandboxConfigProtectionReconciler struct { // when atecontroller starts, which releases a config whose last user went // away while atecontroller was down. func (r *SandboxConfigProtectionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - sc := &atev1alpha1.SandboxConfig{} + sc := &atev1.SandboxConfig{} if err := r.Get(ctx, req.NamespacedName, sc); err != nil { // Already deleted. Nothing to release. return ctrl.Result{}, client.IgnoreNotFound(err) } - if sc.DeletionTimestamp.IsZero() || !controllerutil.ContainsFinalizer(sc, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) { + if sc.DeletionTimestamp.IsZero() || !controllerutil.ContainsFinalizer(sc, atev1.SandboxConfigWorkerPoolProtectionFinalizer) { // Not being deleted, or already released. Other finalizers, if // any, decide the rest. return ctrl.Result{}, nil @@ -83,14 +83,14 @@ func (r *SandboxConfigProtectionReconciler) Reconcile(ctx context.Context, req c // does it list from the API server. That is rare, because a config is deleted // far less often than a pool reconciles. func (r *SandboxConfigProtectionReconciler) usedByWorkerPool(ctx context.Context, name string) (bool, error) { - var cached atev1alpha1.WorkerPoolList + var cached atev1.WorkerPoolList if err := r.List(ctx, &cached, client.MatchingFields{workerPoolSandboxConfigIndex: name}); err != nil { return false, fmt.Errorf("failed to list WorkerPools using SandboxConfig %q: %w", name, err) } if len(cached.Items) > 0 { return true, nil } - var pools atev1alpha1.WorkerPoolList + var pools atev1.WorkerPoolList if err := r.APIReader.List(ctx, &pools); err != nil { return false, fmt.Errorf("failed to list WorkerPools: %w", err) } @@ -105,12 +105,12 @@ func (r *SandboxConfigProtectionReconciler) usedByWorkerPool(ctx context.Context // removeProtectionFinalizer removes the protection finalizer from sc. The // patch carries sc's resourceVersion, so a concurrent change to the config // fails with a conflict and the reconcile is retried. -func removeProtectionFinalizer(ctx context.Context, c client.Client, sc *atev1alpha1.SandboxConfig) error { - if !controllerutil.ContainsFinalizer(sc, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) { +func removeProtectionFinalizer(ctx context.Context, c client.Client, sc *atev1.SandboxConfig) error { + if !controllerutil.ContainsFinalizer(sc, atev1.SandboxConfigWorkerPoolProtectionFinalizer) { return nil } orig := sc.DeepCopy() - controllerutil.RemoveFinalizer(sc, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) + controllerutil.RemoveFinalizer(sc, atev1.SandboxConfigWorkerPoolProtectionFinalizer) if err := c.Patch(ctx, sc, client.MergeFromWithOptions(orig, client.MergeFromWithOptimisticLock{})); err != nil { return fmt.Errorf("failed to update finalizers of SandboxConfig %q: %w", sc.Name, err) } @@ -131,9 +131,9 @@ func removeProtectionFinalizer(ctx context.Context, c client.Client, sc *atev1al // being marked for deletion, and for every SandboxConfig a WorkerPool's // status names when that WorkerPool changes. func (r *SandboxConfigProtectionReconciler) SetupWithManager(mgr ctrl.Manager) error { - if err := mgr.GetFieldIndexer().IndexField(context.Background(), &atev1alpha1.WorkerPool{}, workerPoolSandboxConfigIndex, + if err := mgr.GetFieldIndexer().IndexField(context.Background(), &atev1.WorkerPool{}, workerPoolSandboxConfigIndex, func(obj client.Object) []string { - wp, ok := obj.(*atev1alpha1.WorkerPool) + wp, ok := obj.(*atev1.WorkerPool) if !ok { return nil } @@ -143,13 +143,13 @@ func (r *SandboxConfigProtectionReconciler) SetupWithManager(mgr ctrl.Manager) e } return ctrl.NewControllerManagedBy(mgr). Named("sandboxconfig-protection"). - For(&atev1alpha1.SandboxConfig{}). + For(&atev1.SandboxConfig{}). // A config that is being deleted waits for the last pool that uses // it to go away. For an update, this runs for the old and the new // object, so the config a pool switches away from is reconciled too. - Watches(&atev1alpha1.WorkerPool{}, handler.EnqueueRequestsFromMapFunc( + Watches(&atev1.WorkerPool{}, handler.EnqueueRequestsFromMapFunc( func(_ context.Context, obj client.Object) []reconcile.Request { - wp, ok := obj.(*atev1alpha1.WorkerPool) + wp, ok := obj.(*atev1.WorkerPool) if !ok { return nil } diff --git a/cmd/atecontroller/internal/controllers/sandboxconfig_protection_controller_test.go b/cmd/atecontroller/internal/controllers/sandboxconfig_protection_controller_test.go index 0357664891..92b43c2ecf 100644 --- a/cmd/atecontroller/internal/controllers/sandboxconfig_protection_controller_test.go +++ b/cmd/atecontroller/internal/controllers/sandboxconfig_protection_controller_test.go @@ -29,7 +29,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/interceptor" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" ) // TestSandboxConfigProtectionReconcile checks that the reconciler never adds @@ -39,18 +39,18 @@ import ( func TestSandboxConfigProtectionReconcile(t *testing.T) { t.Parallel() scheme := runtime.NewScheme() - if err := atev1alpha1.AddToScheme(scheme); err != nil { + if err := atev1.AddToScheme(scheme); err != nil { t.Fatalf("add scheme: %v", err) } now := metav1.Now() // using returns a pool whose status has one sandbox class per name, each // using the named config, or no config when the name is "". - using := func(names ...string) *atev1alpha1.WorkerPool { + using := func(names ...string) *atev1.WorkerPool { wp := makeWorkerPool("pool", "default", 1, "worker:v1") for _, name := range names { - s := atev1alpha1.WorkerPoolSandboxClassStatus{Name: atev1alpha1.SandboxClassGvisor} + s := atev1.WorkerPoolSandboxClassStatus{Name: atev1.SandboxClassGvisor} if name != "" { - s.ConfigRef = &atev1alpha1.SandboxConfigReference{Name: name} + s.ConfigRef = &atev1.SandboxConfigReference{Name: name} } wp.Status.SandboxClasses = append(wp.Status.SandboxClasses, s) } @@ -58,18 +58,18 @@ func TestSandboxConfigProtectionReconcile(t *testing.T) { } // claiming returns a pool whose one sandbox class uses "other" and is // switching to the named config. - claiming := func(name string) *atev1alpha1.WorkerPool { + claiming := func(name string) *atev1.WorkerPool { wp := using("other") - wp.Status.SandboxClasses[0].PendingConfigRef = &atev1alpha1.SandboxConfigReference{Name: name} + wp.Status.SandboxClasses[0].PendingConfigRef = &atev1.SandboxConfigReference{Name: name} return wp } // config builds a SandboxConfig that has the protection finalizer if // protected. A deleting one carries another finalizer too, as the fake // client, like the API server, keeps no deleting object without one. - config := func(protected, deleting bool) *atev1alpha1.SandboxConfig { - sc := makeSandboxConfig("sc", atev1alpha1.SandboxClassGvisor, true) + config := func(protected, deleting bool) *atev1.SandboxConfig { + sc := makeSandboxConfig("sc", atev1.SandboxClassGvisor, true) if protected { - controllerutil.AddFinalizer(sc, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) + controllerutil.AddFinalizer(sc, atev1.SandboxConfigWorkerPoolProtectionFinalizer) } if deleting { controllerutil.AddFinalizer(sc, testHoldFinalizer) @@ -80,8 +80,8 @@ func TestSandboxConfigProtectionReconcile(t *testing.T) { // newClient returns a client whose List fails with listErr, if set. newClient := func(listErr error, objs ...client.Object) client.Client { return fake.NewClientBuilder().WithScheme(scheme).WithObjects(objs...). - WithIndex(&atev1alpha1.WorkerPool{}, workerPoolSandboxConfigIndex, func(obj client.Object) []string { - return sandboxConfigsInUse(obj.(*atev1alpha1.WorkerPool)) + WithIndex(&atev1.WorkerPool{}, workerPoolSandboxConfigIndex, func(obj client.Object) []string { + return sandboxConfigsInUse(obj.(*atev1.WorkerPool)) }). WithInterceptorFuncs(interceptor.Funcs{ List: func(ctx context.Context, c client.WithWatch, list client.ObjectList, opts ...client.ListOption) error { @@ -96,7 +96,7 @@ func TestSandboxConfigProtectionReconcile(t *testing.T) { tests := []struct { name string - sc *atev1alpha1.SandboxConfig + sc *atev1.SandboxConfig cached []client.Object live []client.Object // cachedErr and liveErr fail the cached and the live WorkerPool list. @@ -202,11 +202,11 @@ func TestSandboxConfigProtectionReconcile(t *testing.T) { if !errors.Is(err, tc.wantErr) { t.Fatalf("Reconcile error = %v, want %v", err, tc.wantErr) } - got := &atev1alpha1.SandboxConfig{} + got := &atev1.SandboxConfig{} if err := c.Get(t.Context(), types.NamespacedName{Name: tc.sc.Name}, got); err != nil { t.Fatalf("get SandboxConfig: %v", err) } - if has := controllerutil.ContainsFinalizer(got, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer); has != tc.want { + if has := controllerutil.ContainsFinalizer(got, atev1.SandboxConfigWorkerPoolProtectionFinalizer); has != tc.want { t.Errorf("has protection finalizer = %v, want %v", has, tc.want) } if controllerutil.ContainsFinalizer(tc.sc, testHoldFinalizer) && !controllerutil.ContainsFinalizer(got, testHoldFinalizer) { @@ -222,7 +222,7 @@ func TestSandboxConfigProtectionReconcile(t *testing.T) { func TestSandboxConfigProtectionReconcileGet(t *testing.T) { t.Parallel() scheme := runtime.NewScheme() - if err := atev1alpha1.AddToScheme(scheme); err != nil { + if err := atev1.AddToScheme(scheme); err != nil { t.Fatalf("add scheme: %v", err) } errGet := errors.New("get failed") @@ -270,8 +270,8 @@ func TestSandboxConfigProtectionReconcileGet(t *testing.T) { // addProtectionFinalizer or removeProtectionFinalizer to a SandboxConfig. type protectionFinalizerCase struct { name string - op func(context.Context, client.Client, *atev1alpha1.SandboxConfig) error - sc *atev1alpha1.SandboxConfig + op func(context.Context, client.Client, *atev1.SandboxConfig) error + sc *atev1.SandboxConfig // stale changes the stored config after it is read, so the patch // carries an outdated resourceVersion. stale bool @@ -283,11 +283,11 @@ type protectionFinalizerCase struct { // protectedSandboxConfig builds a SandboxConfig for a protectionFinalizerCase. // It always carries testHoldFinalizer, so it stays readable while deleting, // and the protection finalizer if protected. -func protectedSandboxConfig(protected, deleting bool) *atev1alpha1.SandboxConfig { - sc := makeSandboxConfig("sc", atev1alpha1.SandboxClassGvisor, false) +func protectedSandboxConfig(protected, deleting bool) *atev1.SandboxConfig { + sc := makeSandboxConfig("sc", atev1.SandboxClassGvisor, false) controllerutil.AddFinalizer(sc, testHoldFinalizer) if protected { - controllerutil.AddFinalizer(sc, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) + controllerutil.AddFinalizer(sc, atev1.SandboxConfigWorkerPoolProtectionFinalizer) } if deleting { now := metav1.Now() @@ -302,7 +302,7 @@ func protectedSandboxConfig(protected, deleting bool) *atev1alpha1.SandboxConfig func runProtectionFinalizerCases(t *testing.T, tests []protectionFinalizerCase) { t.Helper() scheme := runtime.NewScheme() - if err := atev1alpha1.AddToScheme(scheme); err != nil { + if err := atev1.AddToScheme(scheme); err != nil { t.Fatalf("add scheme: %v", err) } for _, tc := range tests { @@ -317,7 +317,7 @@ func runProtectionFinalizerCases(t *testing.T, tests []protectionFinalizerCase) }, }).Build() key := types.NamespacedName{Name: tc.sc.Name} - read := &atev1alpha1.SandboxConfig{} + read := &atev1.SandboxConfig{} if err := c.Get(t.Context(), key, read); err != nil { t.Fatalf("get SandboxConfig: %v", err) } @@ -339,11 +339,11 @@ func runProtectionFinalizerCases(t *testing.T, tests []protectionFinalizerCase) if patches != tc.wantPatches { t.Errorf("patches = %d, want %d", patches, tc.wantPatches) } - got := &atev1alpha1.SandboxConfig{} + got := &atev1.SandboxConfig{} if err := c.Get(t.Context(), key, got); err != nil { t.Fatalf("get SandboxConfig: %v", err) } - if has := controllerutil.ContainsFinalizer(got, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer); has != tc.want { + if has := controllerutil.ContainsFinalizer(got, atev1.SandboxConfigWorkerPoolProtectionFinalizer); has != tc.want { t.Errorf("has protection finalizer = %v, want %v", has, tc.want) } if !controllerutil.ContainsFinalizer(got, testHoldFinalizer) { diff --git a/cmd/atecontroller/internal/controllers/workerpool_apply.go b/cmd/atecontroller/internal/controllers/workerpool_apply.go index 8be68e8c28..a4b41798ab 100644 --- a/cmd/atecontroller/internal/controllers/workerpool_apply.go +++ b/cmd/atecontroller/internal/controllers/workerpool_apply.go @@ -26,12 +26,12 @@ import ( corev1ac "k8s.io/client-go/applyconfigurations/core/v1" metav1ac "k8s.io/client-go/applyconfigurations/meta/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/deviceplugin" "go.ate.dev/substrate/internal/installdefaults" "go.ate.dev/substrate/internal/nodepath" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/workercapacity" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" ) // workerOTelResourceAttributes mirrors atelet.yaml; service.instance.id is the pod @@ -108,7 +108,7 @@ const ( // Deployment managed by a WorkerPool. Only fields owned by this controller // are declared here. otel is propagated to the worker container (see // workerContainerEnv). -func buildDeploymentApplyConfig(wp *atev1alpha1.WorkerPool, otel workerOTelSettings, systemNamespace, ateletServiceAccount, routerServiceAccount, dnsEgressPolicy string) *appsv1ac.DeploymentApplyConfiguration { +func buildDeploymentApplyConfig(wp *atev1.WorkerPool, otel workerOTelSettings, systemNamespace, ateletServiceAccount, routerServiceAccount, dnsEgressPolicy string) *appsv1ac.DeploymentApplyConfiguration { labels := map[string]string{} annotations := map[string]string{} if wp.Spec.Template != nil { @@ -267,7 +267,7 @@ func buildDeploymentApplyConfig(wp *atev1alpha1.WorkerPool, otel workerOTelSetti WithLabels(labels). WithAnnotations(annotations). WithOwnerReferences(metav1ac.OwnerReference(). - WithAPIVersion(atev1alpha1.GroupVersion.String()). + WithAPIVersion(atev1.GroupVersion.String()). WithKind("WorkerPool"). WithName(wp.Name). WithUID(wp.UID). @@ -406,7 +406,7 @@ var workerMicroVMCapabilities = slices.Concat(workerGvisorCapabilities, []corev1 // class. Neither class runs privileged; they differ in their capability set. // Both declare seccomp Unconfined because their sandbox child pivot_root()s, // which the default profile denies. An empty class defaults to gVisor. -func workerSecurityContext(class atev1alpha1.SandboxClass) *corev1ac.SecurityContextApplyConfiguration { +func workerSecurityContext(class atev1.SandboxClass) *corev1ac.SecurityContextApplyConfiguration { // Both runtimes mount inside the worker — runsc pivots root and the worker // remounts /sys/fs/cgroup to nest per-actor cgroups; the micro-VM worker // shares /run/kata-containers and remounts /proc/sys — and the default @@ -421,7 +421,7 @@ func workerSecurityContext(class atev1alpha1.SandboxClass) *corev1ac.SecurityCon WithAppArmorProfile(corev1ac.AppArmorProfile(). WithType(corev1.AppArmorProfileTypeUnconfined)) - if class == atev1alpha1.SandboxClassMicroVM { + if class == atev1.SandboxClassMicroVM { // Give up the default seccomp profile so virtiofsd keeps its own sandbox, // which pivot_root()s — a syscall the profile denies whatever capabilities // the worker holds. The trade favors containing the guest: virtiofsd parses @@ -462,9 +462,9 @@ func workerSecurityContext(class atev1alpha1.SandboxClass) *corev1ac.SecurityCon func maybeApplyMicroVMPodShape( podSpecAC *corev1ac.PodSpecApplyConfiguration, containerAC *corev1ac.ContainerApplyConfiguration, - sandboxClass atev1alpha1.SandboxClass, + sandboxClass atev1.SandboxClass, ) { - if sandboxClass != atev1alpha1.SandboxClassMicroVM { + if sandboxClass != atev1.SandboxClassMicroVM { return } @@ -528,10 +528,10 @@ const sandboxClassTaintKey = "ate.dev/sandboxClass" // which is what the CRD's defaulting produces on the server. func applySandboxClassToleration( podSpecAC *corev1ac.PodSpecApplyConfiguration, - sandboxClass atev1alpha1.SandboxClass, + sandboxClass atev1.SandboxClass, ) { if sandboxClass == "" { - sandboxClass = atev1alpha1.SandboxClassGvisor + sandboxClass = atev1.SandboxClassGvisor } podSpecAC.WithTolerations(corev1ac.Toleration(). WithKey(sandboxClassTaintKey). @@ -565,7 +565,7 @@ func addDeviceResourceLimits(containerAC *corev1ac.ContainerApplyConfiguration, func applyWorkerPoolPodTemplate( podSpecAC *corev1ac.PodSpecApplyConfiguration, containerAC *corev1ac.ContainerApplyConfiguration, - tmpl *atev1alpha1.WorkerPoolPodTemplate, + tmpl *atev1.WorkerPoolPodTemplate, ) { podSpecAC.NodeSelector = map[string]string{} podSpecAC.Tolerations = []corev1ac.TolerationApplyConfiguration{} diff --git a/cmd/atecontroller/internal/controllers/workerpool_apply_test.go b/cmd/atecontroller/internal/controllers/workerpool_apply_test.go index af9780948d..20907c4393 100644 --- a/cmd/atecontroller/internal/controllers/workerpool_apply_test.go +++ b/cmd/atecontroller/internal/controllers/workerpool_apply_test.go @@ -30,13 +30,13 @@ import ( metav1ac "k8s.io/client-go/applyconfigurations/meta/v1" "k8s.io/utils/ptr" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/deviceplugin" "go.ate.dev/substrate/internal/egresspolicy" "go.ate.dev/substrate/internal/installdefaults" "go.ate.dev/substrate/internal/nodepath" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/workercapacity" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" ) func TestBuildDeploymentApplyConfig(t *testing.T) { @@ -74,7 +74,7 @@ func TestBuildDeploymentApplyConfig(t *testing.T) { tests := []struct { name string - wp *atev1alpha1.WorkerPool + wp *atev1.WorkerPool want *appsv1ac.DeploymentApplyConfiguration }{ { @@ -84,7 +84,7 @@ func TestBuildDeploymentApplyConfig(t *testing.T) { }, { name: "with node selector", - wp: testWorkerPoolApplyConfig(&atev1alpha1.WorkerPoolPodTemplate{ + wp: testWorkerPoolApplyConfig(&atev1.WorkerPoolPodTemplate{ NodeSelector: map[string]string{ "accelerator": "gpu", "topology": "high-mem", @@ -99,7 +99,7 @@ func TestBuildDeploymentApplyConfig(t *testing.T) { }, { name: "with tolerations", - wp: testWorkerPoolApplyConfig(&atev1alpha1.WorkerPoolPodTemplate{ + wp: testWorkerPoolApplyConfig(&atev1.WorkerPoolPodTemplate{ Tolerations: []corev1.Toleration{toleration}, }), want: expectedDeploymentApplyConfig(func(podSpecAC *corev1ac.PodSpecApplyConfiguration) { @@ -112,13 +112,13 @@ func TestBuildDeploymentApplyConfig(t *testing.T) { WithValue("workerpool"). WithEffect(corev1.TaintEffectNoSchedule). WithTolerationSeconds(300), - sandboxClassTolerationAC(atev1alpha1.SandboxClassGvisor), + sandboxClassTolerationAC(atev1.SandboxClassGvisor), } }), }, { name: "with node affinity", - wp: testWorkerPoolApplyConfig(&atev1alpha1.WorkerPoolPodTemplate{ + wp: testWorkerPoolApplyConfig(&atev1.WorkerPoolPodTemplate{ NodeAffinity: requiredNodeAffinity, }), want: expectedDeploymentApplyConfig(func(podSpecAC *corev1ac.PodSpecApplyConfiguration) { @@ -138,7 +138,7 @@ func TestBuildDeploymentApplyConfig(t *testing.T) { }, { name: "with priority class name", - wp: testWorkerPoolApplyConfig(&atev1alpha1.WorkerPoolPodTemplate{ + wp: testWorkerPoolApplyConfig(&atev1.WorkerPoolPodTemplate{ PriorityClassName: "interactive-workerpool", }), want: expectedDeploymentApplyConfig(func(podSpecAC *corev1ac.PodSpecApplyConfiguration) { @@ -147,7 +147,7 @@ func TestBuildDeploymentApplyConfig(t *testing.T) { }, { name: "with service account name", - wp: testWorkerPoolApplyConfig(&atev1alpha1.WorkerPoolPodTemplate{ + wp: testWorkerPoolApplyConfig(&atev1.WorkerPoolPodTemplate{ ServiceAccountName: ptr.To("substrate-worker"), }), want: expectedDeploymentApplyConfig(func(podSpecAC *corev1ac.PodSpecApplyConfiguration) { @@ -156,7 +156,7 @@ func TestBuildDeploymentApplyConfig(t *testing.T) { }, { name: "with resources", - wp: testWorkerPoolApplyConfig(&atev1alpha1.WorkerPoolPodTemplate{ + wp: testWorkerPoolApplyConfig(&atev1.WorkerPoolPodTemplate{ Resources: &corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("500m"), @@ -182,7 +182,7 @@ func TestBuildDeploymentApplyConfig(t *testing.T) { }, { name: "with combined scheduling fields", - wp: testWorkerPoolApplyConfig(&atev1alpha1.WorkerPoolPodTemplate{ + wp: testWorkerPoolApplyConfig(&atev1.WorkerPoolPodTemplate{ NodeSelector: map[string]string{ "accelerator": "gpu", "topology": "high-mem", @@ -203,7 +203,7 @@ func TestBuildDeploymentApplyConfig(t *testing.T) { WithValue("workerpool"). WithEffect(corev1.TaintEffectNoSchedule). WithTolerationSeconds(300), - sandboxClassTolerationAC(atev1alpha1.SandboxClassGvisor), + sandboxClassTolerationAC(atev1.SandboxClassGvisor), } podSpecAC.WithPriorityClassName("interactive-workerpool") podSpecAC.WithAffinity(corev1ac.Affinity().WithNodeAffinity( @@ -233,8 +233,8 @@ func TestBuildDeploymentApplyConfig(t *testing.T) { } func TestBuildDeploymentApplyConfigMetadata(t *testing.T) { - wp := testWorkerPoolApplyConfig(&atev1alpha1.WorkerPoolPodTemplate{ - Labels: map[string]atev1alpha1.WorkerPoolLabelValue{ + wp := testWorkerPoolApplyConfig(&atev1.WorkerPoolPodTemplate{ + Labels: map[string]atev1.WorkerPoolLabelValue{ "project": "agent-substrate", "team": "compute", "ate.dev/worker-pool": "incorrect", @@ -270,7 +270,7 @@ func TestBuildDeploymentApplyConfigMetadata(t *testing.T) { // sandboxClassTolerationAC is the toleration applySandboxClassToleration adds // for class, in apply-configuration form for cmp against built pod specs. -func sandboxClassTolerationAC(class atev1alpha1.SandboxClass) corev1ac.TolerationApplyConfiguration { +func sandboxClassTolerationAC(class atev1.SandboxClass) corev1ac.TolerationApplyConfiguration { return *corev1ac.Toleration(). WithKey(sandboxClassTaintKey). WithOperator(corev1.TolerationOpEqual). @@ -285,23 +285,23 @@ func sandboxClassTolerationAC(class atev1alpha1.SandboxClass) corev1ac.Toleratio func TestSandboxClassToleration(t *testing.T) { tests := []struct { name string - class atev1alpha1.SandboxClass + class atev1.SandboxClass want string }{ {"gvisor default", "", "gvisor"}, - {"gvisor explicit", atev1alpha1.SandboxClassGvisor, "gvisor"}, - {"microvm", atev1alpha1.SandboxClassMicroVM, "microvm"}, + {"gvisor explicit", atev1.SandboxClassGvisor, "gvisor"}, + {"microvm", atev1.SandboxClassMicroVM, "microvm"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - wp := testWorkerPoolApplyConfig(&atev1alpha1.WorkerPoolPodTemplate{ + wp := testWorkerPoolApplyConfig(&atev1.WorkerPoolPodTemplate{ Tolerations: []corev1.Toleration{{ Key: "dedicated", Operator: corev1.TolerationOpExists, Effect: corev1.TaintEffectNoSchedule, }}, }) - wp.Spec.SandboxClasses = []atev1alpha1.WorkerPoolSandboxClass{{Name: tt.class}} + wp.Spec.SandboxClasses = []atev1.WorkerPoolSandboxClass{{Name: tt.class}} ps := buildDeploymentApplyConfig(wp, workerOTelSettings{}, installdefaults.SystemNamespace, installdefaults.AteletServiceAccount, installdefaults.RouterServiceAccount, egresspolicy.DNSEgressPolicyEnforceInAtunnel).Spec.Template.Spec var classValues []string @@ -339,17 +339,17 @@ func TestSandboxClassToleration(t *testing.T) { func TestMicroVMPodShape(t *testing.T) { tests := []struct { name string - class atev1alpha1.SandboxClass + class atev1.SandboxClass wantMicroVM bool }{ {"gvisor default", "", false}, - {"gvisor explicit", atev1alpha1.SandboxClassGvisor, false}, - {"microvm", atev1alpha1.SandboxClassMicroVM, true}, + {"gvisor explicit", atev1.SandboxClassGvisor, false}, + {"microvm", atev1.SandboxClassMicroVM, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { wp := testWorkerPoolApplyConfig(nil) - wp.Spec.SandboxClasses = []atev1alpha1.WorkerPoolSandboxClass{{Name: tt.class}} + wp.Spec.SandboxClasses = []atev1.WorkerPoolSandboxClass{{Name: tt.class}} ps := buildDeploymentApplyConfig(wp, workerOTelSettings{}, installdefaults.SystemNamespace, installdefaults.AteletServiceAccount, installdefaults.RouterServiceAccount, egresspolicy.DNSEgressPolicyEnforceInAtunnel).Spec.Template.Spec // /dev/kvm must come from the device plugin, never a hostPath: a @@ -431,12 +431,12 @@ func deviceLimit(c corev1ac.ContainerApplyConfiguration, name string) (string, b // A pod template's own resource limits must survive the device requests being // merged in. func TestMicroVMDeviceRequestsPreserveTemplateResources(t *testing.T) { - wp := testWorkerPoolApplyConfig(&atev1alpha1.WorkerPoolPodTemplate{ + wp := testWorkerPoolApplyConfig(&atev1.WorkerPoolPodTemplate{ Resources: &corev1.ResourceRequirements{ Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, }, }) - wp.Spec.SandboxClasses = []atev1alpha1.WorkerPoolSandboxClass{{Name: atev1alpha1.SandboxClassMicroVM}} + wp.Spec.SandboxClasses = []atev1.WorkerPoolSandboxClass{{Name: atev1.SandboxClassMicroVM}} c := buildDeploymentApplyConfig(wp, workerOTelSettings{}, installdefaults.SystemNamespace, installdefaults.AteletServiceAccount, installdefaults.RouterServiceAccount, egresspolicy.DNSEgressPolicyEnforceInAtunnel).Spec.Template.Spec.Containers[0] if got, ok := deviceLimit(c, string(corev1.ResourceMemory)); !ok || got != "2Gi" { @@ -454,15 +454,15 @@ func TestMicroVMDeviceRequestsPreserveTemplateResources(t *testing.T) { func TestWorkerSecurityContextByClass(t *testing.T) { tests := []struct { name string - class atev1alpha1.SandboxClass + class atev1.SandboxClass wantCaps []corev1.Capability // wantSeccompUnconfined holds for every class: both runsc's and // virtiofsd's sandbox pivot_root(), which the default profile denies. wantSeccompUnconfined bool }{ {"gvisor default", "", workerGvisorCapabilities, true}, - {"gvisor explicit", atev1alpha1.SandboxClassGvisor, workerGvisorCapabilities, true}, - {"microvm", atev1alpha1.SandboxClassMicroVM, workerMicroVMCapabilities, true}, + {"gvisor explicit", atev1.SandboxClassGvisor, workerGvisorCapabilities, true}, + {"microvm", atev1.SandboxClassMicroVM, workerMicroVMCapabilities, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -808,10 +808,10 @@ func envByName(env []corev1ac.EnvVarApplyConfiguration) map[string]envInfo { return m } -func testWorkerPoolApplyConfig(tmpl *atev1alpha1.WorkerPoolPodTemplate) *atev1alpha1.WorkerPool { - return &atev1alpha1.WorkerPool{ +func testWorkerPoolApplyConfig(tmpl *atev1.WorkerPoolPodTemplate) *atev1.WorkerPool { + return &atev1.WorkerPool{ ObjectMeta: metav1.ObjectMeta{Name: "pool", Namespace: "default", UID: "uid"}, - Spec: atev1alpha1.WorkerPoolSpec{ + Spec: atev1.WorkerPoolSpec{ Replicas: 2, WorkerImage: "worker:v1", Template: tmpl, @@ -969,7 +969,7 @@ func expectedDeploymentApplyConfig(mutatePodSpec func(*corev1ac.PodSpecApplyConf podSpecAC.NodeSelector = map[string]string{} podSpecAC.Tolerations = []corev1ac.TolerationApplyConfiguration{ - sandboxClassTolerationAC(atev1alpha1.SandboxClassGvisor), + sandboxClassTolerationAC(atev1.SandboxClassGvisor), } podSpecAC.WithPriorityClassName("") podSpecAC.WithServiceAccountName("ateworker") @@ -982,7 +982,7 @@ func expectedDeploymentApplyConfig(mutatePodSpec func(*corev1ac.PodSpecApplyConf return appsv1ac.Deployment(wp.Name, wp.Namespace). WithLabels(map[string]string{"ate.dev/worker-pool": wp.Name}). WithOwnerReferences(metav1ac.OwnerReference(). - WithAPIVersion(atev1alpha1.GroupVersion.String()). + WithAPIVersion(atev1.GroupVersion.String()). WithKind("WorkerPool"). WithName(wp.Name). WithUID(wp.UID). diff --git a/cmd/atecontroller/internal/controllers/workerpool_controller.go b/cmd/atecontroller/internal/controllers/workerpool_controller.go index cb654cd987..0ccd5febfd 100644 --- a/cmd/atecontroller/internal/controllers/workerpool_controller.go +++ b/cmd/atecontroller/internal/controllers/workerpool_controller.go @@ -38,9 +38,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/installdefaults" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" ) const ( @@ -115,7 +115,7 @@ func (r *WorkerPoolReconciler) Reconcile(ctx context.Context, req ctrl.Request) log := log.FromContext(ctx) // Fetch worker pool - wp := &atev1alpha1.WorkerPool{} + wp := &atev1.WorkerPool{} if err := r.Get(ctx, req.NamespacedName, wp); err != nil { if k8errors.IsNotFound(err) { return ctrl.Result{}, nil @@ -159,7 +159,7 @@ func (r *WorkerPoolReconciler) Reconcile(ctx context.Context, req ctrl.Request) // released this config, it listed the pools before step 2 wrote the claim. // The config was already being deleted then, so the read in step 3 sees the // deletion and the class does not switch. -func (r *WorkerPoolReconciler) reconcileWorkerPool(ctx context.Context, wp *atev1alpha1.WorkerPool) error { +func (r *WorkerPoolReconciler) reconcileWorkerPool(ctx context.Context, wp *atev1.WorkerPool) error { log := log.FromContext(ctx) log.Info("Reconciling worker pool") @@ -179,7 +179,7 @@ func (r *WorkerPoolReconciler) reconcileWorkerPool(ctx context.Context, wp *atev } } - var list atev1alpha1.SandboxConfigList + var list atev1.SandboxConfigList if err := r.List(ctx, &list); err != nil { return fmt.Errorf("failed to list SandboxConfigs: %w", err) } @@ -214,7 +214,7 @@ func (r *WorkerPoolReconciler) reconcileWorkerPool(ctx context.Context, wp *atev // everyClassHasConfig reports whether every class in classes has a // SandboxConfig, either resolved now or kept from before. -func everyClassHasConfig(classes []atev1alpha1.WorkerPoolSandboxClassStatus) bool { +func everyClassHasConfig(classes []atev1.WorkerPoolSandboxClassStatus) bool { for _, c := range classes { if c.ConfigRef == nil { return false @@ -230,12 +230,12 @@ func everyClassHasConfig(classes []atev1alpha1.WorkerPoolSandboxClassStatus) boo // ever used has no finalizer and is deleted right away. A config that was // deleted after the cached read is caught later, when reconcileWorkerPool // confirms it against the API server. -func protectSandboxConfigs(ctx context.Context, c client.Client, classes []atev1alpha1.WorkerPoolSandboxClassStatus, configs []atev1alpha1.SandboxConfig) error { +func protectSandboxConfigs(ctx context.Context, c client.Client, classes []atev1.WorkerPoolSandboxClassStatus, configs []atev1.SandboxConfig) error { for _, class := range classes { if class.ConfigRef == nil { continue } - i := slices.IndexFunc(configs, func(sc atev1alpha1.SandboxConfig) bool { return sc.Name == class.ConfigRef.Name }) + i := slices.IndexFunc(configs, func(sc atev1.SandboxConfig) bool { return sc.Name == class.ConfigRef.Name }) if i < 0 { return fmt.Errorf("resolved SandboxConfig %q is not in the list it was resolved from", class.ConfigRef.Name) } @@ -251,12 +251,12 @@ func protectSandboxConfigs(ctx context.Context, c client.Client, classes []atev1 // config is left alone. The patch carries sc's resourceVersion, so a // concurrent change to the config fails with a conflict and the reconcile is // retried. -func addProtectionFinalizer(ctx context.Context, c client.Client, sc *atev1alpha1.SandboxConfig) error { - if controllerutil.ContainsFinalizer(sc, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) || !sc.DeletionTimestamp.IsZero() { +func addProtectionFinalizer(ctx context.Context, c client.Client, sc *atev1.SandboxConfig) error { + if controllerutil.ContainsFinalizer(sc, atev1.SandboxConfigWorkerPoolProtectionFinalizer) || !sc.DeletionTimestamp.IsZero() { return nil } orig := sc.DeepCopy() - controllerutil.AddFinalizer(sc, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) + controllerutil.AddFinalizer(sc, atev1.SandboxConfigWorkerPoolProtectionFinalizer) if err := c.Patch(ctx, sc, client.MergeFromWithOptions(orig, client.MergeFromWithOptimisticLock{})); err != nil { return fmt.Errorf("failed to update finalizers of SandboxConfig %q: %w", sc.Name, err) } @@ -268,12 +268,12 @@ func addProtectionFinalizer(ctx context.Context, c client.Client, sc *atev1alpha // to another class, or is being deleted gets an entry that keeps the config in // use instead. wp's status must already claim the new configs. See // reconcileWorkerPool. -func (r *WorkerPoolReconciler) confirmSandboxConfigSwitches(ctx context.Context, wp *atev1alpha1.WorkerPool, classes []atev1alpha1.WorkerPoolSandboxClassStatus, configs []atev1alpha1.SandboxConfig) error { +func (r *WorkerPoolReconciler) confirmSandboxConfigSwitches(ctx context.Context, wp *atev1.WorkerPool, classes []atev1.WorkerPoolSandboxClassStatus, configs []atev1.SandboxConfig) error { for i, class := range classes { if !switchesSandboxConfig(wp, class) { continue } - live := &atev1alpha1.SandboxConfig{} + live := &atev1.SandboxConfig{} if err := r.APIReader.Get(ctx, client.ObjectKey{Name: class.ConfigRef.Name}, live); err != nil { if !k8errors.IsNotFound(err) { return fmt.Errorf("failed to get SandboxConfig %q: %w", class.ConfigRef.Name, err) @@ -300,7 +300,7 @@ func (r *WorkerPoolReconciler) confirmSandboxConfigSwitches(ctx context.Context, // copy of the pool sees the switch a second time. The reconcile that a claim // write triggers often does. Its status write fails on the resourceVersion // before it gets here, so the switch is reported once. -func (r *WorkerPoolReconciler) recordSandboxConfigEvents(wp *atev1alpha1.WorkerPool, prev, classes []atev1alpha1.WorkerPoolSandboxClassStatus) { +func (r *WorkerPoolReconciler) recordSandboxConfigEvents(wp *atev1.WorkerPool, prev, classes []atev1.WorkerPoolSandboxClassStatus) { for _, class := range classes { if switchesSandboxConfigFrom(prev, class) { if prev := findSandboxClassStatus(prev, class.Name); prev != nil && prev.ConfigRef != nil { @@ -311,7 +311,7 @@ func (r *WorkerPoolReconciler) recordSandboxConfigEvents(wp *atev1alpha1.WorkerP "sandbox class %q uses SandboxConfig %q", class.Name, class.ConfigRef.Name) } } - cond := meta.FindStatusCondition(class.Conditions, atev1alpha1.WorkerPoolSandboxClassConditionResolved) + cond := meta.FindStatusCondition(class.Conditions, atev1.WorkerPoolSandboxClassConditionResolved) if cond == nil || cond.Status == metav1.ConditionTrue { continue } @@ -325,7 +325,7 @@ func (r *WorkerPoolReconciler) recordSandboxConfigEvents(wp *atev1alpha1.WorkerP } } -func (r *WorkerPoolReconciler) applyDeployment(ctx context.Context, wp *atev1alpha1.WorkerPool) error { +func (r *WorkerPoolReconciler) applyDeployment(ctx context.Context, wp *atev1.WorkerPool) error { if wp.Spec.Template == nil || wp.Spec.Template.ServiceAccountName == nil { if err := r.applyWorkerServiceAccount(ctx, wp.Namespace); err != nil { return err @@ -359,7 +359,7 @@ func (r *WorkerPoolReconciler) applyWorkerServiceAccount(ctx context.Context, na // syncStatus writes wp's status: replica counts and selector from dep (left // as they are when dep is nil) and sandboxClasses from classes. -func (r *WorkerPoolReconciler) syncStatus(ctx context.Context, wp *atev1alpha1.WorkerPool, dep *appsv1.Deployment, classes []atev1alpha1.WorkerPoolSandboxClassStatus) error { +func (r *WorkerPoolReconciler) syncStatus(ctx context.Context, wp *atev1.WorkerPool, dep *appsv1.Deployment, classes []atev1.WorkerPoolSandboxClassStatus) error { want := wp.Status.DeepCopy() if dep != nil { selector, err := metav1.LabelSelectorAsSelector(dep.Spec.Selector) @@ -408,7 +408,7 @@ func (r *WorkerPoolReconciler) InitMetrics(meter metric.Meter) error { _, err = meter.RegisterCallback( func(ctx context.Context, obs metric.Observer) error { - var list atev1alpha1.WorkerPoolList + var list atev1.WorkerPoolList if err := r.List(ctx, &list); err != nil { log.FromContext(ctx).Error(err, "failed to list worker pools to observe ate.workerpool.desired_workers and ate.workerpool.ready_workers") return nil @@ -444,9 +444,9 @@ func (r *WorkerPoolReconciler) SetupWithManager(mgr ctrl.Manager) error { return fmt.Errorf("failed to initialize workerpool metrics: %w", err) } return ctrl.NewControllerManagedBy(mgr). - For(&atev1alpha1.WorkerPool{}). + For(&atev1.WorkerPool{}). Owns(&appsv1.Deployment{}). - Watches(&atev1alpha1.SandboxConfig{}, handler.EnqueueRequestsFromMapFunc(r.workerPoolsForSandboxConfig)). + Watches(&atev1.SandboxConfig{}, handler.EnqueueRequestsFromMapFunc(r.workerPoolsForSandboxConfig)). Complete(r) } @@ -455,11 +455,11 @@ func (r *WorkerPoolReconciler) SetupWithManager(mgr ctrl.Manager) error { // class, because the config may become or stop being their default, and the // pools whose spec or status names it. func (r *WorkerPoolReconciler) workerPoolsForSandboxConfig(ctx context.Context, obj client.Object) []reconcile.Request { - sc, ok := obj.(*atev1alpha1.SandboxConfig) + sc, ok := obj.(*atev1.SandboxConfig) if !ok { return nil } - var pools atev1alpha1.WorkerPoolList + var pools atev1.WorkerPoolList if err := r.List(ctx, &pools); err != nil { log.FromContext(ctx).Error(err, "failed to list worker pools for SandboxConfig", "sandboxConfig", sc.Name) return nil @@ -474,7 +474,7 @@ func (r *WorkerPoolReconciler) workerPoolsForSandboxConfig(ctx context.Context, return reqs } -func workerPoolMayUseSandboxConfig(wp *atev1alpha1.WorkerPool, sc *atev1alpha1.SandboxConfig) bool { +func workerPoolMayUseSandboxConfig(wp *atev1.WorkerPool, sc *atev1.SandboxConfig) bool { for _, entry := range wp.Spec.SandboxClasses { if entry.Name == sc.Spec.SandboxClass || (entry.ConfigRef != nil && entry.ConfigRef.Name == sc.Name) { return true diff --git a/cmd/atecontroller/internal/controllers/workerpool_controller_test.go b/cmd/atecontroller/internal/controllers/workerpool_controller_test.go index 4760d13f5e..38395829d6 100644 --- a/cmd/atecontroller/internal/controllers/workerpool_controller_test.go +++ b/cmd/atecontroller/internal/controllers/workerpool_controller_test.go @@ -43,10 +43,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/installdefaults" "go.ate.dev/substrate/internal/testenv" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" ) var ( @@ -60,7 +60,7 @@ func TestMain(m *testing.M) { scheme := runtime.NewScheme() utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(atev1alpha1.AddToScheme(scheme)) + utilruntime.Must(atev1.AddToScheme(scheme)) var err error k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) @@ -99,7 +99,7 @@ func TestMain(m *testing.M) { // makeWorkerPool omits configRef, so every gvisor pool resolves to this // class default. Tests that need to control the class default use microvm. - if err := k8sClient.Create(context.Background(), makeSandboxConfig(testGvisorDefault, atev1alpha1.SandboxClassGvisor, true)); err != nil { + if err := k8sClient.Create(context.Background(), makeSandboxConfig(testGvisorDefault, atev1.SandboxClassGvisor, true)); err != nil { fmt.Fprintf(os.Stderr, "create default SandboxConfig: %v\n", err) os.Exit(1) } @@ -181,7 +181,7 @@ func TestWorkerPoolReplicasUpdate(t *testing.T) { return err == nil, nil }) - updateWorkerPoolSpec(t, ctx, wp, "update WorkerPool replicas", func(current *atev1alpha1.WorkerPool) { + updateWorkerPoolSpec(t, ctx, wp, "update WorkerPool replicas", func(current *atev1.WorkerPool) { current.Spec.Replicas = 5 }) @@ -210,7 +210,7 @@ func TestWorkerPoolImageUpdate(t *testing.T) { return err == nil, nil }) - updateWorkerPoolSpec(t, ctx, wp, "update WorkerPool image", func(current *atev1alpha1.WorkerPool) { + updateWorkerPoolSpec(t, ctx, wp, "update WorkerPool image", func(current *atev1.WorkerPool) { current.Spec.WorkerImage = "worker:v2" }) @@ -343,7 +343,7 @@ func TestStatusReplicasPropagation(t *testing.T) { }) eventually(t, func(ctx context.Context) (bool, error) { - current := &atev1alpha1.WorkerPool{} + current := &atev1.WorkerPool{} if err := k8sClient.Get(ctx, types.NamespacedName{Name: wp.Name, Namespace: wp.Namespace}, current); err != nil { return false, nil } @@ -354,8 +354,8 @@ func TestStatusReplicasPropagation(t *testing.T) { }) } -func sampleWorkerPoolPodTemplate() *atev1alpha1.WorkerPoolPodTemplate { - return &atev1alpha1.WorkerPoolPodTemplate{ +func sampleWorkerPoolPodTemplate() *atev1.WorkerPoolPodTemplate { + return &atev1.WorkerPoolPodTemplate{ NodeSelector: map[string]string{ "workload": "substrate", }, @@ -431,7 +431,7 @@ func TestWorkerPoolWithServiceAccountSkipsDefault(t *testing.T) { t.Fatalf("create namespace: %v", err) } wp := makeWorkerPool("test-custom-sa", ns.Name, 1, "worker:v1") - wp.Spec.Template = &atev1alpha1.WorkerPoolPodTemplate{ServiceAccountName: ptr.To("substrate-worker")} + wp.Spec.Template = &atev1.WorkerPoolPodTemplate{ServiceAccountName: ptr.To("substrate-worker")} if err := k8sClient.Create(ctx, wp); err != nil { t.Fatalf("create WorkerPool: %v", err) } @@ -517,7 +517,7 @@ func TestWorkerPoolPodTemplateUpdate(t *testing.T) { return err == nil && dep.Spec.Template.Spec.NodeSelector["workload"] == "substrate", nil }) - updateWorkerPoolSpec(t, ctx, wp, "update WorkerPool template", func(current *atev1alpha1.WorkerPool) { + updateWorkerPoolSpec(t, ctx, wp, "update WorkerPool template", func(current *atev1.WorkerPool) { current.Spec.Template.NodeSelector = map[string]string{"workload": "updated"} }) @@ -549,7 +549,7 @@ func TestWorkerPoolPodTemplateClear(t *testing.T) { return err == nil && dep.Spec.Template.Spec.NodeSelector["workload"] == "substrate", nil }) - updateWorkerPoolSpec(t, ctx, wp, "clear WorkerPool nodeSelector", func(current *atev1alpha1.WorkerPool) { + updateWorkerPoolSpec(t, ctx, wp, "clear WorkerPool nodeSelector", func(current *atev1.WorkerPool) { current.Spec.Template.NodeSelector = nil }) @@ -591,7 +591,7 @@ func TestWorkerPoolPodTemplateClearAll(t *testing.T) { container.Resources.Requests.Cpu().String() == "500m", nil }) - updateWorkerPoolSpec(t, ctx, wp, "clear WorkerPool template", func(current *atev1alpha1.WorkerPool) { + updateWorkerPoolSpec(t, ctx, wp, "clear WorkerPool template", func(current *atev1.WorkerPool) { current.Spec.Template = nil }) @@ -663,13 +663,13 @@ func TestReplicasValidationRejectsNegative(t *testing.T) { // --- helpers --- -func makeWorkerPool(name, ns string, replicas int32, image string) *atev1alpha1.WorkerPool { - return &atev1alpha1.WorkerPool{ +func makeWorkerPool(name, ns string, replicas int32, image string) *atev1.WorkerPool { + return &atev1.WorkerPool{ ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: ns}, - Spec: atev1alpha1.WorkerPoolSpec{ + Spec: atev1.WorkerPoolSpec{ Replicas: replicas, WorkerImage: image, - SandboxClasses: []atev1alpha1.WorkerPoolSandboxClass{{Name: atev1alpha1.SandboxClassGvisor}}, + SandboxClasses: []atev1.WorkerPoolSandboxClass{{Name: atev1.SandboxClassGvisor}}, }, } } @@ -687,7 +687,7 @@ func deleteOnCleanup(t *testing.T, obj client.Object) { }) } -func getDeployment(ctx context.Context, wp *atev1alpha1.WorkerPool) (*appsv1.Deployment, error) { +func getDeployment(ctx context.Context, wp *atev1.WorkerPool) (*appsv1.Deployment, error) { dep := &appsv1.Deployment{} err := k8sClient.Get(ctx, types.NamespacedName{ Name: wp.Name, @@ -701,7 +701,7 @@ func getDeployment(ctx context.Context, wp *atev1alpha1.WorkerPool) (*appsv1.Dep // controller reconciles the Deployment concurrently (bumping its // resourceVersion on every SSA apply), so a plain get-then-update flakes with // "the object has been modified" under load. -func updateDeployment(t *testing.T, ctx context.Context, wp *atev1alpha1.WorkerPool, action string, mutate func(*appsv1.Deployment), update func(*appsv1.Deployment) error) { +func updateDeployment(t *testing.T, ctx context.Context, wp *atev1.WorkerPool, action string, mutate func(*appsv1.Deployment), update func(*appsv1.Deployment) error) { t.Helper() err := retry.RetryOnConflict(retry.DefaultBackoff, func() error { dep, err := getDeployment(ctx, wp) @@ -716,7 +716,7 @@ func updateDeployment(t *testing.T, ctx context.Context, wp *atev1alpha1.WorkerP } } -func updateDeploymentSpec(t *testing.T, ctx context.Context, wp *atev1alpha1.WorkerPool, action string, mutate func(*appsv1.Deployment)) { +func updateDeploymentSpec(t *testing.T, ctx context.Context, wp *atev1.WorkerPool, action string, mutate func(*appsv1.Deployment)) { t.Helper() updateDeployment(t, ctx, wp, action, mutate, func(dep *appsv1.Deployment) error { return k8sClient.Update(ctx, dep) @@ -724,17 +724,17 @@ func updateDeploymentSpec(t *testing.T, ctx context.Context, wp *atev1alpha1.Wor } // updateDeploymentStatus is updateDeploymentSpec for the status subresource. -func updateDeploymentStatus(t *testing.T, ctx context.Context, wp *atev1alpha1.WorkerPool, action string, mutate func(*appsv1.Deployment)) { +func updateDeploymentStatus(t *testing.T, ctx context.Context, wp *atev1.WorkerPool, action string, mutate func(*appsv1.Deployment)) { t.Helper() updateDeployment(t, ctx, wp, action, mutate, func(dep *appsv1.Deployment) error { return k8sClient.Status().Update(ctx, dep) }) } -func updateWorkerPoolSpec(t *testing.T, ctx context.Context, wp *atev1alpha1.WorkerPool, action string, mutate func(*atev1alpha1.WorkerPool)) { +func updateWorkerPoolSpec(t *testing.T, ctx context.Context, wp *atev1.WorkerPool, action string, mutate func(*atev1.WorkerPool)) { t.Helper() err := retry.RetryOnConflict(retry.DefaultBackoff, func() error { - current := &atev1alpha1.WorkerPool{} + current := &atev1.WorkerPool{} if err := k8sClient.Get(ctx, types.NamespacedName{Name: wp.Name, Namespace: wp.Namespace}, current); err != nil { return err } @@ -774,7 +774,7 @@ func TestSyncStatus_ReadyReplicas(t *testing.T) { dep.Status.ReadyReplicas = 2 }) eventually(t, func(ctx context.Context) (bool, error) { - current := &atev1alpha1.WorkerPool{} + current := &atev1.WorkerPool{} if err := k8sClient.Get(ctx, types.NamespacedName{Name: wp.Name, Namespace: wp.Namespace}, current); err != nil { return false, nil } @@ -789,11 +789,11 @@ func TestSyncStatus_ReadyReplicas(t *testing.T) { func TestWorkerPoolMetrics(t *testing.T) { t.Parallel() scheme := runtime.NewScheme() - if err := atev1alpha1.AddToScheme(scheme); err != nil { + if err := atev1.AddToScheme(scheme); err != nil { t.Fatalf("add scheme: %v", err) } wp := makeWorkerPool("test-metrics", "default", 4, "worker:v1") - wp.Status = atev1alpha1.WorkerPoolStatus{Replicas: 4, ReadyReplicas: 2} + wp.Status = atev1.WorkerPoolStatus{Replicas: 4, ReadyReplicas: 2} reader := sdkmetric.NewManualReader() r := &WorkerPoolReconciler{ Client: fake.NewClientBuilder().WithScheme(scheme).WithObjects(wp).Build(), diff --git a/cmd/atecontroller/internal/controllers/workerpool_sandboxconfig.go b/cmd/atecontroller/internal/controllers/workerpool_sandboxconfig.go index 1a23edd376..6227f4585d 100644 --- a/cmd/atecontroller/internal/controllers/workerpool_sandboxconfig.go +++ b/cmd/atecontroller/internal/controllers/workerpool_sandboxconfig.go @@ -22,7 +22,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" ) // resolveLatestSandboxConfig picks the SandboxConfig the spec of one sandbox @@ -34,31 +34,31 @@ import ( // - Without configRef, the newest config of the class that is annotated as // the class default and is not being deleted is used. If two were created // at the same time, the name that sorts first wins. -func resolveLatestSandboxConfig(entry atev1alpha1.WorkerPoolSandboxClass, configs []atev1alpha1.SandboxConfig) (*atev1alpha1.SandboxConfig, string, string) { +func resolveLatestSandboxConfig(entry atev1.WorkerPoolSandboxClass, configs []atev1.SandboxConfig) (*atev1.SandboxConfig, string, string) { if entry.ConfigRef != nil { name := entry.ConfigRef.Name - i := slices.IndexFunc(configs, func(sc atev1alpha1.SandboxConfig) bool { return sc.Name == name }) + i := slices.IndexFunc(configs, func(sc atev1.SandboxConfig) bool { return sc.Name == name }) if i < 0 { - return nil, atev1alpha1.WorkerPoolReasonSandboxConfigNotFound, + return nil, atev1.WorkerPoolReasonSandboxConfigNotFound, fmt.Sprintf("SandboxConfig %q not found", name) } sc := &configs[i] if sc.Spec.SandboxClass != entry.Name { - return nil, atev1alpha1.WorkerPoolReasonSandboxClassMismatch, + return nil, atev1.WorkerPoolReasonSandboxClassMismatch, fmt.Sprintf("SandboxConfig %q is for sandbox class %q, not %q", name, sc.Spec.SandboxClass, entry.Name) } if !sc.DeletionTimestamp.IsZero() { - return nil, atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + return nil, atev1.WorkerPoolReasonSandboxConfigDeleting, fmt.Sprintf("SandboxConfig %q is being deleted", name) } return sc, "", "" } - isDefault := func(sc atev1alpha1.SandboxConfig) bool { + isDefault := func(sc atev1.SandboxConfig) bool { return sc.Spec.SandboxClass == entry.Name && - sc.Annotations[atev1alpha1.SandboxConfigClassDefaultAnnotation] == "true" + sc.Annotations[atev1.SandboxConfigClassDefaultAnnotation] == "true" } - var best *atev1alpha1.SandboxConfig + var best *atev1.SandboxConfig for i := range configs { sc := &configs[i] if isDefault(*sc) && sc.DeletionTimestamp.IsZero() && (best == nil || newerSandboxConfig(sc, best)) { @@ -68,28 +68,28 @@ func resolveLatestSandboxConfig(entry atev1alpha1.WorkerPoolSandboxClass, config if best != nil { return best, "", "" } - isDeletingDefault := func(sc atev1alpha1.SandboxConfig) bool { + isDeletingDefault := func(sc atev1.SandboxConfig) bool { return isDefault(sc) && !sc.DeletionTimestamp.IsZero() } if slices.ContainsFunc(configs, isDeletingDefault) { - return nil, atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + return nil, atev1.WorkerPoolReasonSandboxConfigDeleting, fmt.Sprintf("the default SandboxConfig for sandbox class %q is being deleted", entry.Name) } - return nil, atev1alpha1.WorkerPoolReasonDefaultConfigNotFound, - fmt.Sprintf("no SandboxConfig of sandbox class %q is annotated %s=true", entry.Name, atev1alpha1.SandboxConfigClassDefaultAnnotation) + return nil, atev1.WorkerPoolReasonDefaultConfigNotFound, + fmt.Sprintf("no SandboxConfig of sandbox class %q is annotated %s=true", entry.Name, atev1.SandboxConfigClassDefaultAnnotation) } // resolveSandboxConfig returns the SandboxConfig one sandbox class entry uses // and its Resolved condition. inUse is the config the pool's status already // uses for this class, or "". When the spec does not resolve, the condition is // False and the pool keeps inUse. See keepSandboxConfig. -func resolveSandboxConfig(entry atev1alpha1.WorkerPoolSandboxClass, inUse string, configs []atev1alpha1.SandboxConfig) (*atev1alpha1.SandboxConfig, metav1.Condition) { +func resolveSandboxConfig(entry atev1.WorkerPoolSandboxClass, inUse string, configs []atev1.SandboxConfig) (*atev1.SandboxConfig, metav1.Condition) { sc, reason, message := resolveLatestSandboxConfig(entry, configs) if sc != nil { return sc, metav1.Condition{ - Type: atev1alpha1.WorkerPoolSandboxClassConditionResolved, + Type: atev1.WorkerPoolSandboxClassConditionResolved, Status: metav1.ConditionTrue, - Reason: atev1alpha1.WorkerPoolReasonResolved, + Reason: atev1.WorkerPoolReasonResolved, Message: fmt.Sprintf("resolved to SandboxConfig %q", sc.Name), } } @@ -104,18 +104,18 @@ func resolveSandboxConfig(entry atev1alpha1.WorkerPoolSandboxClass, inUse string // config in use that is being deleted carries the protection finalizer while // any pool's status names it. One without the finalizer is about to // disappear, so it is not kept. -func keepSandboxConfig(class atev1alpha1.SandboxClass, inUse string, configs []atev1alpha1.SandboxConfig, reason, message string) (*atev1alpha1.SandboxConfig, metav1.Condition) { - var kept *atev1alpha1.SandboxConfig +func keepSandboxConfig(class atev1.SandboxClass, inUse string, configs []atev1.SandboxConfig, reason, message string) (*atev1.SandboxConfig, metav1.Condition) { + var kept *atev1.SandboxConfig if inUse != "" { - i := slices.IndexFunc(configs, func(sc atev1alpha1.SandboxConfig) bool { return sc.Name == inUse }) + i := slices.IndexFunc(configs, func(sc atev1.SandboxConfig) bool { return sc.Name == inUse }) if i >= 0 && configs[i].Spec.SandboxClass == class && - (configs[i].DeletionTimestamp.IsZero() || controllerutil.ContainsFinalizer(&configs[i], atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer)) { + (configs[i].DeletionTimestamp.IsZero() || controllerutil.ContainsFinalizer(&configs[i], atev1.SandboxConfigWorkerPoolProtectionFinalizer)) { kept = &configs[i] message = fmt.Sprintf("%s; keeping %q", message, kept.Name) } } return kept, metav1.Condition{ - Type: atev1alpha1.WorkerPoolSandboxClassConditionResolved, + Type: atev1.WorkerPoolSandboxClassConditionResolved, Status: metav1.ConditionFalse, Reason: reason, Message: message, @@ -124,7 +124,7 @@ func keepSandboxConfig(class atev1alpha1.SandboxClass, inUse string, configs []a // newerSandboxConfig reports whether a takes precedence over b as a class // default. -func newerSandboxConfig(a, b *atev1alpha1.SandboxConfig) bool { +func newerSandboxConfig(a, b *atev1.SandboxConfig) bool { if !a.CreationTimestamp.Equal(&b.CreationTimestamp) { return b.CreationTimestamp.Before(&a.CreationTimestamp) } @@ -135,8 +135,8 @@ func newerSandboxConfig(a, b *atev1alpha1.SandboxConfig) bool { // returns one status entry per class, and whether every class resolved. Each // entry carries the config the class uses, nil if it has none, and its // Resolved condition. -func resolveSandboxClasses(wp *atev1alpha1.WorkerPool, configs []atev1alpha1.SandboxConfig) ([]atev1alpha1.WorkerPoolSandboxClassStatus, bool) { - statuses := make([]atev1alpha1.WorkerPoolSandboxClassStatus, 0, len(wp.Spec.SandboxClasses)) +func resolveSandboxClasses(wp *atev1.WorkerPool, configs []atev1.SandboxConfig) ([]atev1.WorkerPoolSandboxClassStatus, bool) { + statuses := make([]atev1.WorkerPoolSandboxClassStatus, 0, len(wp.Spec.SandboxClasses)) resolved := true for _, entry := range wp.Spec.SandboxClasses { prev := sandboxClassStatus(wp, entry.Name) @@ -157,28 +157,28 @@ func resolveSandboxClasses(wp *atev1alpha1.WorkerPool, configs []atev1alpha1.San // uses, nil if none, and its Resolved condition. The entry starts from the // class's previous conditions in wp, so lastTransitionTime only moves when the // condition's status does. -func sandboxClassStatusFor(wp *atev1alpha1.WorkerPool, class atev1alpha1.SandboxClass, sc *atev1alpha1.SandboxConfig, cond metav1.Condition) atev1alpha1.WorkerPoolSandboxClassStatus { +func sandboxClassStatusFor(wp *atev1.WorkerPool, class atev1.SandboxClass, sc *atev1.SandboxConfig, cond metav1.Condition) atev1.WorkerPoolSandboxClassStatus { cond.ObservedGeneration = wp.Generation - status := atev1alpha1.WorkerPoolSandboxClassStatus{Name: class} + status := atev1.WorkerPoolSandboxClassStatus{Name: class} if prev := sandboxClassStatus(wp, class); prev != nil { status.Conditions = slices.Clone(prev.Conditions) } meta.SetStatusCondition(&status.Conditions, cond) if sc != nil { - status.ConfigRef = &atev1alpha1.SandboxConfigReference{Name: sc.Name} + status.ConfigRef = &atev1.SandboxConfigReference{Name: sc.Name} } return status } // switchesSandboxConfig reports whether class, as resolved, uses a config // other than the one wp's status uses for it. -func switchesSandboxConfig(wp *atev1alpha1.WorkerPool, class atev1alpha1.WorkerPoolSandboxClassStatus) bool { +func switchesSandboxConfig(wp *atev1.WorkerPool, class atev1.WorkerPoolSandboxClassStatus) bool { return switchesSandboxConfigFrom(wp.Status.SandboxClasses, class) } // switchesSandboxConfigFrom reports whether class, as resolved, uses a config // other than the one its entry in prev uses. -func switchesSandboxConfigFrom(prev []atev1alpha1.WorkerPoolSandboxClassStatus, class atev1alpha1.WorkerPoolSandboxClassStatus) bool { +func switchesSandboxConfigFrom(prev []atev1.WorkerPoolSandboxClassStatus, class atev1.WorkerPoolSandboxClassStatus) bool { if class.ConfigRef == nil { return false } @@ -191,11 +191,11 @@ func switchesSandboxConfigFrom(prev []atev1alpha1.WorkerPoolSandboxClassStatus, // class's status in wp as it is and names the new config in pendingConfigRef. // That protects the new config like configRef does while // confirmSandboxConfigSwitch checks it. -func claimSandboxConfigs(wp *atev1alpha1.WorkerPool, classes []atev1alpha1.WorkerPoolSandboxClassStatus) []atev1alpha1.WorkerPoolSandboxClassStatus { - claim := make([]atev1alpha1.WorkerPoolSandboxClassStatus, 0, len(classes)) +func claimSandboxConfigs(wp *atev1.WorkerPool, classes []atev1.WorkerPoolSandboxClassStatus) []atev1.WorkerPoolSandboxClassStatus { + claim := make([]atev1.WorkerPoolSandboxClassStatus, 0, len(classes)) claimed := false for _, class := range classes { - status := atev1alpha1.WorkerPoolSandboxClassStatus{Name: class.Name} + status := atev1.WorkerPoolSandboxClassStatus{Name: class.Name} if prev := sandboxClassStatus(wp, class.Name); prev != nil { status = *prev.DeepCopy() status.PendingConfigRef = nil @@ -218,18 +218,18 @@ func claimSandboxConfigs(wp *atev1alpha1.WorkerPool, classes []atev1alpha1.Worke // if the config belongs to the class and is not being deleted. Otherwise the // class keeps the config wp's status uses, with a False Resolved condition. // configs is the cached list keepSandboxConfig checks that config against. -func confirmSandboxConfigSwitch(wp *atev1alpha1.WorkerPool, class atev1alpha1.WorkerPoolSandboxClassStatus, live *atev1alpha1.SandboxConfig, configs []atev1alpha1.SandboxConfig) atev1alpha1.WorkerPoolSandboxClassStatus { +func confirmSandboxConfigSwitch(wp *atev1.WorkerPool, class atev1.WorkerPoolSandboxClassStatus, live *atev1.SandboxConfig, configs []atev1.SandboxConfig) atev1.WorkerPoolSandboxClassStatus { name := class.ConfigRef.Name var reason, message string switch { case live == nil: - reason, message = atev1alpha1.WorkerPoolReasonSandboxConfigNotFound, + reason, message = atev1.WorkerPoolReasonSandboxConfigNotFound, fmt.Sprintf("SandboxConfig %q not found", name) case live.Spec.SandboxClass != class.Name: - reason, message = atev1alpha1.WorkerPoolReasonSandboxClassMismatch, + reason, message = atev1.WorkerPoolReasonSandboxClassMismatch, fmt.Sprintf("SandboxConfig %q is for sandbox class %q, not %q", name, live.Spec.SandboxClass, class.Name) case !live.DeletionTimestamp.IsZero(): - reason, message = atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + reason, message = atev1.WorkerPoolReasonSandboxConfigDeleting, fmt.Sprintf("SandboxConfig %q is being deleted", name) default: return class @@ -243,12 +243,12 @@ func confirmSandboxConfigSwitch(wp *atev1alpha1.WorkerPool, class atev1alpha1.Wo } // sandboxClassStatus returns the status entry wp records for class, or nil. -func sandboxClassStatus(wp *atev1alpha1.WorkerPool, class atev1alpha1.SandboxClass) *atev1alpha1.WorkerPoolSandboxClassStatus { +func sandboxClassStatus(wp *atev1.WorkerPool, class atev1.SandboxClass) *atev1.WorkerPoolSandboxClassStatus { return findSandboxClassStatus(wp.Status.SandboxClasses, class) } // findSandboxClassStatus returns the entry of class in statuses, or nil. -func findSandboxClassStatus(statuses []atev1alpha1.WorkerPoolSandboxClassStatus, class atev1alpha1.SandboxClass) *atev1alpha1.WorkerPoolSandboxClassStatus { +func findSandboxClassStatus(statuses []atev1.WorkerPoolSandboxClassStatus, class atev1.SandboxClass) *atev1.WorkerPoolSandboxClassStatus { for i := range statuses { if statuses[i].Name == class { return &statuses[i] @@ -259,7 +259,7 @@ func findSandboxClassStatus(statuses []atev1alpha1.WorkerPoolSandboxClassStatus, // sandboxConfigsInUse returns the names of the SandboxConfigs wp's status // records as in use. That is every configRef and every pendingConfigRef. -func sandboxConfigsInUse(wp *atev1alpha1.WorkerPool) []string { +func sandboxConfigsInUse(wp *atev1.WorkerPool) []string { names := make([]string, 0, len(wp.Status.SandboxClasses)) for _, s := range wp.Status.SandboxClasses { if s.ConfigRef != nil { diff --git a/cmd/atecontroller/internal/controllers/workerpool_sandboxconfig_test.go b/cmd/atecontroller/internal/controllers/workerpool_sandboxconfig_test.go index e5b1e7dbfc..fdb17ab63f 100644 --- a/cmd/atecontroller/internal/controllers/workerpool_sandboxconfig_test.go +++ b/cmd/atecontroller/internal/controllers/workerpool_sandboxconfig_test.go @@ -42,7 +42,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" ) // testGvisorDefault is the gvisor class default TestMain creates. @@ -56,7 +56,7 @@ func TestResolveSandboxConfig(t *testing.T) { t.Parallel() t0 := metav1.NewTime(time.Date(2026, 10, 1, 0, 0, 0, 0, time.UTC)) t1 := metav1.NewTime(t0.Add(time.Minute)) - sc := func(name string, class atev1alpha1.SandboxClass, isDefault bool, created metav1.Time, mutate ...func(*atev1alpha1.SandboxConfig)) atev1alpha1.SandboxConfig { + sc := func(name string, class atev1.SandboxClass, isDefault bool, created metav1.Time, mutate ...func(*atev1.SandboxConfig)) atev1.SandboxConfig { c := *makeSandboxConfig(name, class, isDefault) c.CreationTimestamp = created for _, m := range mutate { @@ -64,25 +64,25 @@ func TestResolveSandboxConfig(t *testing.T) { } return c } - deleting := func(c *atev1alpha1.SandboxConfig) { c.DeletionTimestamp = &t1 } - protected := func(c *atev1alpha1.SandboxConfig) { - controllerutil.AddFinalizer(c, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) + deleting := func(c *atev1.SandboxConfig) { c.DeletionTimestamp = &t1 } + protected := func(c *atev1.SandboxConfig) { + controllerutil.AddFinalizer(c, atev1.SandboxConfigWorkerPoolProtectionFinalizer) } - gvisor := func(ref string) atev1alpha1.WorkerPoolSandboxClass { - e := atev1alpha1.WorkerPoolSandboxClass{Name: atev1alpha1.SandboxClassGvisor} + gvisor := func(ref string) atev1.WorkerPoolSandboxClass { + e := atev1.WorkerPoolSandboxClass{Name: atev1.SandboxClassGvisor} if ref != "" { - e.ConfigRef = &atev1alpha1.SandboxConfigReference{Name: ref} + e.ConfigRef = &atev1.SandboxConfigReference{Name: ref} } return e } - gv := atev1alpha1.SandboxClassGvisor + gv := atev1.SandboxClassGvisor tests := []struct { name string - entry atev1alpha1.WorkerPoolSandboxClass + entry atev1.WorkerPoolSandboxClass inUse string - configs []atev1alpha1.SandboxConfig + configs []atev1.SandboxConfig // want is the config the class uses, or "" for none. want string // wantReason is the False condition's reason, or "" for True. @@ -92,134 +92,134 @@ func TestResolveSandboxConfig(t *testing.T) { { name: "explicit ref resolves even when another config is the default", entry: gvisor("custom"), - configs: []atev1alpha1.SandboxConfig{sc("custom", gv, false, t0), sc("def", gv, true, t1)}, + configs: []atev1.SandboxConfig{sc("custom", gv, false, t0), sc("def", gv, true, t1)}, want: "custom", wantMessage: `resolved to SandboxConfig "custom"`, }, { name: "explicit ref not found", entry: gvisor("missing"), - configs: []atev1alpha1.SandboxConfig{sc("def", gv, true, t0)}, - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigNotFound, + configs: []atev1.SandboxConfig{sc("def", gv, true, t0)}, + wantReason: atev1.WorkerPoolReasonSandboxConfigNotFound, wantMessage: `SandboxConfig "missing" not found`, }, { name: "explicit ref not found keeps the config in use", entry: gvisor("missing"), inUse: "old", - configs: []atev1alpha1.SandboxConfig{sc("old", gv, false, t0)}, + configs: []atev1.SandboxConfig{sc("old", gv, false, t0)}, want: "old", - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigNotFound, + wantReason: atev1.WorkerPoolReasonSandboxConfigNotFound, wantMessage: `SandboxConfig "missing" not found; keeping "old"`, }, { name: "explicit ref of another class", entry: gvisor("vm"), - configs: []atev1alpha1.SandboxConfig{sc("vm", atev1alpha1.SandboxClassMicroVM, false, t0)}, - wantReason: atev1alpha1.WorkerPoolReasonSandboxClassMismatch, + configs: []atev1.SandboxConfig{sc("vm", atev1.SandboxClassMicroVM, false, t0)}, + wantReason: atev1.WorkerPoolReasonSandboxClassMismatch, wantMessage: `SandboxConfig "vm" is for sandbox class "microvm", not "gvisor"`, }, { name: "explicit ref of another class keeps the config in use", entry: gvisor("vm"), inUse: "old", - configs: []atev1alpha1.SandboxConfig{sc("vm", atev1alpha1.SandboxClassMicroVM, false, t0), sc("old", gv, false, t0)}, + configs: []atev1.SandboxConfig{sc("vm", atev1.SandboxClassMicroVM, false, t0), sc("old", gv, false, t0)}, want: "old", - wantReason: atev1alpha1.WorkerPoolReasonSandboxClassMismatch, + wantReason: atev1.WorkerPoolReasonSandboxClassMismatch, wantMessage: `SandboxConfig "vm" is for sandbox class "microvm", not "gvisor"; keeping "old"`, }, { name: "explicit ref being deleted takes no new users", entry: gvisor("dying"), - configs: []atev1alpha1.SandboxConfig{sc("dying", gv, false, t0, deleting)}, - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + configs: []atev1.SandboxConfig{sc("dying", gv, false, t0, deleting)}, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, wantMessage: `SandboxConfig "dying" is being deleted`, }, { name: "explicit ref being deleted is kept but reported by a pool already using it", entry: gvisor("dying"), inUse: "dying", - configs: []atev1alpha1.SandboxConfig{sc("dying", gv, false, t0, deleting, protected)}, + configs: []atev1.SandboxConfig{sc("dying", gv, false, t0, deleting, protected)}, want: "dying", - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, wantMessage: `SandboxConfig "dying" is being deleted; keeping "dying"`, }, { name: "explicit ref being deleted and released is not kept by a pool using it", entry: gvisor("dying"), inUse: "dying", - configs: []atev1alpha1.SandboxConfig{sc("dying", gv, false, t0, deleting)}, - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + configs: []atev1.SandboxConfig{sc("dying", gv, false, t0, deleting)}, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, wantMessage: `SandboxConfig "dying" is being deleted`, }, { name: "explicit ref being deleted keeps the previous config in use", entry: gvisor("dying"), inUse: "old", - configs: []atev1alpha1.SandboxConfig{sc("dying", gv, false, t0, deleting), sc("old", gv, false, t0)}, + configs: []atev1.SandboxConfig{sc("dying", gv, false, t0, deleting), sc("old", gv, false, t0)}, want: "old", - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, wantMessage: `SandboxConfig "dying" is being deleted; keeping "old"`, }, { name: "no default", entry: gvisor(""), - configs: []atev1alpha1.SandboxConfig{sc("plain", gv, false, t0)}, - wantReason: atev1alpha1.WorkerPoolReasonDefaultConfigNotFound, + configs: []atev1.SandboxConfig{sc("plain", gv, false, t0)}, + wantReason: atev1.WorkerPoolReasonDefaultConfigNotFound, wantMessage: `no SandboxConfig of sandbox class "gvisor" is annotated sandboxconfig.ate.dev/is-class-default=true`, }, { name: "default of another class is ignored", entry: gvisor(""), - configs: []atev1alpha1.SandboxConfig{sc("vm", atev1alpha1.SandboxClassMicroVM, true, t0)}, - wantReason: atev1alpha1.WorkerPoolReasonDefaultConfigNotFound, + configs: []atev1.SandboxConfig{sc("vm", atev1.SandboxClassMicroVM, true, t0)}, + wantReason: atev1.WorkerPoolReasonDefaultConfigNotFound, wantMessage: `no SandboxConfig of sandbox class "gvisor" is annotated sandboxconfig.ate.dev/is-class-default=true`, }, { name: "annotation must be exactly true", entry: gvisor(""), - configs: []atev1alpha1.SandboxConfig{sc("no", gv, false, t0, func(c *atev1alpha1.SandboxConfig) { - c.Annotations = map[string]string{atev1alpha1.SandboxConfigClassDefaultAnnotation: "True"} + configs: []atev1.SandboxConfig{sc("no", gv, false, t0, func(c *atev1.SandboxConfig) { + c.Annotations = map[string]string{atev1.SandboxConfigClassDefaultAnnotation: "True"} })}, - wantReason: atev1alpha1.WorkerPoolReasonDefaultConfigNotFound, + wantReason: atev1.WorkerPoolReasonDefaultConfigNotFound, wantMessage: `no SandboxConfig of sandbox class "gvisor" is annotated sandboxconfig.ate.dev/is-class-default=true`, }, { name: "default being deleted takes no new users", entry: gvisor(""), - configs: []atev1alpha1.SandboxConfig{sc("dying", gv, true, t0, deleting)}, - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + configs: []atev1.SandboxConfig{sc("dying", gv, true, t0, deleting)}, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, wantMessage: `the default SandboxConfig for sandbox class "gvisor" is being deleted`, }, { name: "several defaults being deleted are reported", entry: gvisor(""), - configs: []atev1alpha1.SandboxConfig{sc("dying-new", gv, true, t1, deleting), sc("dying-old", gv, true, t0, deleting)}, - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + configs: []atev1.SandboxConfig{sc("dying-new", gv, true, t1, deleting), sc("dying-old", gv, true, t0, deleting)}, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, wantMessage: `the default SandboxConfig for sandbox class "gvisor" is being deleted`, }, { name: "default being deleted is kept but reported by a pool already using it", entry: gvisor(""), inUse: "dying", - configs: []atev1alpha1.SandboxConfig{sc("dying", gv, true, t0, deleting, protected)}, + configs: []atev1.SandboxConfig{sc("dying", gv, true, t0, deleting, protected)}, want: "dying", - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, wantMessage: `the default SandboxConfig for sandbox class "gvisor" is being deleted; keeping "dying"`, }, { name: "default being deleted and released is not kept by a pool using it", entry: gvisor(""), inUse: "dying", - configs: []atev1alpha1.SandboxConfig{sc("dying", gv, true, t0, deleting)}, - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + configs: []atev1.SandboxConfig{sc("dying", gv, true, t0, deleting)}, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, wantMessage: `the default SandboxConfig for sandbox class "gvisor" is being deleted`, }, { name: "a live default replaces the deleting one in use, even when older", entry: gvisor(""), inUse: "dying", - configs: []atev1alpha1.SandboxConfig{sc("dying", gv, true, t1, deleting), sc("old", gv, true, t0)}, + configs: []atev1.SandboxConfig{sc("dying", gv, true, t1, deleting), sc("old", gv, true, t0)}, want: "old", wantMessage: `resolved to SandboxConfig "old"`, }, @@ -227,45 +227,45 @@ func TestResolveSandboxConfig(t *testing.T) { name: "config in use that lost the default annotation is kept but reported", entry: gvisor(""), inUse: "plain", - configs: []atev1alpha1.SandboxConfig{sc("plain", gv, false, t0)}, + configs: []atev1.SandboxConfig{sc("plain", gv, false, t0)}, want: "plain", - wantReason: atev1alpha1.WorkerPoolReasonDefaultConfigNotFound, + wantReason: atev1.WorkerPoolReasonDefaultConfigNotFound, wantMessage: `no SandboxConfig of sandbox class "gvisor" is annotated sandboxconfig.ate.dev/is-class-default=true; keeping "plain"`, }, { name: "config in use that no longer exists is not kept", entry: gvisor(""), inUse: "gone", - configs: []atev1alpha1.SandboxConfig{sc("plain", gv, false, t0)}, - wantReason: atev1alpha1.WorkerPoolReasonDefaultConfigNotFound, + configs: []atev1.SandboxConfig{sc("plain", gv, false, t0)}, + wantReason: atev1.WorkerPoolReasonDefaultConfigNotFound, wantMessage: `no SandboxConfig of sandbox class "gvisor" is annotated sandboxconfig.ate.dev/is-class-default=true`, }, { name: "config in use of another class is not kept", entry: gvisor(""), inUse: "vm", - configs: []atev1alpha1.SandboxConfig{sc("vm", atev1alpha1.SandboxClassMicroVM, true, t0)}, - wantReason: atev1alpha1.WorkerPoolReasonDefaultConfigNotFound, + configs: []atev1.SandboxConfig{sc("vm", atev1.SandboxClassMicroVM, true, t0)}, + wantReason: atev1.WorkerPoolReasonDefaultConfigNotFound, wantMessage: `no SandboxConfig of sandbox class "gvisor" is annotated sandboxconfig.ate.dev/is-class-default=true`, }, { name: "newest default wins", entry: gvisor(""), - configs: []atev1alpha1.SandboxConfig{sc("a-old", gv, true, t0), sc("z-new", gv, true, t1), sc("plain", gv, false, t1)}, + configs: []atev1.SandboxConfig{sc("a-old", gv, true, t0), sc("z-new", gv, true, t1), sc("plain", gv, false, t1)}, want: "z-new", wantMessage: `resolved to SandboxConfig "z-new"`, }, { name: "newest default wins regardless of list order", entry: gvisor(""), - configs: []atev1alpha1.SandboxConfig{sc("z-new", gv, true, t1), sc("a-old", gv, true, t0)}, + configs: []atev1.SandboxConfig{sc("z-new", gv, true, t1), sc("a-old", gv, true, t0)}, want: "z-new", wantMessage: `resolved to SandboxConfig "z-new"`, }, { name: "creation time tie goes to the first name", entry: gvisor(""), - configs: []atev1alpha1.SandboxConfig{sc("b", gv, true, t0), sc("a", gv, true, t0)}, + configs: []atev1.SandboxConfig{sc("b", gv, true, t0), sc("a", gv, true, t0)}, want: "a", wantMessage: `resolved to SandboxConfig "a"`, }, @@ -279,9 +279,9 @@ func TestResolveSandboxConfig(t *testing.T) { gotName = got.Name } want := metav1.Condition{ - Type: atev1alpha1.WorkerPoolSandboxClassConditionResolved, + Type: atev1.WorkerPoolSandboxClassConditionResolved, Status: metav1.ConditionTrue, - Reason: atev1alpha1.WorkerPoolReasonResolved, + Reason: atev1.WorkerPoolReasonResolved, Message: tc.wantMessage, } if tc.wantReason != "" { @@ -306,16 +306,16 @@ func TestReconcileProtectsBeforeRecording(t *testing.T) { if err := clientgoscheme.AddToScheme(scheme); err != nil { t.Fatalf("add client-go scheme: %v", err) } - if err := atev1alpha1.AddToScheme(scheme); err != nil { + if err := atev1.AddToScheme(scheme); err != nil { t.Fatalf("add scheme: %v", err) } - protected := func(sc *atev1alpha1.SandboxConfig) *atev1alpha1.SandboxConfig { - controllerutil.AddFinalizer(sc, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) + protected := func(sc *atev1.SandboxConfig) *atev1.SandboxConfig { + controllerutil.AddFinalizer(sc, atev1.SandboxConfigWorkerPoolProtectionFinalizer) return sc } tests := []struct { name string - config *atev1alpha1.SandboxConfig + config *atev1.SandboxConfig // ref is the pool's configRef. "" follows the class default. ref string // wantResolved is whether the pool must end up using config. @@ -325,26 +325,26 @@ func TestReconcileProtectsBeforeRecording(t *testing.T) { }{ { name: "unprotected class default", - config: makeSandboxConfig("fresh-default", atev1alpha1.SandboxClassGvisor, true), + config: makeSandboxConfig("fresh-default", atev1.SandboxClassGvisor, true), wantResolved: true, wantProtected: true, }, { name: "unprotected configRef target", - config: makeSandboxConfig("fresh-ref", atev1alpha1.SandboxClassGvisor, false), + config: makeSandboxConfig("fresh-ref", atev1.SandboxClassGvisor, false), ref: "fresh-ref", wantResolved: true, wantProtected: true, }, { name: "already protected config", - config: protected(makeSandboxConfig("held", atev1alpha1.SandboxClassGvisor, true)), + config: protected(makeSandboxConfig("held", atev1.SandboxClassGvisor, true)), wantResolved: true, wantProtected: true, }, { name: "unresolved pool protects nothing", - config: makeSandboxConfig("other-class", atev1alpha1.SandboxClassMicroVM, false), + config: makeSandboxConfig("other-class", atev1.SandboxClassMicroVM, false), ref: "other-class", wantResolved: false, wantProtected: false, @@ -355,7 +355,7 @@ func TestReconcileProtectsBeforeRecording(t *testing.T) { t.Parallel() wp := makeWorkerPool("pool", "default", 1, "worker:v1") if tc.ref != "" { - wp.Spec.SandboxClasses[0].ConfigRef = &atev1alpha1.SandboxConfigReference{Name: tc.ref} + wp.Spec.SandboxClasses[0].ConfigRef = &atev1.SandboxConfigReference{Name: tc.ref} } // protectedAtWrite records whether config carried the finalizer // at the moment the pool's status was written. @@ -363,12 +363,12 @@ func TestReconcileProtectsBeforeRecording(t *testing.T) { c := fake.NewClientBuilder().WithScheme(scheme).WithObjects(wp, tc.config).WithStatusSubresource(wp). WithInterceptorFuncs(interceptor.Funcs{ SubResourceUpdate: func(ctx context.Context, c client.Client, sub string, obj client.Object, opts ...client.SubResourceUpdateOption) error { - sc := &atev1alpha1.SandboxConfig{} + sc := &atev1.SandboxConfig{} if err := c.Get(ctx, types.NamespacedName{Name: tc.config.Name}, sc); err != nil { return err } wroteStatus = true - protectedAtWrite = controllerutil.ContainsFinalizer(sc, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) + protectedAtWrite = controllerutil.ContainsFinalizer(sc, atev1.SandboxConfigWorkerPoolProtectionFinalizer) return c.SubResource(sub).Update(ctx, obj, opts...) }, }).Build() @@ -377,18 +377,18 @@ func TestReconcileProtectsBeforeRecording(t *testing.T) { t.Fatalf("Reconcile: %v", err) } - sc := &atev1alpha1.SandboxConfig{} + sc := &atev1.SandboxConfig{} if err := c.Get(t.Context(), types.NamespacedName{Name: tc.config.Name}, sc); err != nil { t.Fatalf("get SandboxConfig: %v", err) } - if got := controllerutil.ContainsFinalizer(sc, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer); got != tc.wantProtected { + if got := controllerutil.ContainsFinalizer(sc, atev1.SandboxConfigWorkerPoolProtectionFinalizer); got != tc.wantProtected { t.Errorf("config protected = %v, want %v", got, tc.wantProtected) } - got := &atev1alpha1.WorkerPool{} + got := &atev1.WorkerPool{} if err := c.Get(t.Context(), client.ObjectKeyFromObject(wp), got); err != nil { t.Fatalf("get WorkerPool: %v", err) } - if resolved := statusConfig(got, atev1alpha1.SandboxClassGvisor) == tc.config.Name; resolved != tc.wantResolved { + if resolved := statusConfig(got, atev1.SandboxClassGvisor) == tc.config.Name; resolved != tc.wantResolved { t.Errorf("status names config = %v, want %v (status %+v)", resolved, tc.wantResolved, got.Status) } if !wroteStatus { @@ -415,33 +415,33 @@ func TestReconcileConfigDeletedBeforeClaim(t *testing.T) { if err := clientgoscheme.AddToScheme(scheme); err != nil { t.Fatalf("add scheme: %v", err) } - if err := atev1alpha1.AddToScheme(scheme); err != nil { + if err := atev1.AddToScheme(scheme); err != nil { t.Fatalf("add scheme: %v", err) } t0 := metav1.NewTime(time.Date(2026, 10, 1, 0, 0, 0, 0, time.UTC)) // newDefault is the newest gvisor default, so the pool resolves to it // first. oldDefault is the one it must fall back to. - config := func(name string, created metav1.Time, finalizers ...string) *atev1alpha1.SandboxConfig { - sc := makeSandboxConfig(name, atev1alpha1.SandboxClassGvisor, true) + config := func(name string, created metav1.Time, finalizers ...string) *atev1.SandboxConfig { + sc := makeSandboxConfig(name, atev1.SandboxClassGvisor, true) sc.CreationTimestamp = created sc.Finalizers = finalizers return sc } - using := func(name string) []atev1alpha1.WorkerPoolSandboxClassStatus { - return []atev1alpha1.WorkerPoolSandboxClassStatus{{ - Name: atev1alpha1.SandboxClassGvisor, - ConfigRef: &atev1alpha1.SandboxConfigReference{Name: name}, + using := func(name string) []atev1.WorkerPoolSandboxClassStatus { + return []atev1.WorkerPoolSandboxClassStatus{{ + Name: atev1.SandboxClassGvisor, + ConfigRef: &atev1.SandboxConfigReference{Name: name}, }} } tests := []struct { name string // newDefault is the config the pool resolves to from the cache. - newDefault *atev1alpha1.SandboxConfig + newDefault *atev1.SandboxConfig // pinned sets the pool's configRef to newDefault. pinned bool // status is the pool's status before the reconcile. - status []atev1alpha1.WorkerPoolSandboxClassStatus + status []atev1.WorkerPoolSandboxClassStatus // deletedBefore marks newDefault for deletion before the reconcile. deletedBefore bool // deleteDuringWrite deletes newDefault just before the first status @@ -515,7 +515,7 @@ func TestReconcileConfigDeletedBeforeClaim(t *testing.T) { wp := makeWorkerPool("pool", "default", 1, "worker:v1") wp.Status.SandboxClasses = tc.status if tc.pinned { - wp.Spec.SandboxClasses[0].ConfigRef = &atev1alpha1.SandboxConfigReference{Name: tc.newDefault.Name} + wp.Spec.SandboxClasses[0].ConfigRef = &atev1.SandboxConfigReference{Name: tc.newDefault.Name} } newDefault := tc.newDefault.DeepCopy() if tc.deletedBefore { @@ -525,8 +525,8 @@ func TestReconcileConfigDeletedBeforeClaim(t *testing.T) { c := fake.NewClientBuilder().WithScheme(scheme). WithObjects(wp, newDefault, config("old-default", t0)). WithStatusSubresource(wp). - WithIndex(&atev1alpha1.WorkerPool{}, workerPoolSandboxConfigIndex, func(obj client.Object) []string { - return sandboxConfigsInUse(obj.(*atev1alpha1.WorkerPool)) + WithIndex(&atev1.WorkerPool{}, workerPoolSandboxConfigIndex, func(obj client.Object) []string { + return sandboxConfigsInUse(obj.(*atev1.WorkerPool)) }). WithInterceptorFuncs(interceptor.Funcs{ SubResourceUpdate: func(ctx context.Context, c client.Client, sub string, obj client.Object, opts ...client.SubResourceUpdateOption) error { @@ -553,11 +553,11 @@ func TestReconcileConfigDeletedBeforeClaim(t *testing.T) { if tc.deleteDuringWrite && !deleted { t.Fatalf("status was never written, so nothing was deleted") } - got := &atev1alpha1.WorkerPool{} + got := &atev1.WorkerPool{} if err := c.Get(t.Context(), client.ObjectKeyFromObject(wp), got); err != nil { t.Fatalf("get WorkerPool: %v", err) } - if name := statusConfig(got, atev1alpha1.SandboxClassGvisor); name != want { + if name := statusConfig(got, atev1.SandboxClassGvisor); name != want { t.Errorf("after reconcile %d, status names %q, want %q", i+1, name, want) } for _, class := range got.Status.SandboxClasses { @@ -609,15 +609,15 @@ func TestSandboxConfigReleasedWhenUnused(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() for _, name := range tc.configs { - createSandboxConfig(t, makeSandboxConfig(name, atev1alpha1.SandboxClassGvisor, false)) + createSandboxConfig(t, makeSandboxConfig(name, atev1.SandboxClassGvisor, false)) } wp := makeWorkerPool(tc.pool, "default", 1, "worker:v1") - wp.Spec.SandboxClasses[0].ConfigRef = &atev1alpha1.SandboxConfigReference{Name: tc.ref} + wp.Spec.SandboxClasses[0].ConfigRef = &atev1.SandboxConfigReference{Name: tc.ref} createWorkerPool(t, wp) waitResolvedAndDeployed(t, wp, tc.ref) if tc.switchTo != "" { - updateWorkerPoolSpec(t, t.Context(), wp, "switch configRef", func(wp *atev1alpha1.WorkerPool) { + updateWorkerPoolSpec(t, t.Context(), wp, "switch configRef", func(wp *atev1.WorkerPool) { wp.Spec.SandboxClasses[0].ConfigRef.Name = tc.switchTo }) waitResolved(t, wp, tc.switchTo) @@ -625,15 +625,15 @@ func TestSandboxConfigReleasedWhenUnused(t *testing.T) { } if tc.release != tc.ref { // Never used, so never protected. - got := &atev1alpha1.SandboxConfig{} + got := &atev1.SandboxConfig{} if err := k8sClient.Get(t.Context(), types.NamespacedName{Name: tc.release}, got); err != nil { t.Fatalf("get SandboxConfig: %v", err) } - if controllerutil.ContainsFinalizer(got, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) { + if controllerutil.ContainsFinalizer(got, atev1.SandboxConfigWorkerPoolProtectionFinalizer) { t.Fatalf("unused SandboxConfig %s carries the protection finalizer", tc.release) } } - deleteAndWait(t, &atev1alpha1.SandboxConfig{ObjectMeta: metav1.ObjectMeta{Name: tc.release}}) + deleteAndWait(t, &atev1.SandboxConfig{ObjectMeta: metav1.ObjectMeta{Name: tc.release}}) }) } } @@ -648,7 +648,7 @@ func TestWorkerPoolConfigRef(t *testing.T) { tests := []struct { name string // config is created before the pool. nil creates none. - config *atev1alpha1.SandboxConfig + config *atev1.SandboxConfig // deleting marks config for deletion before the pool is created. deleting bool ref string @@ -657,31 +657,31 @@ func TestWorkerPoolConfigRef(t *testing.T) { wantReason string // late is created once the pool reports wantReason. The pool must // then resolve to it. - late *atev1alpha1.SandboxConfig + late *atev1.SandboxConfig }{ { name: "existing config of the same class", - config: makeSandboxConfig("ref-ok", atev1alpha1.SandboxClassGvisor, false), + config: makeSandboxConfig("ref-ok", atev1.SandboxClassGvisor, false), ref: "ref-ok", }, { name: "missing config, created later", ref: "ref-late", - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigNotFound, - late: makeSandboxConfig("ref-late", atev1alpha1.SandboxClassGvisor, false), + wantReason: atev1.WorkerPoolReasonSandboxConfigNotFound, + late: makeSandboxConfig("ref-late", atev1.SandboxClassGvisor, false), }, { name: "config of another class", - config: makeSandboxConfig("ref-vm", atev1alpha1.SandboxClassMicroVM, false), + config: makeSandboxConfig("ref-vm", atev1.SandboxClassMicroVM, false), ref: "ref-vm", - wantReason: atev1alpha1.WorkerPoolReasonSandboxClassMismatch, + wantReason: atev1.WorkerPoolReasonSandboxClassMismatch, }, { name: "config being deleted", - config: makeSandboxConfig("ref-dying", atev1alpha1.SandboxClassGvisor, false), + config: makeSandboxConfig("ref-dying", atev1.SandboxClassGvisor, false), deleting: true, ref: "ref-dying", - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, }, } for _, tc := range tests { @@ -700,7 +700,7 @@ func TestWorkerPoolConfigRef(t *testing.T) { } } wp := makeWorkerPool("test-configref-"+tc.ref, "default", 1, "worker:v1") - wp.Spec.SandboxClasses[0].ConfigRef = &atev1alpha1.SandboxConfigReference{Name: tc.ref} + wp.Spec.SandboxClasses[0].ConfigRef = &atev1.SandboxConfigReference{Name: tc.ref} createWorkerPool(t, wp) if tc.wantReason == "" { @@ -708,7 +708,7 @@ func TestWorkerPoolConfigRef(t *testing.T) { return } current := waitUnresolved(t, wp, tc.wantReason) - if got := statusConfig(current, atev1alpha1.SandboxClassGvisor); got != "" { + if got := statusConfig(current, atev1.SandboxClassGvisor); got != "" { t.Errorf("status.sandboxClasses names %q, want no config for a pool that never resolved", got) } assertNoDeployment(t, wp) @@ -723,7 +723,7 @@ func TestWorkerPoolConfigRef(t *testing.T) { // waitResolvedAndDeployed waits for wp to resolve to config, for config to // carry the protection finalizer, and for wp's Deployment to exist. -func waitResolvedAndDeployed(t *testing.T, wp *atev1alpha1.WorkerPool, config string) { +func waitResolvedAndDeployed(t *testing.T, wp *atev1.WorkerPool, config string) { t.Helper() waitResolved(t, wp, config) waitProtectionFinalizer(t, config, true) @@ -734,7 +734,7 @@ func waitResolvedAndDeployed(t *testing.T, wp *atev1alpha1.WorkerPool, config st } // waitWarningEvent waits for a Warning event with reason about wp. -func waitWarningEvent(t *testing.T, wp *atev1alpha1.WorkerPool, reason string) { +func waitWarningEvent(t *testing.T, wp *atev1.WorkerPool, reason string) { t.Helper() eventually(t, func(ctx context.Context) (bool, error) { var evs eventsv1.EventList @@ -761,7 +761,7 @@ func TestWorkerPoolUnresolvedKeepsConfigInUse(t *testing.T) { pool string // config is created with testHoldFinalizer and named by the pool's // configRef. nil leaves the pool on the class default. - config *atev1alpha1.SandboxConfig + config *atev1.SandboxConfig // missingRef, if set, breaks resolution by pointing configRef at a // config that does not exist, in the same update that scales the // pool. Otherwise config is deleted and the pool scaled afterwards. @@ -774,14 +774,14 @@ func TestWorkerPoolUnresolvedKeepsConfigInUse(t *testing.T) { pool: "test-unresolved-keeps", missingRef: "never-created", replicas: 5, - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigNotFound, + wantReason: atev1.WorkerPoolReasonSandboxConfigNotFound, }, { name: "config in use marked for deletion", pool: "test-ref-deleting-in-use", - config: makeSandboxConfig("dying-in-use", atev1alpha1.SandboxClassGvisor, false), + config: makeSandboxConfig("dying-in-use", atev1.SandboxClassGvisor, false), replicas: 3, - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, }, } for _, tc := range tests { @@ -795,28 +795,28 @@ func TestWorkerPoolUnresolvedKeepsConfigInUse(t *testing.T) { createSandboxConfig(t, tc.config) t.Cleanup(func() { removeFinalizer(t, tc.config.Name, testHoldFinalizer) }) inUse = tc.config.Name - wp.Spec.SandboxClasses[0].ConfigRef = &atev1alpha1.SandboxConfigReference{Name: inUse} + wp.Spec.SandboxClasses[0].ConfigRef = &atev1.SandboxConfigReference{Name: inUse} } createWorkerPool(t, wp) waitResolvedAndDeployed(t, wp, inUse) if tc.missingRef != "" { - updateWorkerPoolSpec(t, ctx, wp, "point WorkerPool at a missing SandboxConfig and scale it", func(wp *atev1alpha1.WorkerPool) { + updateWorkerPoolSpec(t, ctx, wp, "point WorkerPool at a missing SandboxConfig and scale it", func(wp *atev1.WorkerPool) { wp.Spec.Replicas = tc.replicas - wp.Spec.SandboxClasses[0].ConfigRef = &atev1alpha1.SandboxConfigReference{Name: tc.missingRef} + wp.Spec.SandboxClasses[0].ConfigRef = &atev1.SandboxConfigReference{Name: tc.missingRef} }) } else if err := k8sClient.Delete(ctx, tc.config); err != nil { t.Fatalf("delete SandboxConfig: %v", err) } current := waitUnresolved(t, wp, tc.wantReason) - if got := statusConfig(current, atev1alpha1.SandboxClassGvisor); got != inUse { + if got := statusConfig(current, atev1.SandboxClassGvisor); got != inUse { t.Errorf("status.sandboxClasses names %q, want the config in use %q", got, inUse) } waitWarningEvent(t, wp, tc.wantReason) waitProtectionFinalizer(t, inUse, true) if tc.missingRef == "" { - updateWorkerPoolSpec(t, ctx, wp, "scale WorkerPool", func(wp *atev1alpha1.WorkerPool) { + updateWorkerPoolSpec(t, ctx, wp, "scale WorkerPool", func(wp *atev1.WorkerPool) { wp.Spec.Replicas = tc.replicas }) } @@ -826,7 +826,7 @@ func TestWorkerPoolUnresolvedKeepsConfigInUse(t *testing.T) { } // waitDeploymentReplicas waits for wp's Deployment to ask for replicas pods. -func waitDeploymentReplicas(t *testing.T, wp *atev1alpha1.WorkerPool, replicas int32) { +func waitDeploymentReplicas(t *testing.T, wp *atev1.WorkerPool, replicas int32) { t.Helper() eventually(t, func(ctx context.Context) (bool, error) { dep, err := getDeployment(ctx, wp) @@ -868,18 +868,18 @@ func TestSandboxConfigInUseProtection(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() ctx := t.Context() - sc := makeSandboxConfig(tc.config, atev1alpha1.SandboxClassGvisor, false) + sc := makeSandboxConfig(tc.config, atev1.SandboxClassGvisor, false) createSandboxConfig(t, sc) - sentinel := makeSandboxConfig(tc.sentinel, atev1alpha1.SandboxClassGvisor, false) + sentinel := makeSandboxConfig(tc.sentinel, atev1.SandboxClassGvisor, false) createSandboxConfig(t, sentinel) - newPool := func(name, config string) *atev1alpha1.WorkerPool { + newPool := func(name, config string) *atev1.WorkerPool { wp := makeWorkerPool(name, "default", 1, "worker:v1") - wp.Spec.SandboxClasses[0].ConfigRef = &atev1alpha1.SandboxConfigReference{Name: config} + wp.Spec.SandboxClasses[0].ConfigRef = &atev1.SandboxConfigReference{Name: config} createWorkerPool(t, wp) waitResolved(t, wp, config) return wp } - var users []*atev1alpha1.WorkerPool + var users []*atev1.WorkerPool for _, name := range tc.users { users = append(users, newPool(name, sc.Name)) } @@ -887,7 +887,7 @@ func TestSandboxConfigInUseProtection(t *testing.T) { waitProtectionFinalizer(t, sc.Name, true) waitProtectionFinalizer(t, sentinel.Name, true) - for _, c := range []*atev1alpha1.SandboxConfig{sc, sentinel} { + for _, c := range []*atev1.SandboxConfig{sc, sentinel} { if err := k8sClient.Delete(ctx, c); err != nil { t.Fatalf("delete SandboxConfig %s: %v", c.Name, err) } @@ -900,7 +900,7 @@ func TestSandboxConfigInUseProtection(t *testing.T) { waitGone(t, sentinel) // The shared config has been reconciled for every other user's // deletion. It must stay for the last one. - got := &atev1alpha1.SandboxConfig{} + got := &atev1.SandboxConfig{} if err := k8sClient.Get(ctx, types.NamespacedName{Name: sc.Name}, got); err != nil { t.Fatalf("SandboxConfig still used by %s: get: %v", last.Name, err) } @@ -920,19 +920,19 @@ func TestSandboxConfigInUseProtection(t *testing.T) { // defaults and checks the pool's resolution afterwards. It is not parallel // because it owns the microvm class default. func TestWorkerPoolDefaultNewestWins(t *testing.T) { - mvdefA := makeSandboxConfig("mvdef-a", atev1alpha1.SandboxClassMicroVM, true) - mvdefB := makeSandboxConfig("mvdef-b", atev1alpha1.SandboxClassMicroVM, true) + mvdefA := makeSandboxConfig("mvdef-a", atev1.SandboxClassMicroVM, true) + mvdefB := makeSandboxConfig("mvdef-b", atev1.SandboxClassMicroVM, true) // The steps create the configs, but they outlive each step. deleteOnCleanup(t, mvdefA) deleteOnCleanup(t, mvdefB) - create := func(t *testing.T, sc *atev1alpha1.SandboxConfig) { + create := func(t *testing.T, sc *atev1.SandboxConfig) { t.Helper() if err := k8sClient.Create(t.Context(), sc); err != nil { t.Fatalf("create SandboxConfig %s: %v", sc.Name, err) } } wp := makeWorkerPool("test-default-newest", "default", 1, "worker:v1") - wp.Spec.SandboxClasses[0].Name = atev1alpha1.SandboxClassMicroVM + wp.Spec.SandboxClasses[0].Name = atev1.SandboxClassMicroVM createWorkerPool(t, wp) steps := []struct { @@ -947,7 +947,7 @@ func TestWorkerPoolDefaultNewestWins(t *testing.T) { }{ { name: "no class default", - wantReason: atev1alpha1.WorkerPoolReasonDefaultConfigNotFound, + wantReason: atev1.WorkerPoolReasonDefaultConfigNotFound, }, { name: "a class default appears", @@ -978,17 +978,17 @@ func TestWorkerPoolDefaultNewestWins(t *testing.T) { } }, wantConfig: "mvdef-b", - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, }, { name: "no default left: the config in use is kept", act: func(t *testing.T) { err := retry.RetryOnConflict(retry.DefaultBackoff, func() error { - sc := &atev1alpha1.SandboxConfig{} + sc := &atev1.SandboxConfig{} if err := k8sClient.Get(t.Context(), types.NamespacedName{Name: "mvdef-b"}, sc); err != nil { return err } - delete(sc.Annotations, atev1alpha1.SandboxConfigClassDefaultAnnotation) + delete(sc.Annotations, atev1.SandboxConfigClassDefaultAnnotation) return k8sClient.Update(t.Context(), sc) }) if err != nil { @@ -996,7 +996,7 @@ func TestWorkerPoolDefaultNewestWins(t *testing.T) { } }, wantConfig: "mvdef-b", - wantReason: atev1alpha1.WorkerPoolReasonDefaultConfigNotFound, + wantReason: atev1.WorkerPoolReasonDefaultConfigNotFound, }, } for _, step := range steps { @@ -1010,7 +1010,7 @@ func TestWorkerPoolDefaultNewestWins(t *testing.T) { return } current := waitUnresolved(t, wp, step.wantReason) - if got := statusConfig(current, atev1alpha1.SandboxClassMicroVM); got != step.wantConfig { + if got := statusConfig(current, atev1.SandboxClassMicroVM); got != step.wantConfig { t.Errorf("status.sandboxClasses names %q, want %q", got, step.wantConfig) } waitWarningEvent(t, wp, step.wantReason) @@ -1031,64 +1031,64 @@ func TestWorkerPoolDefaultNewestWins(t *testing.T) { // event can concern a WorkerPool. func TestWorkerPoolMayUseSandboxConfig(t *testing.T) { t.Parallel() - sc := makeSandboxConfig("sc", atev1alpha1.SandboxClassGvisor, false) - gvisor := atev1alpha1.WorkerPoolSandboxClass{Name: atev1alpha1.SandboxClassGvisor} - microvm := atev1alpha1.WorkerPoolSandboxClass{Name: atev1alpha1.SandboxClassMicroVM} - withRef := func(e atev1alpha1.WorkerPoolSandboxClass, name string) atev1alpha1.WorkerPoolSandboxClass { - e.ConfigRef = &atev1alpha1.SandboxConfigReference{Name: name} + sc := makeSandboxConfig("sc", atev1.SandboxClassGvisor, false) + gvisor := atev1.WorkerPoolSandboxClass{Name: atev1.SandboxClassGvisor} + microvm := atev1.WorkerPoolSandboxClass{Name: atev1.SandboxClassMicroVM} + withRef := func(e atev1.WorkerPoolSandboxClass, name string) atev1.WorkerPoolSandboxClass { + e.ConfigRef = &atev1.SandboxConfigReference{Name: name} return e } - using := func(name string) atev1alpha1.WorkerPoolSandboxClassStatus { - return atev1alpha1.WorkerPoolSandboxClassStatus{Name: atev1alpha1.SandboxClassMicroVM, ConfigRef: &atev1alpha1.SandboxConfigReference{Name: name}} + using := func(name string) atev1.WorkerPoolSandboxClassStatus { + return atev1.WorkerPoolSandboxClassStatus{Name: atev1.SandboxClassMicroVM, ConfigRef: &atev1.SandboxConfigReference{Name: name}} } tests := []struct { name string - spec []atev1alpha1.WorkerPoolSandboxClass - status []atev1alpha1.WorkerPoolSandboxClassStatus + spec []atev1.WorkerPoolSandboxClass + status []atev1.WorkerPoolSandboxClassStatus want bool }{ { name: "runs the config's class", - spec: []atev1alpha1.WorkerPoolSandboxClass{gvisor}, + spec: []atev1.WorkerPoolSandboxClass{gvisor}, want: true, }, { name: "runs the config's class with another ref", - spec: []atev1alpha1.WorkerPoolSandboxClass{withRef(gvisor, "other")}, + spec: []atev1.WorkerPoolSandboxClass{withRef(gvisor, "other")}, want: true, }, { name: "spec names the config", - spec: []atev1alpha1.WorkerPoolSandboxClass{withRef(microvm, "sc")}, + spec: []atev1.WorkerPoolSandboxClass{withRef(microvm, "sc")}, want: true, }, { name: "status names the config", - spec: []atev1alpha1.WorkerPoolSandboxClass{microvm}, - status: []atev1alpha1.WorkerPoolSandboxClassStatus{using("sc")}, + spec: []atev1.WorkerPoolSandboxClass{microvm}, + status: []atev1.WorkerPoolSandboxClassStatus{using("sc")}, want: true, }, { name: "status claims the config", - spec: []atev1alpha1.WorkerPoolSandboxClass{microvm}, - status: []atev1alpha1.WorkerPoolSandboxClassStatus{{ - Name: atev1alpha1.SandboxClassMicroVM, - ConfigRef: &atev1alpha1.SandboxConfigReference{Name: "other"}, - PendingConfigRef: &atev1alpha1.SandboxConfigReference{Name: "sc"}, + spec: []atev1.WorkerPoolSandboxClass{microvm}, + status: []atev1.WorkerPoolSandboxClassStatus{{ + Name: atev1.SandboxClassMicroVM, + ConfigRef: &atev1.SandboxConfigReference{Name: "other"}, + PendingConfigRef: &atev1.SandboxConfigReference{Name: "sc"}, }}, want: true, }, { name: "another class, another config", - spec: []atev1alpha1.WorkerPoolSandboxClass{withRef(microvm, "other")}, - status: []atev1alpha1.WorkerPoolSandboxClassStatus{using("other")}, + spec: []atev1.WorkerPoolSandboxClass{withRef(microvm, "other")}, + status: []atev1.WorkerPoolSandboxClassStatus{using("other")}, want: false, }, { name: "another class, no config in use", - spec: []atev1alpha1.WorkerPoolSandboxClass{withRef(microvm, "other")}, - status: []atev1alpha1.WorkerPoolSandboxClassStatus{{Name: atev1alpha1.SandboxClassMicroVM}}, + spec: []atev1.WorkerPoolSandboxClass{withRef(microvm, "other")}, + status: []atev1.WorkerPoolSandboxClassStatus{{Name: atev1.SandboxClassMicroVM}}, want: false, }, { @@ -1113,13 +1113,13 @@ func TestWorkerPoolMayUseSandboxConfig(t *testing.T) { func TestWorkerPoolsForSandboxConfig(t *testing.T) { t.Parallel() scheme := runtime.NewScheme() - if err := atev1alpha1.AddToScheme(scheme); err != nil { + if err := atev1.AddToScheme(scheme); err != nil { t.Fatalf("add scheme: %v", err) } - gvisor := []atev1alpha1.WorkerPoolSandboxClass{{Name: atev1alpha1.SandboxClassGvisor}} - microvm := []atev1alpha1.WorkerPoolSandboxClass{{Name: atev1alpha1.SandboxClassMicroVM}} - microvmRef := []atev1alpha1.WorkerPoolSandboxClass{{Name: atev1alpha1.SandboxClassMicroVM, ConfigRef: &atev1alpha1.SandboxConfigReference{Name: "sc"}}} - usingSC := []atev1alpha1.WorkerPoolSandboxClassStatus{{Name: atev1alpha1.SandboxClassMicroVM, ConfigRef: &atev1alpha1.SandboxConfigReference{Name: "sc"}}} + gvisor := []atev1.WorkerPoolSandboxClass{{Name: atev1.SandboxClassGvisor}} + microvm := []atev1.WorkerPoolSandboxClass{{Name: atev1.SandboxClassMicroVM}} + microvmRef := []atev1.WorkerPoolSandboxClass{{Name: atev1.SandboxClassMicroVM, ConfigRef: &atev1.SandboxConfigReference{Name: "sc"}}} + usingSC := []atev1.WorkerPoolSandboxClassStatus{{Name: atev1.SandboxClassMicroVM, ConfigRef: &atev1.SandboxConfigReference{Name: "sc"}}} // newReconciler returns a reconciler whose List fails with listErr, if set. newReconciler := func(listErr error) *WorkerPoolReconciler { return &WorkerPoolReconciler{Client: fake.NewClientBuilder().WithScheme(scheme).WithObjects( @@ -1149,12 +1149,12 @@ func TestWorkerPoolsForSandboxConfig(t *testing.T) { }{ { name: "gvisor config: its class and the pools naming it", - obj: makeSandboxConfig("sc", atev1alpha1.SandboxClassGvisor, false), + obj: makeSandboxConfig("sc", atev1.SandboxClassGvisor, false), want: []reconcile.Request{req("a", "gv"), req("b", "vm-ref"), req("b", "vm-status")}, }, { name: "microvm config: every microvm pool", - obj: makeSandboxConfig("other", atev1alpha1.SandboxClassMicroVM, false), + obj: makeSandboxConfig("other", atev1.SandboxClassMicroVM, false), want: []reconcile.Request{req("b", "vm"), req("b", "vm-ref"), req("b", "vm-status")}, }, { @@ -1163,7 +1163,7 @@ func TestWorkerPoolsForSandboxConfig(t *testing.T) { }, { name: "list fails: nothing", - obj: makeSandboxConfig("sc", atev1alpha1.SandboxClassGvisor, false), + obj: makeSandboxConfig("sc", atev1.SandboxClassGvisor, false), listErr: errors.New("list failed"), }, } @@ -1187,27 +1187,27 @@ func TestWorkerPoolsForSandboxConfig(t *testing.T) { func TestRecordSandboxConfigEvents(t *testing.T) { t.Parallel() failed := metav1.Condition{ - Type: atev1alpha1.WorkerPoolSandboxClassConditionResolved, + Type: atev1.WorkerPoolSandboxClassConditionResolved, Status: metav1.ConditionFalse, - Reason: atev1alpha1.WorkerPoolReasonSandboxConfigNotFound, + Reason: atev1.WorkerPoolReasonSandboxConfigNotFound, Message: `SandboxConfig "x" not found`, } resolved := func(config string) metav1.Condition { return metav1.Condition{ - Type: atev1alpha1.WorkerPoolSandboxClassConditionResolved, + Type: atev1.WorkerPoolSandboxClassConditionResolved, Status: metav1.ConditionTrue, - Reason: atev1alpha1.WorkerPoolReasonResolved, + Reason: atev1.WorkerPoolReasonResolved, Message: fmt.Sprintf("resolved to SandboxConfig %q", config), } } // class builds a gvisor status entry using config ("" for none) with // cond. - class := func(config string, cond metav1.Condition) []atev1alpha1.WorkerPoolSandboxClassStatus { - status := atev1alpha1.WorkerPoolSandboxClassStatus{Name: atev1alpha1.SandboxClassGvisor, Conditions: []metav1.Condition{cond}} + class := func(config string, cond metav1.Condition) []atev1.WorkerPoolSandboxClassStatus { + status := atev1.WorkerPoolSandboxClassStatus{Name: atev1.SandboxClassGvisor, Conditions: []metav1.Condition{cond}} if config != "" { - status.ConfigRef = &atev1alpha1.SandboxConfigReference{Name: config} + status.ConfigRef = &atev1.SandboxConfigReference{Name: config} } - return []atev1alpha1.WorkerPoolSandboxClassStatus{status} + return []atev1.WorkerPoolSandboxClassStatus{status} } with := func(reason, message string) metav1.Condition { c := failed @@ -1220,8 +1220,8 @@ func TestRecordSandboxConfigEvents(t *testing.T) { tests := []struct { name string // prev is the pool's status before the reconcile. - prev []atev1alpha1.WorkerPoolSandboxClassStatus - classes []atev1alpha1.WorkerPoolSandboxClassStatus + prev []atev1.WorkerPoolSandboxClassStatus + classes []atev1.WorkerPoolSandboxClassStatus want []string }{ { @@ -1269,7 +1269,7 @@ func TestRecordSandboxConfigEvents(t *testing.T) { }, { name: "another reason", - prev: class("", with(atev1alpha1.WorkerPoolReasonSandboxClassMismatch, failed.Message)), + prev: class("", with(atev1.WorkerPoolReasonSandboxClassMismatch, failed.Message)), classes: class("", failed), want: []string{warning}, }, @@ -1314,7 +1314,7 @@ func TestReconcileReportsSwitchOnceWritten(t *testing.T) { if err := clientgoscheme.AddToScheme(scheme); err != nil { t.Fatalf("add client-go scheme: %v", err) } - if err := atev1alpha1.AddToScheme(scheme); err != nil { + if err := atev1.AddToScheme(scheme); err != nil { t.Fatalf("add scheme: %v", err) } tests := []struct { @@ -1331,19 +1331,19 @@ func TestReconcileReportsSwitchOnceWritten(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() wp := makeWorkerPoolClasses("default", "pool", - []atev1alpha1.WorkerPoolSandboxClass{{Name: atev1alpha1.SandboxClassGvisor, ConfigRef: &atev1alpha1.SandboxConfigReference{Name: "y"}}}, - []atev1alpha1.WorkerPoolSandboxClassStatus{{Name: atev1alpha1.SandboxClassGvisor, ConfigRef: &atev1alpha1.SandboxConfigReference{Name: "x"}}}) + []atev1.WorkerPoolSandboxClass{{Name: atev1.SandboxClassGvisor, ConfigRef: &atev1.SandboxConfigReference{Name: "y"}}}, + []atev1.WorkerPoolSandboxClassStatus{{Name: atev1.SandboxClassGvisor, ConfigRef: &atev1.SandboxConfigReference{Name: "x"}}}) objs := []client.Object{wp, - makeSandboxConfig("x", atev1alpha1.SandboxClassGvisor, false), - makeSandboxConfig("y", atev1alpha1.SandboxClassGvisor, false), + makeSandboxConfig("x", atev1.SandboxClassGvisor, false), + makeSandboxConfig("y", atev1.SandboxClassGvisor, false), } rejected := 0 c := fake.NewClientBuilder().WithScheme(scheme).WithObjects(objs...).WithStatusSubresource(wp). WithInterceptorFuncs(interceptor.Funcs{ SubResourceUpdate: func(ctx context.Context, c client.Client, sub string, obj client.Object, opts ...client.SubResourceUpdateOption) error { - if pool, ok := obj.(*atev1alpha1.WorkerPool); ok && rejected < tc.rejected && statusConfig(pool, atev1alpha1.SandboxClassGvisor) == "y" { + if pool, ok := obj.(*atev1.WorkerPool); ok && rejected < tc.rejected && statusConfig(pool, atev1.SandboxClassGvisor) == "y" { rejected++ - return k8errors.NewConflict(atev1alpha1.GroupVersion.WithResource("workerpools").GroupResource(), pool.Name, errors.New("stale")) + return k8errors.NewConflict(atev1.GroupVersion.WithResource("workerpools").GroupResource(), pool.Name, errors.New("stale")) } return c.SubResource(sub).Update(ctx, obj, opts...) }, @@ -1371,11 +1371,11 @@ func TestReconcileReportsSwitchOnceWritten(t *testing.T) { if !slices.Equal(got, want) { t.Errorf("events = %q, want %q", got, want) } - current := &atev1alpha1.WorkerPool{} + current := &atev1.WorkerPool{} if err := c.Get(t.Context(), client.ObjectKeyFromObject(wp), current); err != nil { t.Fatalf("get WorkerPool: %v", err) } - if name := statusConfig(current, atev1alpha1.SandboxClassGvisor); name != "y" { + if name := statusConfig(current, atev1.SandboxClassGvisor); name != "y" { t.Errorf("status names %q, want %q", name, "y") } }) @@ -1390,16 +1390,16 @@ func TestResolveSandboxClasses(t *testing.T) { t.Parallel() const generation = 3 earlier := metav1.NewTime(time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)) - configs := []atev1alpha1.SandboxConfig{*makeSandboxConfig("def", atev1alpha1.SandboxClassGvisor, true)} - ref := func(name string) *atev1alpha1.SandboxConfigReference { + configs := []atev1.SandboxConfig{*makeSandboxConfig("def", atev1.SandboxClassGvisor, true)} + ref := func(name string) *atev1.SandboxConfigReference { if name == "" { return nil } - return &atev1alpha1.SandboxConfigReference{Name: name} + return &atev1.SandboxConfigReference{Name: name} } cond := func(status metav1.ConditionStatus, reason, message string, gen int64, at metav1.Time) metav1.Condition { return metav1.Condition{ - Type: atev1alpha1.WorkerPoolSandboxClassConditionResolved, + Type: atev1.WorkerPoolSandboxClassConditionResolved, Status: status, Reason: reason, Message: message, @@ -1408,10 +1408,10 @@ func TestResolveSandboxClasses(t *testing.T) { } } resolvedDef := func(gen int64, at metav1.Time) metav1.Condition { - return cond(metav1.ConditionTrue, atev1alpha1.WorkerPoolReasonResolved, `resolved to SandboxConfig "def"`, gen, at) + return cond(metav1.ConditionTrue, atev1.WorkerPoolReasonResolved, `resolved to SandboxConfig "def"`, gen, at) } notFound := func(message string, gen int64, at metav1.Time) metav1.Condition { - return cond(metav1.ConditionFalse, atev1alpha1.WorkerPoolReasonSandboxConfigNotFound, message, gen, at) + return cond(metav1.ConditionFalse, atev1.WorkerPoolReasonSandboxConfigNotFound, message, gen, at) } // now stands for a lastTransitionTime set during the call. var now metav1.Time @@ -1420,32 +1420,32 @@ func TestResolveSandboxClasses(t *testing.T) { name string // specRef is the pool's configRef. "" follows the class default. specRef string - prev []atev1alpha1.WorkerPoolSandboxClassStatus - want []atev1alpha1.WorkerPoolSandboxClassStatus + prev []atev1.WorkerPoolSandboxClassStatus + want []atev1.WorkerPoolSandboxClassStatus // wantResolved is the second return value. wantResolved bool }{ { name: "first resolve", - want: []atev1alpha1.WorkerPoolSandboxClassStatus{{Name: atev1alpha1.SandboxClassGvisor, ConfigRef: ref("def"), Conditions: []metav1.Condition{resolvedDef(generation, now)}}}, + want: []atev1.WorkerPoolSandboxClassStatus{{Name: atev1.SandboxClassGvisor, ConfigRef: ref("def"), Conditions: []metav1.Condition{resolvedDef(generation, now)}}}, wantResolved: true, }, { name: "still resolved keeps lastTransitionTime", - prev: []atev1alpha1.WorkerPoolSandboxClassStatus{{Name: atev1alpha1.SandboxClassGvisor, ConfigRef: ref("def"), Conditions: []metav1.Condition{resolvedDef(generation-1, earlier)}}}, - want: []atev1alpha1.WorkerPoolSandboxClassStatus{{Name: atev1alpha1.SandboxClassGvisor, ConfigRef: ref("def"), Conditions: []metav1.Condition{resolvedDef(generation, earlier)}}}, + prev: []atev1.WorkerPoolSandboxClassStatus{{Name: atev1.SandboxClassGvisor, ConfigRef: ref("def"), Conditions: []metav1.Condition{resolvedDef(generation-1, earlier)}}}, + want: []atev1.WorkerPoolSandboxClassStatus{{Name: atev1.SandboxClassGvisor, ConfigRef: ref("def"), Conditions: []metav1.Condition{resolvedDef(generation, earlier)}}}, wantResolved: true, }, { name: "never resolved records no config", specRef: "missing", - want: []atev1alpha1.WorkerPoolSandboxClassStatus{{Name: atev1alpha1.SandboxClassGvisor, Conditions: []metav1.Condition{notFound(`SandboxConfig "missing" not found`, generation, now)}}}, + want: []atev1.WorkerPoolSandboxClassStatus{{Name: atev1.SandboxClassGvisor, Conditions: []metav1.Condition{notFound(`SandboxConfig "missing" not found`, generation, now)}}}, }, { name: "stops resolving keeps the config and moves lastTransitionTime", specRef: "missing", - prev: []atev1alpha1.WorkerPoolSandboxClassStatus{{Name: atev1alpha1.SandboxClassGvisor, ConfigRef: ref("def"), Conditions: []metav1.Condition{resolvedDef(generation-1, earlier)}}}, - want: []atev1alpha1.WorkerPoolSandboxClassStatus{{Name: atev1alpha1.SandboxClassGvisor, ConfigRef: ref("def"), Conditions: []metav1.Condition{notFound(`SandboxConfig "missing" not found; keeping "def"`, generation, now)}}}, + prev: []atev1.WorkerPoolSandboxClassStatus{{Name: atev1.SandboxClassGvisor, ConfigRef: ref("def"), Conditions: []metav1.Condition{resolvedDef(generation-1, earlier)}}}, + want: []atev1.WorkerPoolSandboxClassStatus{{Name: atev1.SandboxClassGvisor, ConfigRef: ref("def"), Conditions: []metav1.Condition{notFound(`SandboxConfig "missing" not found; keeping "def"`, generation, now)}}}, }, } for _, tc := range tests { @@ -1481,21 +1481,21 @@ func TestResolveSandboxClasses(t *testing.T) { // class switches. func TestClaimSandboxConfigs(t *testing.T) { t.Parallel() - ref := func(name string) *atev1alpha1.SandboxConfigReference { + ref := func(name string) *atev1.SandboxConfigReference { if name == "" { return nil } - return &atev1alpha1.SandboxConfigReference{Name: name} + return &atev1.SandboxConfigReference{Name: name} } resolved := metav1.Condition{ - Type: atev1alpha1.WorkerPoolSandboxClassConditionResolved, + Type: atev1.WorkerPoolSandboxClassConditionResolved, Status: metav1.ConditionTrue, - Reason: atev1alpha1.WorkerPoolReasonResolved, + Reason: atev1.WorkerPoolReasonResolved, } // status builds the pool's single gvisor status entry. - status := func(configRef, pending string, conds ...metav1.Condition) []atev1alpha1.WorkerPoolSandboxClassStatus { - return []atev1alpha1.WorkerPoolSandboxClassStatus{{ - Name: atev1alpha1.SandboxClassGvisor, + status := func(configRef, pending string, conds ...metav1.Condition) []atev1.WorkerPoolSandboxClassStatus { + return []atev1.WorkerPoolSandboxClassStatus{{ + Name: atev1.SandboxClassGvisor, ConfigRef: ref(configRef), PendingConfigRef: ref(pending), Conditions: conds, @@ -1504,10 +1504,10 @@ func TestClaimSandboxConfigs(t *testing.T) { tests := []struct { name string - prev []atev1alpha1.WorkerPoolSandboxClassStatus + prev []atev1.WorkerPoolSandboxClassStatus // classes is the status resolveSandboxClasses built. - classes []atev1alpha1.WorkerPoolSandboxClassStatus - want []atev1alpha1.WorkerPoolSandboxClassStatus + classes []atev1.WorkerPoolSandboxClassStatus + want []atev1.WorkerPoolSandboxClassStatus }{ { name: "same config: no claim", @@ -1571,33 +1571,33 @@ func TestConfirmSandboxConfigSwitch(t *testing.T) { const generation = 3 now := metav1.Now() resolvedX := metav1.Condition{ - Type: atev1alpha1.WorkerPoolSandboxClassConditionResolved, + Type: atev1.WorkerPoolSandboxClassConditionResolved, Status: metav1.ConditionTrue, - Reason: atev1alpha1.WorkerPoolReasonResolved, + Reason: atev1.WorkerPoolReasonResolved, Message: `resolved to SandboxConfig "x"`, ObservedGeneration: generation, } // class is the entry resolveSandboxClasses built: switching to x. - class := atev1alpha1.WorkerPoolSandboxClassStatus{ - Name: atev1alpha1.SandboxClassGvisor, - ConfigRef: &atev1alpha1.SandboxConfigReference{Name: "x"}, + class := atev1.WorkerPoolSandboxClassStatus{ + Name: atev1.SandboxClassGvisor, + ConfigRef: &atev1.SandboxConfigReference{Name: "x"}, Conditions: []metav1.Condition{resolvedX}, } - onY := []atev1alpha1.WorkerPoolSandboxClassStatus{{ - Name: atev1alpha1.SandboxClassGvisor, - ConfigRef: &atev1alpha1.SandboxConfigReference{Name: "y"}, - PendingConfigRef: &atev1alpha1.SandboxConfigReference{Name: "x"}, + onY := []atev1.WorkerPoolSandboxClassStatus{{ + Name: atev1.SandboxClassGvisor, + ConfigRef: &atev1.SandboxConfigReference{Name: "y"}, + PendingConfigRef: &atev1.SandboxConfigReference{Name: "x"}, }} - x := makeSandboxConfig("x", atev1alpha1.SandboxClassGvisor, false) + x := makeSandboxConfig("x", atev1.SandboxClassGvisor, false) deletingX := x.DeepCopy() deletingX.DeletionTimestamp = &now - configs := []atev1alpha1.SandboxConfig{*makeSandboxConfig("y", atev1alpha1.SandboxClassGvisor, false), *x} + configs := []atev1.SandboxConfig{*makeSandboxConfig("y", atev1.SandboxClassGvisor, false), *x} tests := []struct { name string - prev []atev1alpha1.WorkerPoolSandboxClassStatus + prev []atev1.WorkerPoolSandboxClassStatus // live is x as read from the API server. nil means not found. - live *atev1alpha1.SandboxConfig + live *atev1.SandboxConfig // wantConfig is the config the class must end up using. wantConfig string wantReason string @@ -1608,14 +1608,14 @@ func TestConfirmSandboxConfigSwitch(t *testing.T) { prev: onY, live: x, wantConfig: "x", - wantReason: atev1alpha1.WorkerPoolReasonResolved, + wantReason: atev1.WorkerPoolReasonResolved, wantMessage: `resolved to SandboxConfig "x"`, }, { name: "not found: keeps the config in use", prev: onY, wantConfig: "y", - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigNotFound, + wantReason: atev1.WorkerPoolReasonSandboxConfigNotFound, wantMessage: `SandboxConfig "x" not found; keeping "y"`, }, { @@ -1623,21 +1623,21 @@ func TestConfirmSandboxConfigSwitch(t *testing.T) { prev: onY, live: deletingX, wantConfig: "y", - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, wantMessage: `SandboxConfig "x" is being deleted; keeping "y"`, }, { name: "now of another class: keeps the config in use", prev: onY, - live: makeSandboxConfig("x", atev1alpha1.SandboxClassMicroVM, false), + live: makeSandboxConfig("x", atev1.SandboxClassMicroVM, false), wantConfig: "y", - wantReason: atev1alpha1.WorkerPoolReasonSandboxClassMismatch, + wantReason: atev1.WorkerPoolReasonSandboxClassMismatch, wantMessage: `SandboxConfig "x" is for sandbox class "microvm", not "gvisor"; keeping "y"`, }, { name: "being deleted, new pool: no config", live: deletingX, - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, wantMessage: `SandboxConfig "x" is being deleted`, }, } @@ -1648,13 +1648,13 @@ func TestConfirmSandboxConfigSwitch(t *testing.T) { wp.Generation = generation wp.Status.SandboxClasses = tc.prev got := confirmSandboxConfigSwitch(wp, *class.DeepCopy(), tc.live, configs) - if name := ptr.Deref(got.ConfigRef, atev1alpha1.SandboxConfigReference{}).Name; name != tc.wantConfig { + if name := ptr.Deref(got.ConfigRef, atev1.SandboxConfigReference{}).Name; name != tc.wantConfig { t.Errorf("configRef = %q, want %q", name, tc.wantConfig) } if got.PendingConfigRef != nil { t.Errorf("pendingConfigRef = %q, want none", got.PendingConfigRef.Name) } - cond := meta.FindStatusCondition(got.Conditions, atev1alpha1.WorkerPoolSandboxClassConditionResolved) + cond := meta.FindStatusCondition(got.Conditions, atev1.WorkerPoolSandboxClassConditionResolved) if cond == nil { t.Fatalf("no Resolved condition in %+v", got.Conditions) } @@ -1677,20 +1677,20 @@ func TestReconcileConfirmsSwitch(t *testing.T) { if err := clientgoscheme.AddToScheme(scheme); err != nil { t.Fatalf("add client-go scheme: %v", err) } - if err := atev1alpha1.AddToScheme(scheme); err != nil { + if err := atev1.AddToScheme(scheme); err != nil { t.Fatalf("add scheme: %v", err) } now := metav1.Now() - protected := func(sc *atev1alpha1.SandboxConfig) *atev1alpha1.SandboxConfig { - controllerutil.AddFinalizer(sc, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) + protected := func(sc *atev1.SandboxConfig) *atev1.SandboxConfig { + controllerutil.AddFinalizer(sc, atev1.SandboxConfigWorkerPoolProtectionFinalizer) return sc } - deleting := func(sc *atev1alpha1.SandboxConfig) *atev1alpha1.SandboxConfig { + deleting := func(sc *atev1.SandboxConfig) *atev1.SandboxConfig { sc.DeletionTimestamp = &now return sc } - x := func() *atev1alpha1.SandboxConfig { - return protected(makeSandboxConfig("x", atev1alpha1.SandboxClassGvisor, false)) + x := func() *atev1.SandboxConfig { + return protected(makeSandboxConfig("x", atev1.SandboxClassGvisor, false)) } tests := []struct { @@ -1699,7 +1699,7 @@ func TestReconcileConfirmsSwitch(t *testing.T) { // "" for a new pool. inUse string // liveX is x on the API server. nil means it is gone. - liveX *atev1alpha1.SandboxConfig + liveX *atev1.SandboxConfig // wantRead is whether x must be read from the API server. wantRead bool wantConfig string @@ -1712,7 +1712,7 @@ func TestReconcileConfirmsSwitch(t *testing.T) { liveX: x(), wantRead: true, wantConfig: "x", - wantReason: atev1alpha1.WorkerPoolReasonResolved, + wantReason: atev1.WorkerPoolReasonResolved, wantDeployment: true, }, { @@ -1721,7 +1721,7 @@ func TestReconcileConfirmsSwitch(t *testing.T) { liveX: deleting(x()), wantRead: true, wantConfig: "y", - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, wantDeployment: true, }, { @@ -1729,7 +1729,7 @@ func TestReconcileConfirmsSwitch(t *testing.T) { inUse: "y", wantRead: true, wantConfig: "y", - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigNotFound, + wantReason: atev1.WorkerPoolReasonSandboxConfigNotFound, wantDeployment: true, }, { @@ -1737,21 +1737,21 @@ func TestReconcileConfirmsSwitch(t *testing.T) { liveX: x(), wantRead: true, wantConfig: "x", - wantReason: atev1alpha1.WorkerPoolReasonResolved, + wantReason: atev1.WorkerPoolReasonResolved, wantDeployment: true, }, { name: "being deleted, new pool: no config, no Deployment", liveX: deleting(x()), wantRead: true, - wantReason: atev1alpha1.WorkerPoolReasonSandboxConfigDeleting, + wantReason: atev1.WorkerPoolReasonSandboxConfigDeleting, }, { name: "already in use: not read again", inUse: "x", liveX: deleting(x()), wantConfig: "x", - wantReason: atev1alpha1.WorkerPoolReasonResolved, + wantReason: atev1.WorkerPoolReasonResolved, wantDeployment: true, }, } @@ -1759,12 +1759,12 @@ func TestReconcileConfirmsSwitch(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() wp := makeWorkerPool("pool", "default", 1, "worker:v1") - wp.Spec.SandboxClasses[0].ConfigRef = &atev1alpha1.SandboxConfigReference{Name: "x"} - objs := []client.Object{wp, x(), protected(makeSandboxConfig("y", atev1alpha1.SandboxClassGvisor, false))} + wp.Spec.SandboxClasses[0].ConfigRef = &atev1.SandboxConfigReference{Name: "x"} + objs := []client.Object{wp, x(), protected(makeSandboxConfig("y", atev1.SandboxClassGvisor, false))} if tc.inUse != "" { - wp.Status.SandboxClasses = []atev1alpha1.WorkerPoolSandboxClassStatus{{ - Name: atev1alpha1.SandboxClassGvisor, - ConfigRef: &atev1alpha1.SandboxConfigReference{Name: tc.inUse}, + wp.Status.SandboxClasses = []atev1.WorkerPoolSandboxClassStatus{{ + Name: atev1.SandboxClassGvisor, + ConfigRef: &atev1.SandboxConfigReference{Name: tc.inUse}, }} objs = append(objs, &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: wp.Name, Namespace: wp.Namespace}}) } @@ -1781,7 +1781,7 @@ func TestReconcileConfirmsSwitch(t *testing.T) { WithInterceptorFuncs(interceptor.Funcs{ Get: func(ctx context.Context, lc client.WithWatch, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { read = true - pool := &atev1alpha1.WorkerPool{} + pool := &atev1.WorkerPool{} if err := c.Get(ctx, client.ObjectKeyFromObject(wp), pool); err != nil { return err } @@ -1801,21 +1801,21 @@ func TestReconcileConfirmsSwitch(t *testing.T) { if read && !claimedAtRead { t.Errorf("x was read from the API server before the pool's status claimed it") } - got := &atev1alpha1.WorkerPool{} + got := &atev1.WorkerPool{} if err := c.Get(t.Context(), client.ObjectKeyFromObject(wp), got); err != nil { t.Fatalf("get WorkerPool: %v", err) } - if name := statusConfig(got, atev1alpha1.SandboxClassGvisor); name != tc.wantConfig { + if name := statusConfig(got, atev1.SandboxClassGvisor); name != tc.wantConfig { t.Errorf("status names %q, want %q", name, tc.wantConfig) } - class := sandboxClassStatus(got, atev1alpha1.SandboxClassGvisor) + class := sandboxClassStatus(got, atev1.SandboxClassGvisor) if class == nil { t.Fatalf("no gvisor status entry in %+v", got.Status) } if class.PendingConfigRef != nil { t.Errorf("pendingConfigRef = %q, want none", class.PendingConfigRef.Name) } - if cond := meta.FindStatusCondition(class.Conditions, atev1alpha1.WorkerPoolSandboxClassConditionResolved); cond == nil || cond.Reason != tc.wantReason { + if cond := meta.FindStatusCondition(class.Conditions, atev1.WorkerPoolSandboxClassConditionResolved); cond == nil || cond.Reason != tc.wantReason { t.Errorf("Resolved condition = %+v, want reason %s", cond, tc.wantReason) } err := c.Get(t.Context(), client.ObjectKeyFromObject(wp), &appsv1.Deployment{}) @@ -1839,7 +1839,7 @@ func TestSwitchInterleavings(t *testing.T) { if err := clientgoscheme.AddToScheme(scheme); err != nil { t.Fatalf("add client-go scheme: %v", err) } - if err := atev1alpha1.AddToScheme(scheme); err != nil { + if err := atev1.AddToScheme(scheme); err != nil { t.Fatalf("add scheme: %v", err) } // The points in a switch where the deletion and the protection reconcile @@ -1944,22 +1944,22 @@ func TestSwitchInterleavings(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() wp := makeWorkerPool("pool", "default", 1, "worker:v1") - wp.Spec.SandboxClasses[0].ConfigRef = &atev1alpha1.SandboxConfigReference{Name: "x"} - wp.Status.SandboxClasses = []atev1alpha1.WorkerPoolSandboxClassStatus{{ - Name: atev1alpha1.SandboxClassGvisor, - ConfigRef: &atev1alpha1.SandboxConfigReference{Name: "y"}, + wp.Spec.SandboxClasses[0].ConfigRef = &atev1.SandboxConfigReference{Name: "x"} + wp.Status.SandboxClasses = []atev1.WorkerPoolSandboxClassStatus{{ + Name: atev1.SandboxClassGvisor, + ConfigRef: &atev1.SandboxConfigReference{Name: "y"}, }} - x := makeSandboxConfig("x", atev1alpha1.SandboxClassGvisor, false) + x := makeSandboxConfig("x", atev1.SandboxClassGvisor, false) if !tc.unprotected { - controllerutil.AddFinalizer(x, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) + controllerutil.AddFinalizer(x, atev1.SandboxConfigWorkerPoolProtectionFinalizer) } - y := makeSandboxConfig("y", atev1alpha1.SandboxClassGvisor, false) - controllerutil.AddFinalizer(y, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) + y := makeSandboxConfig("y", atev1.SandboxClassGvisor, false) + controllerutil.AddFinalizer(y, atev1.SandboxConfigWorkerPoolProtectionFinalizer) // base is the cluster itself: the hooks and the protection // reconciler use it, so only the pool's reconcile is intercepted. base := fake.NewClientBuilder().WithScheme(scheme).WithObjects(wp, x, y).WithStatusSubresource(wp). - WithIndex(&atev1alpha1.WorkerPool{}, workerPoolSandboxConfigIndex, func(obj client.Object) []string { - return sandboxConfigsInUse(obj.(*atev1alpha1.WorkerPool)) + WithIndex(&atev1.WorkerPool{}, workerPoolSandboxConfigIndex, func(obj client.Object) []string { + return sandboxConfigsInUse(obj.(*atev1.WorkerPool)) }).Build() protection := &SandboxConfigProtectionReconciler{Client: base, APIReader: base} protect := func(ctx context.Context) error { @@ -1971,7 +1971,7 @@ func TestSwitchInterleavings(t *testing.T) { return nil } exists := func(ctx context.Context, name string) (bool, error) { - err := base.Get(ctx, types.NamespacedName{Name: name}, &atev1alpha1.SandboxConfig{}) + err := base.Get(ctx, types.NamespacedName{Name: name}, &atev1.SandboxConfig{}) if k8errors.IsNotFound(err) { return false, nil } @@ -1980,7 +1980,7 @@ func TestSwitchInterleavings(t *testing.T) { // checkConfigRef fails the test if status names a config in // configRef that does not exist. checkConfigRef := func(ctx context.Context, when string) error { - pool := &atev1alpha1.WorkerPool{} + pool := &atev1.WorkerPool{} if err := base.Get(ctx, client.ObjectKeyFromObject(wp), pool); err != nil { return err } @@ -2007,7 +2007,7 @@ func TestSwitchInterleavings(t *testing.T) { return nil } hit = true - sc := &atev1alpha1.SandboxConfig{} + sc := &atev1.SandboxConfig{} if err := base.Get(ctx, types.NamespacedName{Name: tc.deleted}, sc); err != nil { return err } @@ -2048,7 +2048,7 @@ func TestSwitchInterleavings(t *testing.T) { if err := c.Get(ctx, key, obj, opts...); err != nil { return err } - if _, ok := obj.(*atev1alpha1.SandboxConfig); ok { + if _, ok := obj.(*atev1.SandboxConfig); ok { return interleave(ctx, afterRead) } return nil @@ -2067,11 +2067,11 @@ func TestSwitchInterleavings(t *testing.T) { if statusWrites != 2 { t.Errorf("status writes = %d, want 2: the claim and the final write", statusWrites) } - got := &atev1alpha1.WorkerPool{} + got := &atev1.WorkerPool{} if err := base.Get(t.Context(), req.NamespacedName, got); err != nil { t.Fatalf("get WorkerPool: %v", err) } - if name := statusConfig(got, atev1alpha1.SandboxClassGvisor); name != tc.wantFirst { + if name := statusConfig(got, atev1.SandboxClassGvisor); name != tc.wantFirst { t.Errorf("after the reconcile, status names %q, want %q", name, tc.wantFirst) } if err := checkConfigRef(t.Context(), "after the reconcile"); err != nil { @@ -2092,7 +2092,7 @@ func TestSwitchInterleavings(t *testing.T) { if err := base.Get(t.Context(), req.NamespacedName, got); err != nil { t.Fatalf("get WorkerPool: %v", err) } - if name := statusConfig(got, atev1alpha1.SandboxClassGvisor); name != tc.wantSettled { + if name := statusConfig(got, atev1.SandboxClassGvisor); name != tc.wantSettled { t.Errorf("once settled, status names %q, want %q", name, tc.wantSettled) } if err := checkConfigRef(t.Context(), "once settled"); err != nil { @@ -2115,19 +2115,19 @@ func TestEveryClassHasConfig(t *testing.T) { t.Parallel() tests := []struct { name string - classes []atev1alpha1.WorkerPoolSandboxClassStatus + classes []atev1.WorkerPoolSandboxClassStatus want bool }{ { name: "every class has a config", - classes: []atev1alpha1.WorkerPoolSandboxClassStatus{{Name: atev1alpha1.SandboxClassGvisor, ConfigRef: &atev1alpha1.SandboxConfigReference{Name: "def"}}}, + classes: []atev1.WorkerPoolSandboxClassStatus{{Name: atev1.SandboxClassGvisor, ConfigRef: &atev1.SandboxConfigReference{Name: "def"}}}, want: true, }, { name: "one class has no config", - classes: []atev1alpha1.WorkerPoolSandboxClassStatus{ - {Name: atev1alpha1.SandboxClassGvisor, ConfigRef: &atev1alpha1.SandboxConfigReference{Name: "def"}}, - {Name: atev1alpha1.SandboxClassMicroVM}, + classes: []atev1.WorkerPoolSandboxClassStatus{ + {Name: atev1.SandboxClassGvisor, ConfigRef: &atev1.SandboxConfigReference{Name: "def"}}, + {Name: atev1.SandboxClassMicroVM}, }, want: false, }, @@ -2156,13 +2156,13 @@ func TestReconcileAppliesExistingDeploymentFirst(t *testing.T) { if err := clientgoscheme.AddToScheme(scheme); err != nil { t.Fatalf("add client-go scheme: %v", err) } - if err := atev1alpha1.AddToScheme(scheme); err != nil { + if err := atev1.AddToScheme(scheme); err != nil { t.Fatalf("add scheme: %v", err) } errInjected := errors.New("injected") failList := interceptor.Funcs{ List: func(ctx context.Context, c client.WithWatch, list client.ObjectList, opts ...client.ListOption) error { - if _, ok := list.(*atev1alpha1.SandboxConfigList); ok { + if _, ok := list.(*atev1.SandboxConfigList); ok { return errInjected } return c.List(ctx, list, opts...) @@ -2170,7 +2170,7 @@ func TestReconcileAppliesExistingDeploymentFirst(t *testing.T) { } failProtect := interceptor.Funcs{ Patch: func(ctx context.Context, c client.WithWatch, obj client.Object, patch client.Patch, opts ...client.PatchOption) error { - if _, ok := obj.(*atev1alpha1.SandboxConfig); ok { + if _, ok := obj.(*atev1.SandboxConfig); ok { return errInjected } return c.Patch(ctx, obj, patch, opts...) @@ -2226,7 +2226,7 @@ func TestReconcileAppliesExistingDeploymentFirst(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() wp := makeWorkerPool("pool", "default", 3, "worker:v1") - objs := []client.Object{wp, makeSandboxConfig("def", atev1alpha1.SandboxClassGvisor, true)} + objs := []client.Object{wp, makeSandboxConfig("def", atev1.SandboxClassGvisor, true)} if tc.hasDeployment { objs = append(objs, &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{Name: wp.Name, Namespace: wp.Namespace}, @@ -2261,24 +2261,24 @@ func TestReconcileAppliesExistingDeploymentFirst(t *testing.T) { func TestSyncStatus(t *testing.T) { t.Parallel() scheme := runtime.NewScheme() - if err := atev1alpha1.AddToScheme(scheme); err != nil { + if err := atev1.AddToScheme(scheme); err != nil { t.Fatalf("add scheme: %v", err) } - classes := func(config string) []atev1alpha1.WorkerPoolSandboxClassStatus { - return []atev1alpha1.WorkerPoolSandboxClassStatus{{ - Name: atev1alpha1.SandboxClassGvisor, - ConfigRef: &atev1alpha1.SandboxConfigReference{Name: config}, + classes := func(config string) []atev1.WorkerPoolSandboxClassStatus { + return []atev1.WorkerPoolSandboxClassStatus{{ + Name: atev1.SandboxClassGvisor, + ConfigRef: &atev1.SandboxConfigReference{Name: config}, Conditions: []metav1.Condition{{ - Type: atev1alpha1.WorkerPoolSandboxClassConditionResolved, + Type: atev1.WorkerPoolSandboxClassConditionResolved, Status: metav1.ConditionTrue, - Reason: atev1alpha1.WorkerPoolReasonResolved, + Reason: atev1.WorkerPoolReasonResolved, Message: "resolved to SandboxConfig " + config, ObservedGeneration: 2, LastTransitionTime: metav1.NewTime(time.Date(2026, 10, 1, 0, 0, 0, 0, time.UTC)), }}, }} } - before := atev1alpha1.WorkerPoolStatus{ + before := atev1.WorkerPoolStatus{ Replicas: 3, ReadyReplicas: 2, Selector: "app=old", @@ -2292,14 +2292,14 @@ func TestSyncStatus(t *testing.T) { tests := []struct { name string dep *appsv1.Deployment - classes []atev1alpha1.WorkerPoolSandboxClassStatus - want atev1alpha1.WorkerPoolStatus + classes []atev1.WorkerPoolSandboxClassStatus + want atev1.WorkerPoolStatus wantWrite bool }{ { name: "nil Deployment keeps the replica fields", classes: classes("new"), - want: atev1alpha1.WorkerPoolStatus{ + want: atev1.WorkerPoolStatus{ Replicas: 3, ReadyReplicas: 2, Selector: "app=old", SandboxClasses: classes("new"), }, @@ -2309,7 +2309,7 @@ func TestSyncStatus(t *testing.T) { name: "Deployment replaces the replica fields", dep: dep, classes: classes("new"), - want: atev1alpha1.WorkerPoolStatus{ + want: atev1.WorkerPoolStatus{ Replicas: 5, ReadyReplicas: 4, Selector: "app=new", SandboxClasses: classes("new"), }, @@ -2328,7 +2328,7 @@ func TestSyncStatus(t *testing.T) { wp := makeWorkerPool("pool", "default", 1, "worker:v1") wp.Status = *before.DeepCopy() c := fake.NewClientBuilder().WithScheme(scheme).WithObjects(wp).WithStatusSubresource(wp).Build() - stored := &atev1alpha1.WorkerPool{} + stored := &atev1.WorkerPool{} if err := c.Get(t.Context(), client.ObjectKeyFromObject(wp), stored); err != nil { t.Fatalf("get WorkerPool: %v", err) } @@ -2339,7 +2339,7 @@ func TestSyncStatus(t *testing.T) { if err := r.syncStatus(t.Context(), stored, tc.dep, tc.classes); err != nil { t.Fatalf("syncStatus: %v", err) } - got := &atev1alpha1.WorkerPool{} + got := &atev1.WorkerPool{} if err := c.Get(t.Context(), client.ObjectKeyFromObject(wp), got); err != nil { t.Fatalf("get WorkerPool: %v", err) } @@ -2393,23 +2393,23 @@ func TestAddProtectionFinalizer(t *testing.T) { // --- helpers --- -func makeSandboxConfig(name string, class atev1alpha1.SandboxClass, isDefault bool) *atev1alpha1.SandboxConfig { - v := atev1alpha1.SandboxVersionConfig{Name: "v1"} - sc := &atev1alpha1.SandboxConfig{ +func makeSandboxConfig(name string, class atev1.SandboxClass, isDefault bool) *atev1.SandboxConfig { + v := atev1.SandboxVersionConfig{Name: "v1"} + sc := &atev1.SandboxConfig{ ObjectMeta: metav1.ObjectMeta{Name: name}, - Spec: atev1alpha1.SandboxConfigSpec{ + Spec: atev1.SandboxConfigSpec{ SandboxClass: class, DefaultVersion: v.Name, - Versions: []atev1alpha1.SandboxVersionConfig{v}, + Versions: []atev1.SandboxVersionConfig{v}, }, } if isDefault { - sc.Annotations = map[string]string{atev1alpha1.SandboxConfigClassDefaultAnnotation: "true"} + sc.Annotations = map[string]string{atev1.SandboxConfigClassDefaultAnnotation: "true"} } return sc } -func createSandboxConfig(t *testing.T, sc *atev1alpha1.SandboxConfig) { +func createSandboxConfig(t *testing.T, sc *atev1.SandboxConfig) { t.Helper() if err := k8sClient.Create(t.Context(), sc); err != nil { t.Fatalf("create SandboxConfig %s: %v", sc.Name, err) @@ -2417,7 +2417,7 @@ func createSandboxConfig(t *testing.T, sc *atev1alpha1.SandboxConfig) { deleteOnCleanup(t, sc) } -func createWorkerPool(t *testing.T, wp *atev1alpha1.WorkerPool) { +func createWorkerPool(t *testing.T, wp *atev1.WorkerPool) { t.Helper() if err := k8sClient.Create(t.Context(), wp); err != nil { t.Fatalf("create WorkerPool %s: %v", wp.Name, err) @@ -2427,9 +2427,9 @@ func createWorkerPool(t *testing.T, wp *atev1alpha1.WorkerPool) { // waitResolved waits for wp's sandbox class to report Resolved=True for its // current generation and to use config. -func waitResolved(t *testing.T, wp *atev1alpha1.WorkerPool, config string) *atev1alpha1.WorkerPool { +func waitResolved(t *testing.T, wp *atev1.WorkerPool, config string) *atev1.WorkerPool { t.Helper() - return waitCondition(t, wp, func(current *atev1alpha1.WorkerPool, cond *metav1.Condition) bool { + return waitCondition(t, wp, func(current *atev1.WorkerPool, cond *metav1.Condition) bool { return cond.Status == metav1.ConditionTrue && statusConfig(current, current.Spec.DefaultSandboxClass()) == config }) @@ -2437,16 +2437,16 @@ func waitResolved(t *testing.T, wp *atev1alpha1.WorkerPool, config string) *atev // waitUnresolved waits for wp's sandbox class to report Resolved=False with // reason for its current generation. -func waitUnresolved(t *testing.T, wp *atev1alpha1.WorkerPool, reason string) *atev1alpha1.WorkerPool { +func waitUnresolved(t *testing.T, wp *atev1.WorkerPool, reason string) *atev1.WorkerPool { t.Helper() - return waitCondition(t, wp, func(_ *atev1alpha1.WorkerPool, cond *metav1.Condition) bool { + return waitCondition(t, wp, func(_ *atev1.WorkerPool, cond *metav1.Condition) bool { return cond.Status == metav1.ConditionFalse && cond.Reason == reason }) } -func waitCondition(t *testing.T, wp *atev1alpha1.WorkerPool, ok func(*atev1alpha1.WorkerPool, *metav1.Condition) bool) *atev1alpha1.WorkerPool { +func waitCondition(t *testing.T, wp *atev1.WorkerPool, ok func(*atev1.WorkerPool, *metav1.Condition) bool) *atev1.WorkerPool { t.Helper() - current := &atev1alpha1.WorkerPool{} + current := &atev1.WorkerPool{} eventually(t, func(ctx context.Context) (bool, error) { if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(wp), current); err != nil { return false, nil @@ -2455,7 +2455,7 @@ func waitCondition(t *testing.T, wp *atev1alpha1.WorkerPool, ok func(*atev1alpha if status == nil { return false, nil } - cond := meta.FindStatusCondition(status.Conditions, atev1alpha1.WorkerPoolSandboxClassConditionResolved) + cond := meta.FindStatusCondition(status.Conditions, atev1.WorkerPoolSandboxClassConditionResolved) return cond != nil && cond.ObservedGeneration == current.Generation && ok(current, cond), nil }) return current @@ -2466,11 +2466,11 @@ func waitCondition(t *testing.T, wp *atev1alpha1.WorkerPool, ok func(*atev1alpha func waitProtectionFinalizer(t *testing.T, name string, want bool) { t.Helper() eventually(t, func(ctx context.Context) (bool, error) { - sc := &atev1alpha1.SandboxConfig{} + sc := &atev1.SandboxConfig{} if err := k8sClient.Get(ctx, types.NamespacedName{Name: name}, sc); err != nil { return false, nil } - return controllerutil.ContainsFinalizer(sc, atev1alpha1.SandboxConfigWorkerPoolProtectionFinalizer) == want, nil + return controllerutil.ContainsFinalizer(sc, atev1.SandboxConfigWorkerPoolProtectionFinalizer) == want, nil }) } @@ -2486,7 +2486,7 @@ func waitGone(t *testing.T, obj client.Object) { // assertNoDeployment fails if a Deployment controlled by wp exists. envtest // runs no garbage collector, so a same-named Deployment left by a pool from an // earlier -count iteration does not count. -func assertNoDeployment(t *testing.T, wp *atev1alpha1.WorkerPool) { +func assertNoDeployment(t *testing.T, wp *atev1.WorkerPool) { t.Helper() dep, err := getDeployment(t.Context(), wp) if k8errors.IsNotFound(err) { @@ -2515,7 +2515,7 @@ func removeFinalizer(t *testing.T, name, finalizer string) { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() err := retry.RetryOnConflict(retry.DefaultBackoff, func() error { - sc := &atev1alpha1.SandboxConfig{} + sc := &atev1.SandboxConfig{} if err := k8sClient.Get(ctx, types.NamespacedName{Name: name}, sc); err != nil { return client.IgnoreNotFound(err) } @@ -2531,7 +2531,7 @@ func removeFinalizer(t *testing.T, name, finalizer string) { // makeWorkerPoolClasses returns a pool in ns with the given spec and status // sandbox classes. -func makeWorkerPoolClasses(ns, name string, spec []atev1alpha1.WorkerPoolSandboxClass, status []atev1alpha1.WorkerPoolSandboxClassStatus) *atev1alpha1.WorkerPool { +func makeWorkerPoolClasses(ns, name string, spec []atev1.WorkerPoolSandboxClass, status []atev1.WorkerPoolSandboxClassStatus) *atev1.WorkerPool { wp := makeWorkerPool(name, ns, 1, "worker:v1") wp.Spec.SandboxClasses = spec wp.Status.SandboxClasses = status @@ -2539,7 +2539,7 @@ func makeWorkerPoolClasses(ns, name string, spec []atev1alpha1.WorkerPoolSandbox } // statusConfig returns the SandboxConfig wp's status uses for class, or "". -func statusConfig(wp *atev1alpha1.WorkerPool, class atev1alpha1.SandboxClass) string { +func statusConfig(wp *atev1.WorkerPool, class atev1.SandboxClass) string { if s := sandboxClassStatus(wp, class); s != nil && s.ConfigRef != nil { return s.ConfigRef.Name } diff --git a/cmd/atecontroller/internal/workersync/fakecontrol_test.go b/cmd/atecontroller/internal/workersync/fakecontrol_test.go index 7c5e3132d9..69da1ae206 100644 --- a/cmd/atecontroller/internal/workersync/fakecontrol_test.go +++ b/cmd/atecontroller/internal/workersync/fakecontrol_test.go @@ -22,7 +22,7 @@ import ( "strconv" "sync" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -44,17 +44,17 @@ import ( // Worker surface so this satisfies the interface, and panics if the syncer ever // reaches for one of them. type fakeControl struct { - ateapipb.ControlClient + ateapi.ControlClient mu sync.Mutex - workers map[string]*ateapipb.Worker + workers map[string]*ateapi.Worker uidSeq int // createHook, when set, decides CreateWorker's outcome: a non-nil error is // returned and nothing is registered. - createHook func(*ateapipb.Worker) error + createHook func(*ateapi.Worker) error // listHook, when set, runs before each ListWorkers and can fail the call. - listHook func(*ateapipb.ListWorkersRequest) error + listHook func(*ateapi.ListWorkersRequest) error // updateHook, when set, runs once before an UpdateWorker applies, so a test // can land a concurrent write and make the precondition fail. updateHook func(name string) @@ -64,18 +64,18 @@ type fakeControl struct { } func newFakeControl() *fakeControl { - return &fakeControl{workers: map[string]*ateapipb.Worker{}} + return &fakeControl{workers: map[string]*ateapi.Worker{}} } // get returns the registered worker by name, or nil if there is none. -func (f *fakeControl) get(name string) *ateapipb.Worker { +func (f *fakeControl) get(name string) *ateapi.Worker { f.mu.Lock() defer f.mu.Unlock() w, ok := f.workers[name] if !ok { return nil } - return proto.Clone(w).(*ateapipb.Worker) + return proto.Clone(w).(*ateapi.Worker) } // names returns the names of every registered worker, sorted. @@ -87,39 +87,39 @@ func (f *fakeControl) names() []string { // put registers a worker as if it had been created through the API, assigning // it a uid and version, so a test can start from a worker that already exists. -func (f *fakeControl) put(w *ateapipb.Worker) *ateapipb.Worker { +func (f *fakeControl) put(w *ateapi.Worker) *ateapi.Worker { f.mu.Lock() defer f.mu.Unlock() return f.putLocked(w) } -func (f *fakeControl) putLocked(w *ateapipb.Worker) *ateapipb.Worker { - stored := proto.Clone(w).(*ateapipb.Worker) +func (f *fakeControl) putLocked(w *ateapi.Worker) *ateapi.Worker { + stored := proto.Clone(w).(*ateapi.Worker) f.uidSeq++ - stored.Metadata = &ateapipb.ResourceMetadata{ + stored.Metadata = &ateapi.ResourceMetadata{ Name: w.GetMetadata().GetName(), Uid: fmt.Sprintf("worker-uid-%d", f.uidSeq), Version: 1, } if stored.GetStatus() == nil { - stored.Status = &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_ACTIVE} + stored.Status = &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_ACTIVE} } f.storeLocked(stored) - return proto.Clone(stored).(*ateapipb.Worker) + return proto.Clone(stored).(*ateapi.Worker) } // storeLocked writes w. -func (f *fakeControl) storeLocked(w *ateapipb.Worker) { +func (f *fakeControl) storeLocked(w *ateapi.Worker) { f.workers[w.GetMetadata().GetName()] = w } -func (f *fakeControl) setCreateHook(hook func(*ateapipb.Worker) error) { +func (f *fakeControl) setCreateHook(hook func(*ateapi.Worker) error) { f.mu.Lock() defer f.mu.Unlock() f.createHook = hook } -func (f *fakeControl) setListHook(hook func(*ateapipb.ListWorkersRequest) error) { +func (f *fakeControl) setListHook(hook func(*ateapi.ListWorkersRequest) error) { f.mu.Lock() defer f.mu.Unlock() f.listHook = hook @@ -142,7 +142,7 @@ func (f *fakeControl) takeUpdateHook() func(string) { return hook } -func (f *fakeControl) GetWorker(_ context.Context, in *ateapipb.GetWorkerRequest, _ ...grpc.CallOption) (*ateapipb.Worker, error) { +func (f *fakeControl) GetWorker(_ context.Context, in *ateapi.GetWorkerRequest, _ ...grpc.CallOption) (*ateapi.Worker, error) { name := in.GetWorker().GetName() if w := f.get(name); w != nil { return w, nil @@ -150,7 +150,7 @@ func (f *fakeControl) GetWorker(_ context.Context, in *ateapipb.GetWorkerRequest return nil, status.Errorf(codes.NotFound, "Worker %s not found", name) } -func (f *fakeControl) CreateWorker(_ context.Context, in *ateapipb.CreateWorkerRequest, _ ...grpc.CallOption) (*ateapipb.Worker, error) { +func (f *fakeControl) CreateWorker(_ context.Context, in *ateapi.CreateWorkerRequest, _ ...grpc.CallOption) (*ateapi.Worker, error) { f.mu.Lock() defer f.mu.Unlock() @@ -164,12 +164,12 @@ func (f *fakeControl) CreateWorker(_ context.Context, in *ateapipb.CreateWorkerR return nil, status.Errorf(codes.AlreadyExists, "Worker %s already exists", name) } // status is output-only: every Worker is born UNAVAILABLE. - created := proto.Clone(in.GetWorker()).(*ateapipb.Worker) - created.Status = &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE} + created := proto.Clone(in.GetWorker()).(*ateapi.Worker) + created.Status = &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_UNAVAILABLE} return f.putLocked(created), nil } -func (f *fakeControl) UpdateWorker(_ context.Context, in *ateapipb.UpdateWorkerRequest, _ ...grpc.CallOption) (*ateapipb.Worker, error) { +func (f *fakeControl) UpdateWorker(_ context.Context, in *ateapi.UpdateWorkerRequest, _ ...grpc.CallOption) (*ateapi.Worker, error) { md := in.GetWorker().GetMetadata() // Outside the lock: the hook is how a test lands a concurrent write, and it // does that by calling back in. @@ -196,14 +196,14 @@ func (f *fakeControl) UpdateWorker(_ context.Context, in *ateapipb.UpdateWorkerR // UpdateWorker replaces the whole resource: the request's Worker is taken // wholesale and only the server-owned metadata and status are kept as // stored. - updated := proto.Clone(in.GetWorker()).(*ateapipb.Worker) - updated.Metadata = proto.Clone(stored.GetMetadata()).(*ateapipb.ResourceMetadata) - updated.Status = proto.Clone(stored.GetStatus()).(*ateapipb.WorkerStatus) + updated := proto.Clone(in.GetWorker()).(*ateapi.Worker) + updated.Metadata = proto.Clone(stored.GetMetadata()).(*ateapi.ResourceMetadata) + updated.Status = proto.Clone(stored.GetStatus()).(*ateapi.WorkerStatus) // labels are the only field an update may change, so pinning them to what // is stored leaves any remaining difference on a field that is immutable // after create, including one the request cleared by omitting it. - probe := proto.Clone(updated).(*ateapipb.Worker) + probe := proto.Clone(updated).(*ateapi.Worker) probe.Labels = stored.GetLabels() if !proto.Equal(probe, stored) { return nil, status.Error(codes.InvalidArgument, "update changed a field that is immutable after create") @@ -211,10 +211,10 @@ func (f *fakeControl) UpdateWorker(_ context.Context, in *ateapipb.UpdateWorkerR updated.Metadata.Version++ f.storeLocked(updated) - return proto.Clone(updated).(*ateapipb.Worker), nil + return proto.Clone(updated).(*ateapi.Worker), nil } -func (f *fakeControl) DeleteWorker(_ context.Context, in *ateapipb.DeleteWorkerRequest, _ ...grpc.CallOption) (*ateapipb.Worker, error) { +func (f *fakeControl) DeleteWorker(_ context.Context, in *ateapi.DeleteWorkerRequest, _ ...grpc.CallOption) (*ateapi.Worker, error) { f.mu.Lock() defer f.mu.Unlock() @@ -227,7 +227,7 @@ func (f *fakeControl) DeleteWorker(_ context.Context, in *ateapipb.DeleteWorkerR return stored, nil } -func (f *fakeControl) DrainWorker(_ context.Context, in *ateapipb.DrainWorkerRequest, _ ...grpc.CallOption) (*ateapipb.DrainWorkerResponse, error) { +func (f *fakeControl) DrainWorker(_ context.Context, in *ateapi.DrainWorkerRequest, _ ...grpc.CallOption) (*ateapi.DrainWorkerResponse, error) { f.mu.Lock() defer f.mu.Unlock() @@ -236,36 +236,36 @@ func (f *fakeControl) DrainWorker(_ context.Context, in *ateapipb.DrainWorkerReq if !ok { return nil, status.Errorf(codes.NotFound, "Worker %s not found", name) } - if stored.GetStatus().GetState() == ateapipb.WorkerState_WORKER_STATE_DRAINING { + if stored.GetStatus().GetState() == ateapi.WorkerState_WORKER_STATE_DRAINING { // Already draining: no write, and specifically no version bump. - return &ateapipb.DrainWorkerResponse{Worker: proto.Clone(stored).(*ateapipb.Worker)}, nil + return &ateapi.DrainWorkerResponse{Worker: proto.Clone(stored).(*ateapi.Worker)}, nil } - drained := proto.Clone(stored).(*ateapipb.Worker) - drained.Status.State = ateapipb.WorkerState_WORKER_STATE_DRAINING + drained := proto.Clone(stored).(*ateapi.Worker) + drained.Status.State = ateapi.WorkerState_WORKER_STATE_DRAINING drained.Metadata.Version++ f.storeLocked(drained) - return &ateapipb.DrainWorkerResponse{Worker: proto.Clone(drained).(*ateapipb.Worker)}, nil + return &ateapi.DrainWorkerResponse{Worker: proto.Clone(drained).(*ateapi.Worker)}, nil } -func (f *fakeControl) MarkWorkerAvailable(_ context.Context, in *ateapipb.MarkWorkerAvailableRequest, _ ...grpc.CallOption) (*ateapipb.MarkWorkerAvailableResponse, error) { - w, err := f.markWorker(in.GetWorker().GetName(), ateapipb.WorkerState_WORKER_STATE_ACTIVE) +func (f *fakeControl) MarkWorkerAvailable(_ context.Context, in *ateapi.MarkWorkerAvailableRequest, _ ...grpc.CallOption) (*ateapi.MarkWorkerAvailableResponse, error) { + w, err := f.markWorker(in.GetWorker().GetName(), ateapi.WorkerState_WORKER_STATE_ACTIVE) if err != nil { return nil, err } - return &ateapipb.MarkWorkerAvailableResponse{Worker: w}, nil + return &ateapi.MarkWorkerAvailableResponse{Worker: w}, nil } -func (f *fakeControl) MarkWorkerUnavailable(_ context.Context, in *ateapipb.MarkWorkerUnavailableRequest, _ ...grpc.CallOption) (*ateapipb.MarkWorkerUnavailableResponse, error) { - w, err := f.markWorker(in.GetWorker().GetName(), ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE) +func (f *fakeControl) MarkWorkerUnavailable(_ context.Context, in *ateapi.MarkWorkerUnavailableRequest, _ ...grpc.CallOption) (*ateapi.MarkWorkerUnavailableResponse, error) { + w, err := f.markWorker(in.GetWorker().GetName(), ateapi.WorkerState_WORKER_STATE_UNAVAILABLE) if err != nil { return nil, err } - return &ateapipb.MarkWorkerUnavailableResponse{Worker: w}, nil + return &ateapi.MarkWorkerUnavailableResponse{Worker: w}, nil } // markWorker moves a Worker between ACTIVE and UNAVAILABLE as the Mark RPCs // do: idempotent down to leaving the version alone, with DRAINING final. -func (f *fakeControl) markWorker(name string, state ateapipb.WorkerState) (*ateapipb.Worker, error) { +func (f *fakeControl) markWorker(name string, state ateapi.WorkerState) (*ateapi.Worker, error) { f.mu.Lock() defer f.mu.Unlock() @@ -275,18 +275,18 @@ func (f *fakeControl) markWorker(name string, state ateapipb.WorkerState) (*atea } switch stored.GetStatus().GetState() { case state: - return proto.Clone(stored).(*ateapipb.Worker), nil - case ateapipb.WorkerState_WORKER_STATE_DRAINING: + return proto.Clone(stored).(*ateapi.Worker), nil + case ateapi.WorkerState_WORKER_STATE_DRAINING: return nil, status.Errorf(codes.FailedPrecondition, "Worker %s is draining", name) } - marked := proto.Clone(stored).(*ateapipb.Worker) + marked := proto.Clone(stored).(*ateapi.Worker) marked.Status.State = state marked.Metadata.Version++ f.storeLocked(marked) - return proto.Clone(marked).(*ateapipb.Worker), nil + return proto.Clone(marked).(*ateapi.Worker), nil } -func (f *fakeControl) ListWorkers(_ context.Context, in *ateapipb.ListWorkersRequest, _ ...grpc.CallOption) (*ateapipb.ListWorkersResponse, error) { +func (f *fakeControl) ListWorkers(_ context.Context, in *ateapi.ListWorkersRequest, _ ...grpc.CallOption) (*ateapi.ListWorkersResponse, error) { f.mu.Lock() defer f.mu.Unlock() @@ -315,9 +315,9 @@ func (f *fakeControl) ListWorkers(_ context.Context, in *ateapipb.ListWorkersReq } end := min(start+size, len(names)) - resp := &ateapipb.ListWorkersResponse{} + resp := &ateapi.ListWorkersResponse{} for _, name := range names[start:end] { - resp.Workers = append(resp.Workers, proto.Clone(f.workers[name]).(*ateapipb.Worker)) + resp.Workers = append(resp.Workers, proto.Clone(f.workers[name]).(*ateapi.Worker)) } if end < len(names) { resp.NextPageToken = strconv.Itoa(end) diff --git a/cmd/atecontroller/internal/workersync/syncer.go b/cmd/atecontroller/internal/workersync/syncer.go index 0bba57763b..ebdf1aa775 100644 --- a/cmd/atecontroller/internal/workersync/syncer.go +++ b/cmd/atecontroller/internal/workersync/syncer.go @@ -23,9 +23,9 @@ import ( "maps" "time" + "go.ate.dev/substrate/api/ateapi/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/installdefaults" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" corev1 "k8s.io/api/core/v1" @@ -73,8 +73,8 @@ func (k workerKey) workerName() string { return k.uid } // workerRef is the Worker this key identifies, in the form the API's // single-resource requests take. Workers are global-scoped, so no atespace. -func (k workerKey) workerRef() *ateapipb.ObjectRef { - return &ateapipb.ObjectRef{Name: k.workerName()} +func (k workerKey) workerRef() *ateapi.ObjectRef { + return &ateapi.ObjectRef{Name: k.workerName()} } // logAttrs identifies the Worker in a log line, along with the pod it is @@ -96,7 +96,7 @@ func (k workerKey) logAttrs() []any { // never hands the same key to two workers concurrently, so per-key ordering is // preserved regardless of workerCount. type WorkerPoolSyncer struct { - client ateapipb.ControlClient + client ateapi.ControlClient pods corev1client.PodsGetter apps appsv1client.AppsV1Interface workerInformer cache.SharedIndexInformer @@ -114,7 +114,7 @@ type WorkerPoolSyncer struct { // NewWorkerPoolSyncer creates a new WorkerPoolSyncer. pods is used to delete // worker pods that have reached a terminal phase or outlived their pool, and // apps to tell the latter from pods the garbage collector is still removing. -func NewWorkerPoolSyncer(client ateapipb.ControlClient, pods corev1client.PodsGetter, apps appsv1client.AppsV1Interface, workerInformer, workerPoolInformer cache.SharedIndexInformer, workerCount int) *WorkerPoolSyncer { +func NewWorkerPoolSyncer(client ateapi.ControlClient, pods corev1client.PodsGetter, apps appsv1client.AppsV1Interface, workerInformer, workerPoolInformer cache.SharedIndexInformer, workerCount int) *WorkerPoolSyncer { return &WorkerPoolSyncer{ client: client, pods: pods, @@ -203,7 +203,7 @@ func deletedObject[T any](obj interface{}) (T, bool) { // enqueueWorkerPool schedules every current pod in pool. func (s *WorkerPoolSyncer) enqueueWorkerPool(obj interface{}) { - pool, ok := deletedObject[*atev1alpha1.WorkerPool](obj) + pool, ok := deletedObject[*atev1.WorkerPool](obj) if !ok { slog.Error("Syncer: unexpected WorkerPool informer object", slog.Any("obj", obj)) return @@ -304,14 +304,14 @@ func (s *WorkerPoolSyncer) createOrUpdateWorker(ctx context.Context, key workerK if !exists { return s.reconcileMissingPool(ctx, key, pod, poolName) } - pool, ok := poolObject.(*atev1alpha1.WorkerPool) + pool, ok := poolObject.(*atev1.WorkerPool) if !ok { return fmt.Errorf("getting WorkerPool %s/%s: unexpected object type %T", key.namespace, poolName, poolObject) } available := isWorkerAvailable(pod) - w, err := s.client.GetWorker(ctx, &ateapipb.GetWorkerRequest{Worker: key.workerRef()}) + w, err := s.client.GetWorker(ctx, &ateapi.GetWorkerRequest{Worker: key.workerRef()}) if status.Code(err) == codes.NotFound { // node_name is required and immutable, so the pod is registered once it // is scheduled; the update that binds it re-enqueues the pod. @@ -319,10 +319,10 @@ func (s *WorkerPoolSyncer) createOrUpdateWorker(ctx context.Context, key workerK return nil } slog.InfoContext(ctx, "Syncer: registering worker", key.logAttrs()...) - worker := &ateapipb.Worker{ + worker := &ateapi.Worker{ // Workers are global-scoped, so the name carries no atespace. See // workerKey.workerName for where the name comes from. - Metadata: &ateapipb.ResourceMetadata{Name: key.workerName()}, + Metadata: &ateapi.ResourceMetadata{Name: key.workerName()}, WorkerNamespace: pod.Namespace, WorkerPool: poolName, WorkerPod: pod.Name, @@ -336,7 +336,7 @@ func (s *WorkerPoolSyncer) createOrUpdateWorker(ctx context.Context, key workerK // ALREADY_EXISTS means we lost a create race; requeue and converge via // the update path. INVALID_ARGUMENT is terminal — see // processNextWorkItem. - w, err = s.client.CreateWorker(ctx, &ateapipb.CreateWorkerRequest{Worker: worker}) + w, err = s.client.CreateWorker(ctx, &ateapi.CreateWorkerRequest{Worker: worker}) if err != nil { return err } @@ -347,9 +347,9 @@ func (s *WorkerPoolSyncer) createOrUpdateWorker(ctx context.Context, key workerK // Each write below returns the Worker at its new version, which the next // one carries as its precondition. ABORTED requeues the key; the retry // re-fetches the worker. - if !available && w.GetStatus().GetState() == ateapipb.WorkerState_WORKER_STATE_ACTIVE { + if !available && w.GetStatus().GetState() == ateapi.WorkerState_WORKER_STATE_ACTIVE { slog.InfoContext(ctx, "Syncer: marking worker unavailable (pod not Ready)", key.logAttrs()...) - marked, err := s.client.MarkWorkerUnavailable(ctx, &ateapipb.MarkWorkerUnavailableRequest{Worker: key.workerRef()}) + marked, err := s.client.MarkWorkerUnavailable(ctx, &ateapi.MarkWorkerUnavailableRequest{Worker: key.workerRef()}) if err != nil { return err } @@ -369,16 +369,16 @@ func (s *WorkerPoolSyncer) createOrUpdateWorker(ctx context.Context, key workerK changed = true } if changed { - w, err = s.client.UpdateWorker(ctx, &ateapipb.UpdateWorkerRequest{Worker: w}) + w, err = s.client.UpdateWorker(ctx, &ateapi.UpdateWorkerRequest{Worker: w}) if err != nil { return err } } // A DRAINING Worker is left alone: its pod is on its way out. - if available && w.GetStatus().GetState() == ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE { + if available && w.GetStatus().GetState() == ateapi.WorkerState_WORKER_STATE_UNAVAILABLE { slog.InfoContext(ctx, "Syncer: marking worker available (pod Ready)", key.logAttrs()...) - _, err = s.client.MarkWorkerAvailable(ctx, &ateapipb.MarkWorkerAvailableRequest{Worker: key.workerRef()}) + _, err = s.client.MarkWorkerAvailable(ctx, &ateapi.MarkWorkerAvailableRequest{Worker: key.workerRef()}) return err } return nil @@ -437,7 +437,7 @@ func (s *WorkerPoolSyncer) deleteWorkerPod(ctx context.Context, key workerKey, p // deleted gracefully; a replacement from its ReplicaSet has no Worker, so is // left alone. func (s *WorkerPoolSyncer) reconcileMissingPool(ctx context.Context, key workerKey, pod *corev1.Pod, poolName string) error { - _, err := s.client.GetWorker(ctx, &ateapipb.GetWorkerRequest{Worker: key.workerRef()}) + _, err := s.client.GetWorker(ctx, &ateapi.GetWorkerRequest{Worker: key.workerRef()}) if status.Code(err) == codes.NotFound { return nil } @@ -518,7 +518,7 @@ func workerSPIFFEID(pod *corev1.Pod) string { // and retries against the updated record. func (s *WorkerPoolSyncer) markWorkerDraining(ctx context.Context, key workerKey) error { slog.InfoContext(ctx, "Syncer: marking worker draining (pod deleting)", key.logAttrs()...) - _, err := s.client.DrainWorker(ctx, &ateapipb.DrainWorkerRequest{Worker: key.workerRef()}) + _, err := s.client.DrainWorker(ctx, &ateapi.DrainWorkerRequest{Worker: key.workerRef()}) if status.Code(err) == codes.NotFound { return nil } @@ -534,7 +534,7 @@ func (s *WorkerPoolSyncer) markWorkerDraining(ctx context.Context, key workerKey // NOT_FOUND is success. Idempotency lives here, at the caller, so re-driving a // reconcile is safe. func (s *WorkerPoolSyncer) reconcileDeadWorker(ctx context.Context, key workerKey) error { - _, err := s.client.DeleteWorker(ctx, &ateapipb.DeleteWorkerRequest{Worker: key.workerRef()}) + _, err := s.client.DeleteWorker(ctx, &ateapi.DeleteWorkerRequest{Worker: key.workerRef()}) if status.Code(err) == codes.NotFound { return nil } @@ -592,7 +592,7 @@ func (s *WorkerPoolSyncer) enqueueRegisteredWorkers(ctx context.Context) { // resumes from the same position. A fresh backoff per page means only // consecutive failures of the same call accumulate delay; a page that succeeds // resets it. -func (s *WorkerPoolSyncer) listWorkersPageWithRetry(ctx context.Context, pageToken string) (*ateapipb.ListWorkersResponse, error) { +func (s *WorkerPoolSyncer) listWorkersPageWithRetry(ctx context.Context, pageToken string) (*ateapi.ListWorkersResponse, error) { backoff := wait.Backoff{ Duration: s.listBackoff, Factor: 2.0, @@ -605,7 +605,7 @@ func (s *WorkerPoolSyncer) listWorkersPageWithRetry(ctx context.Context, pageTok Cap: s.listCap, } for { - page, err := s.client.ListWorkers(ctx, &ateapipb.ListWorkersRequest{Options: &ateapipb.ListOptions{PageSize: 1000, PageToken: pageToken}}) + page, err := s.client.ListWorkers(ctx, &ateapi.ListWorkersRequest{Options: &ateapi.ListOptions{PageSize: 1000, PageToken: pageToken}}) if err == nil { return page, nil } diff --git a/cmd/atecontroller/internal/workersync/syncer_test.go b/cmd/atecontroller/internal/workersync/syncer_test.go index 4502d59ce8..83d41fba95 100644 --- a/cmd/atecontroller/internal/workersync/syncer_test.go +++ b/cmd/atecontroller/internal/workersync/syncer_test.go @@ -22,10 +22,10 @@ import ( "testing" "time" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + "go.ate.dev/substrate/api/ateapi/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" atefake "go.ate.dev/substrate/pkg/client/clientset/versioned/fake" "go.ate.dev/substrate/pkg/client/informers/externalversions" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" appsv1 "k8s.io/api/apps/v1" @@ -83,18 +83,18 @@ func workerPod(ns, name, poolName, uid, ip string) *corev1.Pod { return pod } -func workerPool(ns, name string, labels map[string]string) *atev1alpha1.WorkerPool { - return &atev1alpha1.WorkerPool{ +func workerPool(ns, name string, labels map[string]string) *atev1.WorkerPool { + return &atev1.WorkerPool{ ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: ns, Labels: labels}, - Spec: atev1alpha1.WorkerPoolSpec{SandboxClasses: []atev1alpha1.WorkerPoolSandboxClass{{Name: atev1alpha1.SandboxClassGvisor}}}, + Spec: atev1.WorkerPoolSpec{SandboxClasses: []atev1.WorkerPoolSandboxClass{{Name: atev1.SandboxClassGvisor}}}, } } // registeredWorker is a Worker in the shape the syncer would have registered // for the given pod, for seeding the fake API before a test runs. -func registeredWorker(ns, poolName, podName, uid string) *ateapipb.Worker { - return &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: uid}, +func registeredWorker(ns, poolName, podName, uid string) *ateapi.Worker { + return &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: uid}, WorkerNamespace: ns, WorkerPool: poolName, WorkerPod: podName, @@ -106,7 +106,7 @@ func registeredWorker(ns, poolName, podName, uid string) *ateapipb.Worker { // newWorkerPoolInformer builds the WorkerPool informer the syncer reads, backed // by a fake clientset that holds initPools. Nothing is cached until the factory // starts. -func newWorkerPoolInformer(initPools ...*atev1alpha1.WorkerPool) (*atefake.Clientset, externalversions.SharedInformerFactory, cache.SharedIndexInformer) { +func newWorkerPoolInformer(initPools ...*atev1.WorkerPool) (*atefake.Clientset, externalversions.SharedInformerFactory, cache.SharedIndexInformer) { objs := make([]runtime.Object, 0, len(initPools)) for _, pool := range initPools { objs = append(objs, pool) @@ -114,13 +114,13 @@ func newWorkerPoolInformer(initPools ...*atev1alpha1.WorkerPool) (*atefake.Clien //nolint:staticcheck // NewSimpleClientset is the only available fake clientset for versioned CRDs. client := atefake.NewSimpleClientset(objs...) factory := externalversions.NewSharedInformerFactory(client, 0) - return client, factory, factory.Api().V1alpha1().WorkerPools().Informer() + return client, factory, factory.Ate().V1().WorkerPools().Informer() } // setupSyncerTest wires a running syncer to a fake Control API and a fake // Kubernetes, driving it end to end through pod and pool events and the queue. // It returns the fake Kubernetes and the fake clientset the pools live in. -func setupSyncerTest(t *testing.T, ctx context.Context, api *fakeControl, initPools ...*atev1alpha1.WorkerPool) (*fake.Clientset, *atefake.Clientset) { +func setupSyncerTest(t *testing.T, ctx context.Context, api *fakeControl, initPools ...*atev1.WorkerPool) (*fake.Clientset, *atefake.Clientset) { t.Helper() //nolint:staticcheck // NewSimpleClientset is what the informer machinery takes. @@ -144,7 +144,7 @@ func setupSyncerTest(t *testing.T, ctx context.Context, api *fakeControl, initPo // factories or worker goroutines. It returns those caches alongside the syncer. // The syncer's pod and apps clients are a fake clientset that the caches do not // watch. -func setupReconcileTest(t *testing.T, api *fakeControl, initPools ...*atev1alpha1.WorkerPool) (*WorkerPoolSyncer, cache.Indexer, cache.Indexer) { +func setupReconcileTest(t *testing.T, api *fakeControl, initPools ...*atev1.WorkerPool) (*WorkerPoolSyncer, cache.Indexer, cache.Indexer) { t.Helper() //nolint:staticcheck // NewSimpleClientset is what the informer machinery takes. @@ -180,9 +180,9 @@ func mustReconcile(t *testing.T, ctx context.Context, s *WorkerPoolSyncer, key w } // waitForWorker polls the registry until the named worker satisfies cond. -func waitForWorker(t *testing.T, ctx context.Context, api *fakeControl, name string, cond func(*ateapipb.Worker) bool) *ateapipb.Worker { +func waitForWorker(t *testing.T, ctx context.Context, api *fakeControl, name string, cond func(*ateapi.Worker) bool) *ateapi.Worker { t.Helper() - var got *ateapipb.Worker + var got *ateapi.Worker err := wait.PollUntilContextTimeout(ctx, 10*time.Millisecond, 5*time.Second, true, func(context.Context) (bool, error) { got = api.get(name) return cond(got), nil @@ -196,8 +196,8 @@ func waitForWorker(t *testing.T, ctx context.Context, api *fakeControl, name str // workerActive reports whether w is registered and ACTIVE. The syncer registers // a Worker UNAVAILABLE and marks it available in a later call, so a Worker that // exists is not yet one that takes Actors. -func workerActive(w *ateapipb.Worker) bool { - return w.GetStatus().GetState() == ateapipb.WorkerState_WORKER_STATE_ACTIVE +func workerActive(w *ateapi.Worker) bool { + return w.GetStatus().GetState() == ateapi.WorkerState_WORKER_STATE_ACTIVE } func TestSyncer_Lifecycle(t *testing.T) { @@ -241,7 +241,7 @@ func TestSyncer_Lifecycle(t *testing.T) { if err := fakeK8s.CoreV1().Pods(ns).Delete(ctx, podName, metav1.DeleteOptions{}); err != nil { t.Fatalf("delete pod: %v", err) } - waitForWorker(t, ctx, api, testPodUID, func(w *ateapipb.Worker) bool { return w == nil }) + waitForWorker(t, ctx, api, testPodUID, func(w *ateapi.Worker) bool { return w == nil }) } // A pool that sets no labels registers a worker carrying none, rather than one @@ -260,7 +260,7 @@ func TestSyncer_OmittedFields(t *testing.T) { t.Fatalf("create pod: %v", err) } - got := waitForWorker(t, ctx, api, testPodUID, func(w *ateapipb.Worker) bool { return w != nil }) + got := waitForWorker(t, ctx, api, testPodUID, func(w *ateapi.Worker) bool { return w != nil }) if len(got.GetLabels()) != 0 { t.Errorf("worker labels = %v, want none", got.GetLabels()) } @@ -295,7 +295,7 @@ func TestSyncer_DoesNotInferCapacityFromThePod(t *testing.T) { // The registry here is a fake, so what it holds is exactly what the syncer // sent. The syncer writes no capacity: it comes from the Worker's own // report, which is the worker's to make. - got := waitForWorker(t, ctx, api, testPodUID, func(w *ateapipb.Worker) bool { return w != nil }) + got := waitForWorker(t, ctx, api, testPodUID, func(w *ateapi.Worker) bool { return w != nil }) if got.GetStatus().GetCapacity() != nil { t.Errorf("worker capacity = %v, want none", got.GetStatus().GetCapacity()) } @@ -320,7 +320,7 @@ func TestSyncer_SoftDelete_MarksDraining(t *testing.T) { if w == nil { t.Fatal("worker should still exist while draining") } - if w.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_DRAINING { + if w.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_DRAINING { t.Errorf("worker state = %v, want DRAINING", w.GetStatus().GetState()) } } @@ -340,7 +340,7 @@ func TestSyncer_SoftDelete_NoPodIP(t *testing.T) { pod.DeletionTimestamp = &metav1.Time{Time: time.Unix(1, 0)} mustReconcile(t, ctx, s, seedPod(t, pods, pod)) - if got := api.get(testPodUID).GetStatus().GetState(); got != ateapipb.WorkerState_WORKER_STATE_DRAINING { + if got := api.get(testPodUID).GetStatus().GetState(); got != ateapi.WorkerState_WORKER_STATE_DRAINING { t.Errorf("worker state = %v, want DRAINING", got) } } @@ -363,7 +363,7 @@ func TestMarkWorkerDraining(t *testing.T) { t.Run("already draining returns nil without a write", func(t *testing.T) { api := newFakeControl() w := registeredWorker(ns, poolName, podName, testPodUID) - w.Status = &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_DRAINING} + w.Status = &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_DRAINING} seeded := api.put(w) s := &WorkerPoolSyncer{client: api} @@ -385,7 +385,7 @@ func TestMarkWorkerDraining(t *testing.T) { if err := s.markWorkerDraining(ctx, key); err != nil { t.Fatalf("markWorkerDraining = %v, want nil", err) } - if got := api.get(testPodUID).GetStatus().GetState(); got != ateapipb.WorkerState_WORKER_STATE_DRAINING { + if got := api.get(testPodUID).GetStatus().GetState(); got != ateapi.WorkerState_WORKER_STATE_DRAINING { t.Errorf("worker state = %v, want DRAINING", got) } }) @@ -464,7 +464,7 @@ func TestSyncer_EnqueueRegisteredWorkers_RetriesTransientListError(t *testing.T) api.put(registeredWorker("ns-enq-retry", "pool1", "worker-1", testPodUID)) failsLeft := 1 - api.setListHook(func(*ateapipb.ListWorkersRequest) error { + api.setListHook(func(*ateapi.ListWorkersRequest) error { if failsLeft > 0 { failsLeft-- return status.Error(codes.Unavailable, "transient failure") @@ -489,7 +489,7 @@ func TestSyncer_EnqueueRegisteredWorkers_RetriesTransientListError(t *testing.T) // cancelled, rather than spinning forever, when the API stays unavailable. func TestSyncer_ListWorkersPageWithRetry_StopsOnContextCancel(t *testing.T) { api := newFakeControl() - api.setListHook(func(*ateapipb.ListWorkersRequest) error { + api.setListHook(func(*ateapi.ListWorkersRequest) error { return status.Error(codes.Unavailable, "still down") }) s, _, _ := setupReconcileTest(t, api) @@ -522,7 +522,7 @@ func TestSyncer_EnqueueRegisteredWorkers_StreamsPagesAndRetriesLatePage(t *testi // The second page fails once before serving. failed := false - api.setListHook(func(req *ateapipb.ListWorkersRequest) error { + api.setListHook(func(req *ateapi.ListWorkersRequest) error { if req.GetOptions().GetPageToken() == "1" && !failed { failed = true return status.Error(codes.Unavailable, "transient failure on page") @@ -562,8 +562,8 @@ func TestSyncer_CreateWorker_BeforePodIP(t *testing.T) { if got.GetNodeName() != "node1" { t.Errorf("worker node = %q, want node1", got.GetNodeName()) } - if state := got.GetStatus().GetState(); state != ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE { - t.Errorf("worker state = %v, want %v", state, ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE) + if state := got.GetStatus().GetState(); state != ateapi.WorkerState_WORKER_STATE_UNAVAILABLE { + t.Errorf("worker state = %v, want %v", state, ateapi.WorkerState_WORKER_STATE_UNAVAILABLE) } if ips := got.GetStatus().GetIps(); len(ips) != 0 { t.Errorf("worker ips = %q, want none until its worker process registers", ips) @@ -619,7 +619,7 @@ func TestSyncer_UpdateWorker_RetryOnVersionConflict(t *testing.T) { conflicted := false api.setUpdateHookOnce(func(name string) { conflicted = true - if _, err := api.DrainWorker(ctx, &ateapipb.DrainWorkerRequest{Worker: &ateapipb.ObjectRef{Name: name}}); err != nil { + if _, err := api.DrainWorker(ctx, &ateapi.DrainWorkerRequest{Worker: &ateapi.ObjectRef{Name: name}}); err != nil { t.Errorf("injecting conflict: drain worker: %v", err) } }) @@ -641,7 +641,7 @@ func TestSyncer_UpdateWorker_RetryOnVersionConflict(t *testing.T) { if got.GetLabels()["foo"] != "baz" { t.Errorf("worker labels = %v, want foo=baz", got.GetLabels()) } - if got.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_DRAINING { + if got.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_DRAINING { t.Errorf("worker state = %v, want the concurrently injected DRAINING to survive the retry", got.GetStatus().GetState()) } } @@ -798,9 +798,9 @@ func TestSyncer_DeletedWorkerPool(t *testing.T) { if gone := apierrors.IsNotFound(err); gone != tc.deleted { t.Errorf("pod deleted = %v, want %v", gone, tc.deleted) } - wantState := ateapipb.WorkerState_WORKER_STATE_ACTIVE + wantState := ateapi.WorkerState_WORKER_STATE_ACTIVE if tc.deleted { - wantState = ateapipb.WorkerState_WORKER_STATE_DRAINING + wantState = ateapi.WorkerState_WORKER_STATE_DRAINING } if state := got.GetStatus().GetState(); state != wantState { t.Errorf("worker state = %v, want %v", state, wantState) @@ -829,7 +829,7 @@ func TestSyncer_DeletedWorkerPool_NotReadyPod(t *testing.T) { if _, err := fakeK8s.CoreV1().Pods(ns).Get(ctx, podName, metav1.GetOptions{}); !apierrors.IsNotFound(err) { t.Errorf("get pod = %v, want NotFound", err) } - if got := api.get(testPodUID).GetStatus().GetState(); got != ateapipb.WorkerState_WORKER_STATE_DRAINING { + if got := api.get(testPodUID).GetStatus().GetState(); got != ateapi.WorkerState_WORKER_STATE_DRAINING { t.Errorf("worker state = %v, want DRAINING", got) } } @@ -860,7 +860,7 @@ func TestSyncer_DeletedWorkerPool_Errors(t *testing.T) { if _, err := fakeK8s.CoreV1().Pods(ns).Get(ctx, podName, metav1.GetOptions{}); err != nil { t.Errorf("get pod: %v, want it left alone", err) } - if got := api.get(testPodUID).GetStatus().GetState(); got != ateapipb.WorkerState_WORKER_STATE_ACTIVE { + if got := api.get(testPodUID).GetStatus().GetState(); got != ateapi.WorkerState_WORKER_STATE_ACTIVE { t.Errorf("worker state = %v, want ACTIVE", got) } } @@ -906,14 +906,14 @@ func TestSyncer_OrphanedPodsOfDeletedPool_ViaInformer(t *testing.T) { if _, err := fakeK8s.CoreV1().Pods(ns).Create(ctx, pod, metav1.CreateOptions{}); err != nil { t.Fatalf("create pod: %v", err) } - waitForWorker(t, ctx, api, testPodUID, func(w *ateapipb.Worker) bool { - return w.GetStatus().GetState() == ateapipb.WorkerState_WORKER_STATE_ACTIVE + waitForWorker(t, ctx, api, testPodUID, func(w *ateapi.Worker) bool { + return w.GetStatus().GetState() == ateapi.WorkerState_WORKER_STATE_ACTIVE }) - if err := poolClient.ApiV1alpha1().WorkerPools(ns).Delete(ctx, poolName, metav1.DeleteOptions{}); err != nil { + if err := poolClient.AteV1().WorkerPools(ns).Delete(ctx, poolName, metav1.DeleteOptions{}); err != nil { t.Fatalf("delete pool: %v", err) } - waitForWorker(t, ctx, api, testPodUID, func(w *ateapipb.Worker) bool { return w == nil }) + waitForWorker(t, ctx, api, testPodUID, func(w *ateapi.Worker) bool { return w == nil }) if _, err := fakeK8s.CoreV1().Pods(ns).Get(ctx, podName, metav1.GetOptions{}); !apierrors.IsNotFound(err) { t.Errorf("get pod = %v, want NotFound", err) @@ -945,7 +945,7 @@ func TestSyncer_StartWaitsForWorkerPoolCache(t *testing.T) { // The pod cache is warm and the pool cache is not. There is no state to wait // for, so this gives the syncer a window to get it wrong in. err := wait.PollUntilContextTimeout(ctx, 20*time.Millisecond, 300*time.Millisecond, true, func(context.Context) (bool, error) { - if api.get(testPodUID).GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_ACTIVE { + if api.get(testPodUID).GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_ACTIVE { return false, errors.New("worker shut down before the WorkerPool cache synced") } return false, nil @@ -957,7 +957,7 @@ func TestSyncer_StartWaitsForWorkerPoolCache(t *testing.T) { // Once the pool cache syncs, the pod is reconciled against the pool, which // copies the pool's labels onto the surviving Worker. poolFactory.Start(ctx.Done()) - got := waitForWorker(t, ctx, api, testPodUID, func(w *ateapipb.Worker) bool { + got := waitForWorker(t, ctx, api, testPodUID, func(w *ateapi.Worker) bool { return w != nil && maps.Equal(w.GetLabels(), poolLabels) }) if got == nil { @@ -1042,8 +1042,8 @@ func TestSyncer_SoftDelete_ViaInformer(t *testing.T) { t.Fatalf("update pod: %v", err) } - waitForWorker(t, ctx, api, testPodUID, func(w *ateapipb.Worker) bool { - return w.GetStatus().GetState() == ateapipb.WorkerState_WORKER_STATE_DRAINING + waitForWorker(t, ctx, api, testPodUID, func(w *ateapi.Worker) bool { + return w.GetStatus().GetState() == ateapi.WorkerState_WORKER_STATE_DRAINING }) } @@ -1082,7 +1082,7 @@ func TestSyncer_TerminalPod_DeletesPod(t *testing.T) { if got := deletes[0].GetDeleteOptions().Preconditions; got == nil || got.UID == nil || *got.UID != testPodUID { t.Errorf("delete preconditions = %+v, want UID %s", got, testPodUID) } - if got := api.get(testPodUID).GetStatus().GetState(); got != ateapipb.WorkerState_WORKER_STATE_DRAINING { + if got := api.get(testPodUID).GetStatus().GetState(); got != ateapi.WorkerState_WORKER_STATE_DRAINING { t.Errorf("worker state = %v, want DRAINING", got) } }) @@ -1145,7 +1145,7 @@ func TestSyncer_TerminalPod_ViaInformer(t *testing.T) { t.Fatalf("update pod status: %v", err) } - waitForWorker(t, ctx, api, testPodUID, func(w *ateapipb.Worker) bool { return w == nil }) + waitForWorker(t, ctx, api, testPodUID, func(w *ateapi.Worker) bool { return w == nil }) if _, err := fakeK8s.CoreV1().Pods(ns).Get(ctx, podName, metav1.GetOptions{}); !apierrors.IsNotFound(err) { t.Errorf("get pod = %v, want NotFound", err) } @@ -1255,8 +1255,8 @@ func TestSyncer_PodWithIPButNotReadyIsUnavailable(t *testing.T) { if got == nil { t.Fatalf("worker not registered for a not-Ready pod with an IP; registry holds %v", api.names()) } - if state := got.GetStatus().GetState(); state != ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE { - t.Errorf("state = %v, want %v", state, ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE) + if state := got.GetStatus().GetState(); state != ateapi.WorkerState_WORKER_STATE_UNAVAILABLE { + t.Errorf("state = %v, want %v", state, ateapi.WorkerState_WORKER_STATE_UNAVAILABLE) } }) } @@ -1275,8 +1275,8 @@ func TestSyncer_DeleteNeverReadyPod(t *testing.T) { key := seedPod(t, pods, pod) mustReconcile(t, ctx, s, key) - if got := api.get(testPodUID); got.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE { - t.Fatalf("worker = %v, want it registered %v", got, ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE) + if got := api.get(testPodUID); got.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_UNAVAILABLE { + t.Fatalf("worker = %v, want it registered %v", got, ateapi.WorkerState_WORKER_STATE_UNAVAILABLE) } if err := pods.Delete(pod); err != nil { t.Fatalf("deleting pod: %v", err) @@ -1303,8 +1303,8 @@ func TestSyncer_RegisteredPodWithoutIPIsUnavailable(t *testing.T) { } mustReconcile(t, ctx, s, key) got := api.get(testPodUID) - if got.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE { - t.Errorf("state = %v, want %v", got.GetStatus().GetState(), ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE) + if got.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_UNAVAILABLE { + t.Errorf("state = %v, want %v", got.GetStatus().GetState(), ateapi.WorkerState_WORKER_STATE_UNAVAILABLE) } } @@ -1337,8 +1337,8 @@ func TestSyncer_ReadinessFlapDoesNotDeregister(t *testing.T) { if got == nil { t.Fatalf("worker deregistered on a readiness flap; registry holds %v", api.names()) } - if state := got.GetStatus().GetState(); state != ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE { - t.Errorf("state = %v on a readiness flap, want %v", state, ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE) + if state := got.GetStatus().GetState(); state != ateapi.WorkerState_WORKER_STATE_UNAVAILABLE { + t.Errorf("state = %v on a readiness flap, want %v", state, ateapi.WorkerState_WORKER_STATE_UNAVAILABLE) } if err := pods.Update(pod); err != nil { @@ -1346,8 +1346,8 @@ func TestSyncer_ReadinessFlapDoesNotDeregister(t *testing.T) { } mustReconcile(t, ctx, s, key) got = api.get(testPodUID) - if state := got.GetStatus().GetState(); state != ateapipb.WorkerState_WORKER_STATE_ACTIVE { - t.Errorf("state = %v once Ready again, want %v", state, ateapipb.WorkerState_WORKER_STATE_ACTIVE) + if state := got.GetStatus().GetState(); state != ateapi.WorkerState_WORKER_STATE_ACTIVE { + t.Errorf("state = %v once Ready again, want %v", state, ateapi.WorkerState_WORKER_STATE_ACTIVE) } } @@ -1370,7 +1370,7 @@ func TestSyncer_ReconcileErrorsAreClassified(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { api := newFakeControl() - api.setCreateHook(func(*ateapipb.Worker) error { + api.setCreateHook(func(*ateapi.Worker) error { return status.Error(tc.code, "rejected") }) s, pods, _ := setupReconcileTest(t, api, workerPool(ns, poolName, nil)) diff --git a/cmd/atecontroller/main.go b/cmd/atecontroller/main.go index 4af6bb9c5a..d264c67226 100644 --- a/cmd/atecontroller/main.go +++ b/cmd/atecontroller/main.go @@ -21,6 +21,8 @@ import ( "github.com/go-logr/logr" "github.com/spf13/pflag" + "go.ate.dev/substrate/api/ateapi/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/atecontroller/internal/controllers" "go.ate.dev/substrate/cmd/atecontroller/internal/workersync" "go.ate.dev/substrate/internal/ateapiauth" @@ -29,10 +31,8 @@ import ( "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/serverboot" "go.ate.dev/substrate/internal/version" - clientv1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" "go.ate.dev/substrate/pkg/client/clientset/versioned" "go.ate.dev/substrate/pkg/client/informers/externalversions" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "google.golang.org/grpc" corev1 "k8s.io/api/core/v1" @@ -101,7 +101,7 @@ var ( func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(clientv1alpha1.AddToScheme(scheme)) // Register our CRD + utilruntime.Must(atev1.AddToScheme(scheme)) // Register our CRD } const ( @@ -229,7 +229,7 @@ func main() { os.Exit(1) } - ateapiClient := ateapipb.NewControlClient(ateapiConn) + ateapiClient := ateapi.NewControlClient(ateapiConn) // Empty ServiceAccounts would not fail here: path.Join drops the empty // segment, yielding identities that parse but match nothing, so every @@ -316,7 +316,7 @@ func main() { // informer, so asking the shared cache for one would impose it on every other // controller here too. ateFactory := externalversions.NewSharedInformerFactory(ateClient, 0) - workerPoolInformer := ateFactory.Api().V1alpha1().WorkerPools() + workerPoolInformer := ateFactory.Ate().V1().WorkerPools() workerPodInformerFactory, workerPodInformer := workersync.WorkerPodInformer(k8sClient) // Start registers the informer event handlers, so it has to run before the diff --git a/cmd/atelet/egresspolicy.go b/cmd/atelet/egresspolicy.go index a3456cd352..eb6856981e 100644 --- a/cmd/atelet/egresspolicy.go +++ b/cmd/atelet/egresspolicy.go @@ -15,14 +15,14 @@ package main import ( + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/proto/ateletpb" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // toAteletEgressPolicy copies the destinations each rule of the control // plane's policy allows. Metadata and rule effects are dropped: the worker // does not apply them, and they name credentials it has no need to see. -func toAteletEgressPolicy(in *ateapipb.EgressPolicy) *ateletpb.EgressPolicy { +func toAteletEgressPolicy(in *ateapi.EgressPolicy) *ateletpb.EgressPolicy { if in == nil { return nil } @@ -43,7 +43,7 @@ func toAteletEgressPolicy(in *ateapipb.EgressPolicy) *ateletpb.EgressPolicy { return out } -func toEgressDestinations(hostnames []string, ports *ateapipb.Ports) *ateletpb.EgressDestinations { +func toEgressDestinations(hostnames []string, ports *ateapi.Ports) *ateletpb.EgressDestinations { out := &ateletpb.EgressDestinations{Hostnames: hostnames} if ports != nil { out.Ports = &ateletpb.EgressPorts{Numbers: ports.GetNumbers()} diff --git a/cmd/atelet/egresspolicy_test.go b/cmd/atelet/egresspolicy_test.go index 477a0e64c5..0c0ee4f5cc 100644 --- a/cmd/atelet/egresspolicy_test.go +++ b/cmd/atelet/egresspolicy_test.go @@ -18,47 +18,47 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/proto/ateletpb" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/testing/protocmp" ) func TestToAteletEgressPolicy(t *testing.T) { - effects := &ateapipb.HttpRuleEffects{ReplaceHeaders: []*ateapipb.CredentialHeader{{ + effects := &ateapi.HttpRuleEffects{ReplaceHeaders: []*ateapi.CredentialHeader{{ Header: "Authorization", CredentialUri: "secret://team-a/token", }}} for _, tc := range []struct { name string - in *ateapipb.EgressPolicy + in *ateapi.EgressPolicy want *ateletpb.EgressPolicy }{{ name: "no policy", }, { name: "no rules", - in: &ateapipb.EgressPolicy{Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "default"}}, + in: &ateapi.EgressPolicy{Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "default"}}, want: &ateletpb.EgressPolicy{}, }, { // Metadata and effects are the gateway's, and never reach the worker. name: "every protocol", - in: &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "default", Uid: "uid"}, - Rules: []*ateapipb.EgressRule{{ - Http: &ateapipb.HttpRule{ + in: &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "default", Uid: "uid"}, + Rules: []*ateapi.EgressRule{{ + Http: &ateapi.HttpRule{ Hostnames: []string{"api.example.com"}, - Ports: &ateapipb.Ports{Numbers: []int32{80, 8080}}, + Ports: &ateapi.Ports{Numbers: []int32{80, 8080}}, Effects: effects, }, }, { - Https: &ateapipb.HttpsRule{ + Https: &ateapi.HttpsRule{ Hostnames: []string{"*.example.com"}, - Ports: &ateapipb.Ports{All: &ateapipb.AllPorts{}}, + Ports: &ateapi.Ports{All: &ateapi.AllPorts{}}, Effects: effects, }, }, { - TlsPassthrough: &ateapipb.TlsPassthroughRule{ + TlsPassthrough: &ateapi.TlsPassthroughRule{ Hostnames: []string{"db.example.com", "cache.example.com"}, - Ports: &ateapipb.Ports{Numbers: []int32{5432}}, + Ports: &ateapi.Ports{Numbers: []int32{5432}}, }, }}, }, @@ -80,8 +80,8 @@ func TestToAteletEgressPolicy(t *testing.T) { }}}, }, { name: "rule without ports", - in: &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{{ - TlsPassthrough: &ateapipb.TlsPassthroughRule{Hostnames: []string{"db.example.com"}}, + in: &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{{ + TlsPassthrough: &ateapi.TlsPassthroughRule{Hostnames: []string{"db.example.com"}}, }}}, want: &ateletpb.EgressPolicy{Rules: []*ateletpb.EgressRule{{ TlsPassthrough: &ateletpb.EgressDestinations{Hostnames: []string{"db.example.com"}}, @@ -90,7 +90,7 @@ func TestToAteletEgressPolicy(t *testing.T) { // A rule of a protocol the copy does not carry keeps its place, and // allows nothing. name: "rule without a protocol", - in: &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{{}}}, + in: &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{{}}}, want: &ateletpb.EgressPolicy{Rules: []*ateletpb.EgressRule{{}}}, }} { t.Run(tc.name, func(t *testing.T) { diff --git a/cmd/atelet/helm_test.go b/cmd/atelet/helm_test.go index 4a05ce288e..43d06c4dc5 100644 --- a/cmd/atelet/helm_test.go +++ b/cmd/atelet/helm_test.go @@ -22,7 +22,7 @@ import ( "strings" "testing" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -219,7 +219,7 @@ func TestHelmGVisorSandboxConfigMatchesManifest(t *testing.T) { if err != nil { t.Fatal(err) } - var got, want atev1alpha1.SandboxConfig + var got, want atev1.SandboxConfig if err := yaml.Unmarshal(out, &got); err != nil { t.Fatal(err) } diff --git a/cmd/atelet/lifecycle_test.go b/cmd/atelet/lifecycle_test.go index 7bc276da1e..1d96035c65 100644 --- a/cmd/atelet/lifecycle_test.go +++ b/cmd/atelet/lifecycle_test.go @@ -30,6 +30,7 @@ import ( "testing" "time" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/atelet/internal/actordirs" "go.ate.dev/substrate/cmd/atelet/internal/ateletpath" "go.ate.dev/substrate/cmd/atelet/internal/filecache" @@ -44,7 +45,6 @@ import ( "go.ate.dev/substrate/internal/proto/ateworkerpb" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/volume" - "go.ate.dev/substrate/pkg/api/v1alpha1" "go.opentelemetry.io/otel/sdk/metric/metricdata" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -131,7 +131,7 @@ func (f *fakeWorker) RunWorkload(_ context.Context, req *ateworkerpb.RunWorkload return &ateworkerpb.RunWorkloadResponse{WorkerEpoch: f.workerEpoch}, nil } -func (f *fakeWorker) CheckpointWorkload(_ context.Context, req *ateworkerpb.CheckpointWorkloadRequest) (*ateworkerpb.CheckpointWorkloadResponse, error) { +func (f *fakeWorker) CheckpointWorkload(ctx context.Context, req *ateworkerpb.CheckpointWorkloadRequest) (*ateworkerpb.CheckpointWorkloadResponse, error) { f.recordActorDirs("CheckpointWorkload", req.GetActorDirs()) f.recordFidelity("CheckpointWorkload", req.GetFidelity()) dir := req.GetActorDirs().GetCheckpointDir() @@ -145,6 +145,9 @@ func (f *fakeWorker) CheckpointWorkload(_ context.Context, req *ateworkerpb.Chec if f.onCheckpoint != nil { f.onCheckpoint() } + if err := ctx.Err(); err != nil { + return nil, err + } return &ateworkerpb.CheckpointWorkloadResponse{SnapshotFiles: names}, nil } @@ -265,6 +268,7 @@ func runLocalSnapshotGC(t *testing.T, fidelity ateletpb.SnapshotFidelity, useDir anonGCSClient: fakeObjectStorage{data: release.tarball}, systemInfoVolumes: newSystemInfoVolumeRefresher(nil, nil), snapshots: snapshottracker.New(t.Context(), nil, clock.RealClock{}), + checkpointTimeout: defaultCheckpointTimeout, } sandboxRec := testSandboxRecord(release) spec := &ateletpb.WorkloadSpec{ @@ -458,6 +462,7 @@ func TestRestoreUsesRequestSandboxRuntime(t *testing.T) { anonGCSClient: fakeObjectStorage{data: checkpointRelease.tarball}, systemInfoVolumes: newSystemInfoVolumeRefresher(nil, nil), snapshots: snapshottracker.New(t.Context(), nil, clock.RealClock{}), + checkpointTimeout: defaultCheckpointTimeout, } checkpointRec, restoreRec := testSandboxRecord(checkpointRelease), testSandboxRecord(restoreRelease) spec := &ateletpb.WorkloadSpec{ @@ -2220,6 +2225,71 @@ func TestFailedRestoreUnschedulesDetach(t *testing.T) { } } +// TestResetActorDirsFailureIsCanceled checks that Run and Restore report a +// failed actordirs.ResetActorDirsKeepingVolumes as Canceled, which +// ate-api-server retries instead of crashing the actor, and that the retry +// succeeds once the reset can. +func TestResetActorDirsFailureIsCanceled(t *testing.T) { + for _, tc := range []struct { + name string + // prepare sets up the actor and returns the call to retry. + prepare func(t *testing.T, a *pluginActor) func() error + }{{ + name: "Run", + prepare: func(t *testing.T, a *pluginActor) func() error { + return func() error { + _, err := a.s.Run(t.Context(), &ateletpb.RunRequest{ + Atespace: "ate-demo", + ActorName: "counter", + ActorUid: pluginActorUID, + ActorTemplateAtespace: "default", + ActorTemplateName: "counter", + WorkerPodUid: pluginWorkerPodUID, + SandboxRuntime: runtimeFor(t, a.rec), + Spec: a.spec, + }) + return err + } + }, + }, { + name: "Restore", + prepare: func(t *testing.T, a *pluginActor) func() error { + req := a.restoreRequest(t, a.checkpointed(t, "pause-snap-1", 1)) + return func() error { + _, err := a.s.Restore(t.Context(), req) + return err + } + }, + }} { + t.Run(tc.name, func(t *testing.T) { + a := runPluginActor(t) + call := tc.prepare(t, a) + + // Replace the actor's empty volumes dir with a file. The reset keeps + // the volumes dir instead of recreating it, so its MkdirAll of that + // path fails with ENOTDIR. + volumesDir := ateletpath.ExternalVolumeMountsDir(pluginActorUID) + if err := os.Remove(volumesDir); err != nil { + t.Fatalf("removing volumes dir: %v", err) + } + if err := os.WriteFile(volumesDir, nil, 0o600); err != nil { + t.Fatalf("writing file at volumes dir: %v", err) + } + if err := call(); status.Code(err) != codes.Canceled { + t.Fatalf("%s = %v (code %s), want %s", tc.name, err, status.Code(err), codes.Canceled) + } + + // Without the file, the reset recreates the volumes dir. + if err := os.Remove(volumesDir); err != nil { + t.Fatalf("removing file at volumes dir: %v", err) + } + if err := call(); err != nil { + t.Errorf("%s retry: %v", tc.name, err) + } + }) + } +} + // TestRestoreAfterDetachReadsUpload resumes a suspended actor that atelet // detached before the control plane recorded the upload, so the control plane // still sends the Restore here: atelet restores the actor from the upload the @@ -2620,7 +2690,7 @@ func advertiseRuntime(t *testing.T, s *Atelet, rec *sandboxAssetsRecord) { } hash := bundleHash(rec) s.runtimes.register("test-worker-pod", advertisedClass{ - class: v1alpha1.SandboxClass(rec.SandboxClass), + class: atev1.SandboxClass(rec.SandboxClass), config: "test-config", hashed: []hashedVersion{{versionPlan: versionPlan{name: "v1", isDefault: true, rec: rec}, hash: hash}}, }) @@ -3656,3 +3726,148 @@ func TestRestoreLocalSnapshotFromEarlierBoot(t *testing.T) { } }) } + +// TestCheckpointFinishesWhenCallerCancels verifies that once Checkpoint has +// acquired the actor's lock and begun the checkpoint, canceling the caller's +// context mid-flight does not abort the worker checkpoint or snapshot commit, +// a longer caller deadline is preserved past checkpointTimeout, and a retry +// waits on the actor lock and answers from the committed snapshot. +func TestCheckpointFinishesWhenCallerCancels(t *testing.T) { + for _, mode := range []ateletpb.UploadMode{ + ateletpb.UploadMode_UPLOAD_MODE_DEFERRED, + ateletpb.UploadMode_UPLOAD_MODE_IMMEDIATE, + } { + t.Run(mode.String(), func(t *testing.T) { + a := runPluginActor(t) + a.s.checkpointTimeout = 10 * time.Millisecond + snap := a.snapshot("snap-1", 1) + + var workerCheckpoints atomic.Int32 + started := make(chan struct{}) + release := make(chan struct{}) + a.worker.onCheckpoint = func() { + if workerCheckpoints.Add(1) == 1 { + close(started) + <-release + } + } + + // Give the caller a deadline longer than checkpointTimeout so the + // detached context keeps the caller's longer deadline. + callerCtx, cancelCaller := context.WithTimeout(t.Context(), time.Minute) + defer cancelCaller() + + type cpResult struct { + resp *ateletpb.CheckpointResponse + err error + } + resCh := make(chan cpResult, 1) + go func() { + resp, err := a.s.Checkpoint(callerCtx, &ateletpb.CheckpointRequest{ + Atespace: "ate-demo", + ActorName: "counter", + ActorUid: pluginActorUID, + ActorTemplateAtespace: "default", + ActorTemplateName: "counter", + WorkerPodUid: pluginWorkerPodUID, + Spec: a.spec, + Snapshot: snap, + UploadConfig: &ateletpb.UploadConfig{Mode: mode}, + }) + resCh <- cpResult{resp, err} + }() + + select { + case <-started: + case <-time.After(10 * time.Second): + t.Fatal("timed out waiting for Checkpoint to reach worker") + } + + cancelCaller() + + retryCh := make(chan cpResult, 1) + go func() { + resp, err := a.checkpoint(t, snap, mode) + retryCh <- cpResult{resp, err} + }() + // Wait past checkpointTimeout while the retry is queued behind the + // first call's actor lock, verifying both that the retry blocks and + // that the caller's 1-minute deadline was not shortened to 10ms. + select { + case res := <-retryCh: + t.Fatalf("retried Checkpoint returned (%v, %v) while first Checkpoint was still in flight", res.resp, res.err) + case <-time.After(25 * time.Millisecond): + } + + close(release) + + for _, call := range []struct { + name string + ch <-chan cpResult + }{ + {name: "first", ch: resCh}, + {name: "retry", ch: retryCh}, + } { + res := <-call.ch + if res.err != nil { + t.Fatalf("%s Checkpoint: %v", call.name, res.err) + } + st := res.resp.GetState() + if got := st.GetLatestLocal().GetSnapshot(); !proto.Equal(got, snap) { + t.Errorf("%s latest_local = %v, want %v", call.name, got, snap) + } + if mode == ateletpb.UploadMode_UPLOAD_MODE_IMMEDIATE { + if got := st.GetLatestDurable().GetSnapshot(); !proto.Equal(got, snap) { + t.Errorf("%s latest_durable = %v, want %v", call.name, got, snap) + } + } + } + if n := workerCheckpoints.Load(); n != 1 { + t.Errorf("worker checkpointed the actor %d times, want once", n) + } + }) + } + + t.Run("bounded_by_checkpoint_timeout", func(t *testing.T) { + a := runPluginActor(t) + a.s.checkpointTimeout = 100 * time.Millisecond + + started := make(chan struct{}) + release := make(chan struct{}) + defer close(release) + a.worker.onCheckpoint = func() { + close(started) + <-release + } + + errCh := make(chan error, 1) + go func() { + _, err := a.checkpoint(t, a.snapshot("snap-timeout", 1), ateletpb.UploadMode_UPLOAD_MODE_DEFERRED) + errCh <- err + }() + + select { + case <-started: + case err := <-errCh: + t.Fatalf("Checkpoint returned before reaching worker: %v", err) + case <-time.After(10 * time.Second): + t.Fatal("timed out waiting for Checkpoint to reach worker") + } + + var err error + select { + case err = <-errCh: + case <-time.After(10 * time.Second): + t.Fatal("timed out waiting for Checkpoint to fail after checkpointTimeout") + } + if !errors.Is(err, context.DeadlineExceeded) && status.Code(err) != codes.DeadlineExceeded { + t.Fatalf("Checkpoint err = %v, want DeadlineExceeded", err) + } + + unlock, err := a.s.lockActor(t.Context(), pluginActorUID) + if err != nil { + t.Fatalf("lockActor after timed-out Checkpoint: %v", err) + } + unlock() + }) +} diff --git a/cmd/atelet/main.go b/cmd/atelet/main.go index abeaa9f4ae..1d2d846c3d 100644 --- a/cmd/atelet/main.go +++ b/cmd/atelet/main.go @@ -34,6 +34,9 @@ import ( "github.com/spf13/pflag" "github.com/spiffe/go-spiffe/v2/spiffeid" "github.com/spiffe/go-spiffe/v2/svid/x509svid" + "go.ate.dev/substrate/api/ateapi/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/cmd/atelet/internal/actordirs" "go.ate.dev/substrate/cmd/atelet/internal/apivalidation" "go.ate.dev/substrate/cmd/atelet/internal/ateletpath" @@ -65,12 +68,9 @@ import ( "go.ate.dev/substrate/internal/version" "go.ate.dev/substrate/internal/volume" "go.ate.dev/substrate/internal/volume/csi" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" "go.ate.dev/substrate/pkg/client/clientset/versioned" "go.ate.dev/substrate/pkg/client/informers/externalversions" "go.ate.dev/substrate/pkg/objectstorage" - "go.ate.dev/substrate/pkg/proto/ateapipb" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/metric" @@ -363,7 +363,7 @@ func main() { } var ateapiConn *grpc.ClientConn - var workerService ateapipb.WorkerServiceClient + var workerService ateapi.WorkerServiceClient var reporter snapshottracker.Reporter if !*grpcInsecure { dialOpts, err := ateapiauth.DialOptions(ateapiauth.ClientConfig{ @@ -383,7 +383,7 @@ func main() { serverboot.Fatal(ctx, "Failed to create ateapi client", err) } defer ateapiConn.Close() - workerService = ateapipb.NewWorkerServiceClient(ateapiConn) + workerService = ateapi.NewWorkerServiceClient(ateapiConn) reporter = &trackerReporter{workers: workerService} } @@ -420,8 +420,8 @@ func main() { ctx, workerDialer, wrappedAnonGCS, - objectstorev1.NewNodeProviderClient(objectStorePluginConn), - objectstorev1.NewAssetProviderClient(objectStorePluginConn), + objectstore.NewNodeProviderClient(objectStorePluginConn), + objectstore.NewAssetProviderClient(objectStorePluginConn), *objectStorePluginSocket, imageCache, sandboxAssetCache, @@ -488,7 +488,7 @@ func main() { ateletpb.RegisterWorkerSupportServer(workerFacingSrv, &workerSupportServer{ workers: workerService, - control: ateapipb.NewControlClient(ateapiConn), + control: ateapi.NewControlClient(ateapiConn), }) go func() { if err := workerFacingSrv.Serve(workerFacingLis); err != nil { @@ -530,8 +530,8 @@ func main() { // rewritten when the config changes. _, err = startWorkerSandboxSyncer(ctx, workerPodFactory.Core().V1().Pods(), - ateFactory.Api().V1alpha1().WorkerPools(), - ateFactory.Api().V1alpha1().SandboxConfigs(), + ateFactory.Ate().V1().WorkerPools(), + ateFactory.Ate().V1().SandboxConfigs(), wmService, nodepath.WorkersDir(), runtimes, prewarmer) if err != nil { @@ -695,8 +695,8 @@ type directCSIDriverConfigGetter struct { client versioned.Interface } -func (g *directCSIDriverConfigGetter) Get(name string) (*atev1alpha1.CSIDriverConfig, error) { - return g.client.ApiV1alpha1().CSIDriverConfigs().Get(context.Background(), name, metav1.GetOptions{}) +func (g *directCSIDriverConfigGetter) Get(name string) (*atev1.CSIDriverConfig, error) { + return g.client.AteV1().CSIDriverConfigs().Get(context.Background(), name, metav1.GetOptions{}) } // Atelet is a service that allows controlling workloads on individual @@ -723,10 +723,10 @@ type Atelet struct { // anonGCSClient reads gs:// assets the plugin cannot serve, without credentials. anonGCSClient objectstorage.ObjectStorage // objectStorePlugin moves external snapshot files between the node and storage. - objectStorePlugin objectstorev1.NodeProviderClient + objectStorePlugin objectstore.NodeProviderClient // assetPlugin fetches every sandbox asset first; anonGCSClient reads a gs:// // asset it cannot serve. - assetPlugin objectstorev1.AssetProviderClient + assetPlugin objectstore.AssetProviderClient // pluginSocket is the object-store plugin's socket, for error messages. pluginSocket string // snapshotScratchDir holds short-lived manifest directories; it must be @@ -753,8 +753,15 @@ type Atelet struct { // of each local snapshot. A local snapshot recording another, or none, // was written before the node last rebooted. bootID string + // checkpointTimeout is defaultCheckpointTimeout. Shortened in tests. + checkpointTimeout time.Duration } +// defaultCheckpointTimeout bounds a Checkpoint once it detaches from the +// caller's context, so a hung worker or object-store upload cannot hold the +// actor's lock forever. +const defaultCheckpointTimeout = 5 * time.Minute + var _ ateletpb.AteletServer = (*Atelet)(nil) // lockActor acquires the per-actor RPC lock for actorUID, or returns an error @@ -771,8 +778,8 @@ func NewService( ctx context.Context, workerDialer *WorkerDialer, anonGCSClient objectstorage.ObjectStorage, - objectStorePlugin objectstorev1.NodeProviderClient, - assetPlugin objectstorev1.AssetProviderClient, + objectStorePlugin objectstore.NodeProviderClient, + assetPlugin objectstore.AssetProviderClient, pluginSocket string, imageCache *imagecache.Store, sandboxAssetCache *filecache.Store, @@ -783,7 +790,7 @@ func NewService( csiDriverConfigGetter csi.CSIDriverConfigGetter, systemInfoVolumes *systemInfoVolumeRefresher, snapshots *snapshottracker.Tracker, - workers ateapipb.WorkerServiceClient, + workers ateapi.WorkerServiceClient, bootID string, ) *Atelet { wms := &Atelet{ @@ -804,6 +811,7 @@ func NewService( snapshots: snapshots, workerActorJWTs: newWorkerActorJWTs(workers), bootID: bootID, + checkpointTimeout: defaultCheckpointTimeout, } return wms } @@ -861,7 +869,7 @@ func (s *Atelet) Run(ctx context.Context, req *ateletpb.RunRequest) (resp *atele s.systemInfoVolumes.Deregister(actorUID) if err := actordirs.ResetActorDirsKeepingVolumes(actorUID); err != nil { - return nil, fmt.Errorf("while resetting actor dirs: %w", err) + return nil, status.Errorf(codes.Canceled, "while resetting actor dirs: %v", err) } if err := s.mountExternalVolumes(ctx, actorUID, req.GetSpec().GetVolumes()); err != nil { @@ -1040,6 +1048,19 @@ func (s *Atelet) Checkpoint(ctx context.Context, req *ateletpb.CheckpointRequest return &ateletpb.CheckpointResponse{State: state}, nil } + // Detach from caller cancellation once the checkpoint is underway so a + // caller timeout does not abort the checkpoint after the worker has + // started stopping the workload; a retry waits on lockActor for this + // attempt to finish and commit. Keep the later of the caller's deadline + // and checkpointTimeout so a hung worker or upload cannot hold the + // actor's lock forever without shortening a longer caller deadline. + deadline := time.Now().Add(s.checkpointTimeout) + if d, ok := ctx.Deadline(); ok && d.After(deadline) { + deadline = d + } + opCtx, cancel := context.WithDeadline(context.WithoutCancel(ctx), deadline) + defer cancel() + // Checkpoint requests no longer carry the sandbox config; recover the // version this actor was started with from the on-node record and re-fetch // it (a cache hit) so worker can drive runsc, and so we can pin it into the @@ -1051,7 +1072,7 @@ func (s *Atelet) Checkpoint(ctx context.Context, req *ateletpb.CheckpointRequest op.sandboxClass = sandboxRec.SandboxClass tAssets := time.Now() - assetPaths, err := s.ensureSandboxAssets(ctx, sandboxRec, ateletpath.SandboxAssetsDir(actorUID)) + assetPaths, err := s.ensureSandboxAssets(opCtx, sandboxRec, ateletpath.SandboxAssetsDir(actorUID)) dAssets = time.Since(tAssets) if err != nil { return nil, err @@ -1059,7 +1080,7 @@ func (s *Atelet) Checkpoint(ctx context.Context, req *ateletpb.CheckpointRequest checkpointDir := ateletpath.CheckpointStateDir(actorUID) - client, err := s.dialWorker(ctx, req.GetWorkerPodUid()) + client, err := s.dialWorker(opCtx, req.GetWorkerPodUid()) if err != nil { return nil, err } @@ -1073,7 +1094,7 @@ func (s *Atelet) Checkpoint(ctx context.Context, req *ateletpb.CheckpointRequest } tWorker := time.Now() - resp, err := client.CheckpointWorkload(ctx, &ateworkerpb.CheckpointWorkloadRequest{ + resp, err := client.CheckpointWorkload(opCtx, &ateworkerpb.CheckpointWorkloadRequest{ Atespace: actorRef.Atespace, ActorName: actorRef.Name, ActorTemplateAtespace: req.GetActorTemplateAtespace(), @@ -1111,7 +1132,7 @@ func (s *Atelet) Checkpoint(ctx context.Context, req *ateletpb.CheckpointRequest var state *ateletpb.ActorSnapshotState switch mode := req.GetUploadConfig().GetMode(); mode { case ateletpb.UploadMode_UPLOAD_MODE_DEFERRED: - if err := s.moveLocalCheckpoint(ctx, req, sandboxRec); err != nil { + if err := s.moveLocalCheckpoint(opCtx, req, sandboxRec); err != nil { dPersist = time.Since(tPersist) return nil, fmt.Errorf("while moving to local snapshot: %w", err) } @@ -1119,10 +1140,10 @@ func (s *Atelet) Checkpoint(ctx context.Context, req *ateletpb.CheckpointRequest case ateletpb.UploadMode_UPLOAD_MODE_IMMEDIATE: // CheckpointWorkload has already deleted the workload, so a retried // Checkpoint cannot redo this upload. It waits for the object-store plugin - // as long as ctx allows, and a plugin error reaches the control plane as + // as long as opCtx allows, and a plugin error reaches the control plane as // Internal, which crashes the actor. // TODO(#362): Because we do not cache the external snapshot files when upload fails, we have to mark the Actor as CRASHED. - if err := s.uploadExternalCheckpoint(ctx, req, checkpointDir, sandboxRec); err != nil { + if err := s.uploadExternalCheckpoint(opCtx, req, checkpointDir, sandboxRec); err != nil { dPersist = time.Since(tPersist) return nil, fmt.Errorf("while uploading external snapshot: %w", err) } @@ -1132,8 +1153,8 @@ func (s *Atelet) Checkpoint(ctx context.Context, req *ateletpb.CheckpointRequest // The snapshot is durable now, so the local copy only saves a // download: failing to keep it must not fail the checkpoint. // RemoveActorFilesExceptState cleans up checkpointDir if the move fails. - if err := s.moveLocalCheckpoint(ctx, req, sandboxRec); err != nil { - slog.WarnContext(ctx, "Failed to keep a local copy of the uploaded snapshot", slog.Any("actor", actorRef), slog.Any("err", err)) + if err := s.moveLocalCheckpoint(opCtx, req, sandboxRec); err != nil { + slog.WarnContext(opCtx, "Failed to keep a local copy of the uploaded snapshot", slog.Any("actor", actorRef), slog.Any("err", err)) } else { state = s.snapshots.CommitLocal(actorUID, snap) } @@ -1143,7 +1164,7 @@ func (s *Atelet) Checkpoint(ctx context.Context, req *ateletpb.CheckpointRequest dPersist = time.Since(tPersist) tCleanup := time.Now() - err = s.cleanUpAfterCheckpoint(ctx, req, state.GetLatestLocal() != nil) + err = s.cleanUpAfterCheckpoint(opCtx, req, state.GetLatestLocal() != nil) dCleanup = time.Since(tCleanup) if err != nil { return nil, err @@ -1651,11 +1672,11 @@ func (s *Atelet) Restore(ctx context.Context, req *ateletpb.RestoreRequest) (res } defer endStart() - // Not crashing the actor, because terminal errors here indicate problems with atelet, - // node or the disk itself. + // Canceled so ate-api-server retries instead of crashing the actor. A + // failure here points at atelet or the node's disk, not the actor. s.systemInfoVolumes.Deregister(actorUID) if err := actordirs.ResetActorDirsKeepingVolumes(actorUID); err != nil { - return nil, fmt.Errorf("while resetting actor dirs: %w", err) + return nil, status.Errorf(codes.Canceled, "while resetting actor dirs: %v", err) } // A restore may bring another runtime than the one staged here before, // so the assets dir is emptied for it; Run swaps a staged set in diff --git a/cmd/atelet/oci.go b/cmd/atelet/oci.go index 4cf7019008..3f72633d5b 100644 --- a/cmd/atelet/oci.go +++ b/cmd/atelet/oci.go @@ -33,7 +33,7 @@ import ( const ( // capabilityAll is the sentinel a template may put in drop to clear the - // whole default set. It is rejected in add (see v1alpha1.Capabilities). + // whole default set. It is rejected in add (see ateapi.Capabilities). capabilityAll = "ALL" ) diff --git a/cmd/atelet/runtime_prewarm_test.go b/cmd/atelet/runtime_prewarm_test.go index 19105e3cf9..811c97e817 100644 --- a/cmd/atelet/runtime_prewarm_test.go +++ b/cmd/atelet/runtime_prewarm_test.go @@ -35,22 +35,22 @@ import ( kubeinformers "k8s.io/client-go/informers" kubefake "k8s.io/client-go/kubernetes/fake" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/atelet/internal/ateletpath" "go.ate.dev/substrate/cmd/atelet/internal/filecache" - "go.ate.dev/substrate/pkg/api/v1alpha1" atefake "go.ate.dev/substrate/pkg/client/clientset/versioned/fake" "go.ate.dev/substrate/pkg/client/informers/externalversions" ) -func gvisorConfig(name, url, sha string) *v1alpha1.SandboxConfig { - return &v1alpha1.SandboxConfig{ +func gvisorConfig(name, url, sha string) *atev1.SandboxConfig { + return &atev1.SandboxConfig{ ObjectMeta: metav1.ObjectMeta{Name: name}, - Spec: v1alpha1.SandboxConfigSpec{ - SandboxClass: v1alpha1.SandboxClassGvisor, + Spec: atev1.SandboxConfigSpec{ + SandboxClass: atev1.SandboxClassGvisor, DefaultVersion: "v1", - Versions: []v1alpha1.SandboxVersionConfig{{ + Versions: []atev1.SandboxVersionConfig{{ Name: "v1", - Assets: map[string]map[string]v1alpha1.AssetFile{ + Assets: map[string]map[string]atev1.AssetFile{ runtime.GOARCH: { gvisorAssetName: {URL: url, SHA256: sha}, }, @@ -86,7 +86,7 @@ func indexedTestRuntimeAt(t *testing.T, index *runtimeIndex, url string, content Assets: map[string]assetEntry{gvisorAssetName: {URL: url, SHA256: fmt.Sprintf("%x", sha256.Sum256(content))}}, } hash := bundleHash(rec) - index.register("pod-a", advertisedClass{class: v1alpha1.SandboxClassGvisor, config: "gvisor-release", hashed: []hashedVersion{{ + index.register("pod-a", advertisedClass{class: atev1.SandboxClassGvisor, config: "gvisor-release", hashed: []hashedVersion{{ versionPlan: versionPlan{name: "v1", isDefault: true, rec: rec}, hash: hash, }}}) return hash @@ -323,7 +323,7 @@ func TestSyncPodPrewarmsDefaultRuntime(t *testing.T) { if !ok { t.Fatal("pod-a not indexed") } - cr, _ := wr.class(v1alpha1.SandboxClassGvisor) + cr, _ := wr.class(atev1.SandboxClassGvisor) want := []prewarmItem{{hash: cr.defaultHash, dir: s.defaultRuntimeDir("pod-a", cr.defaultHash)}} if got := rec.items(); !slices.Equal(got, want) { t.Errorf("prewarm handed %+v, want %+v", got, want) @@ -456,8 +456,8 @@ func TestDefaultRuntimePrewarmThroughSyncer(t *testing.T) { s, err := startWorkerSandboxSyncer(ctx, podFactory.Core().V1().Pods(), - ateFactory.Api().V1alpha1().WorkerPools(), - ateFactory.Api().V1alpha1().SandboxConfigs(), + ateFactory.Ate().V1().WorkerPools(), + ateFactory.Ate().V1().SandboxConfigs(), newScriptAssetFetcher(t), // the syncer's runsc probe; prewarm goes through herder workersDir, index, p) if err != nil { @@ -483,7 +483,7 @@ func TestDefaultRuntimePrewarmThroughSyncer(t *testing.T) { return err == nil && len(left) == 0 }) wr, _ := index.worker("pod-a") - cr, _ := wr.class(v1alpha1.SandboxClassGvisor) + cr, _ := wr.class(atev1.SandboxClassGvisor) linked := filepath.Join(s.defaultRuntimeDir("pod-a", cr.defaultHash), gvisorAssetName, "runsc") waitFor(t, "the worker's default runtime to be linked under its directory", func() bool { return exists(linked) }) if dirs, err := os.ReadDir(filepath.Join(s.podDir("pod-a"), defaultRuntimeDirsName)); err != nil || len(dirs) != 1 { diff --git a/cmd/atelet/sandbox_assets.go b/cmd/atelet/sandbox_assets.go index bcacecab65..a467188243 100644 --- a/cmd/atelet/sandbox_assets.go +++ b/cmd/atelet/sandbox_assets.go @@ -37,13 +37,13 @@ import ( "strings" "time" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/cmd/atelet/internal/ateletpath" "go.ate.dev/substrate/cmd/atelet/internal/atomicfile" "go.ate.dev/substrate/cmd/atelet/internal/filecache" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/pkg/objectstorage" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -428,7 +428,7 @@ func (s *Atelet) downloadAnonymous(ctx context.Context, entry assetEntry, shown, // signed URL or other credential in a form no scrubber can recognize. func (s *Atelet) fetchFromPlugin(ctx context.Context, entry assetEntry, shown, path string) codes.Code { slog.DebugContext(ctx, "Fetching sandbox asset through the object-store plugin", slog.String("url", shown)) - _, err := s.assetPlugin.FetchAsset(ctx, &objectstorev1.FetchAssetRequest{ + _, err := s.assetPlugin.FetchAsset(ctx, &objectstore.FetchAssetRequest{ AssetUri: entry.URL, Sha256: entry.SHA256, WritePath: path, @@ -446,7 +446,7 @@ func (s *Atelet) pluginError(ctx context.Context, entry assetEntry, shown string switch code { case codes.Unimplemented: msg = fmt.Sprintf("the object-store plugin at %s does not serve %s; private sandbox assets need a plugin that implements it", - s.pluginSocket, objectstorev1.AssetProvider_ServiceDesc.ServiceName) + s.pluginSocket, objectstore.AssetProvider_ServiceDesc.ServiceName) case codes.Unavailable: newErr, msg = apierror.Unavailable, fmt.Sprintf("the object-store plugin at %s is unavailable", s.pluginSocket) case codes.Canceled, codes.DeadlineExceeded: diff --git a/cmd/atelet/sandbox_assets_plugin_test.go b/cmd/atelet/sandbox_assets_plugin_test.go index a008246283..afa1c6e411 100644 --- a/cmd/atelet/sandbox_assets_plugin_test.go +++ b/cmd/atelet/sandbox_assets_plugin_test.go @@ -30,6 +30,7 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateinterceptors" "go.ate.dev/substrate/internal/objectstoreplugin" @@ -37,7 +38,6 @@ import ( "go.ate.dev/substrate/internal/pluginsocket" "go.ate.dev/substrate/internal/serverboot" "go.ate.dev/substrate/pkg/objectstorage" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/health" @@ -82,11 +82,11 @@ func (b *bucketStorage) PutObject(_ context.Context, bucket, object string, r io // countingAssetClient counts FetchAsset calls before passing them on. type countingAssetClient struct { - objectstorev1.AssetProviderClient + objectstore.AssetProviderClient calls atomic.Int64 } -func (c *countingAssetClient) FetchAsset(ctx context.Context, in *objectstorev1.FetchAssetRequest, opts ...grpc.CallOption) (*objectstorev1.FetchAssetResponse, error) { +func (c *countingAssetClient) FetchAsset(ctx context.Context, in *objectstore.FetchAssetRequest, opts ...grpc.CallOption) (*objectstore.FetchAssetResponse, error) { c.calls.Add(1) return c.AssetProviderClient.FetchAsset(ctx, in, opts...) } @@ -302,7 +302,7 @@ func TestFetchAssetThroughPlugin(t *testing.T) { t.Fatal(err) } t.Cleanup(func() { conn.Close() }) - f.herder.assetPlugin = objectstorev1.NewAssetProviderClient(conn) + f.herder.assetPlugin = objectstore.NewAssetProviderClient(conn) _, err = f.fetch(t.Context(), assetEntry{URL: "s3://" + testAssetBucket + "/kata-assets/vmlinux", SHA256: strings.Repeat("a", 64)}) if apierror.Code(err) != codes.Unavailable { t.Fatalf("fetchAsset with the plugin down = %v (code %s), want %s", err, apierror.Code(err), codes.Unavailable) @@ -331,13 +331,13 @@ func TestFetchAssetThroughPlugin(t *testing.T) { t.Fatal(err) } t.Cleanup(func() { conn.Close() }) - f.herder.assetPlugin = objectstorev1.NewAssetProviderClient(conn) + f.herder.assetPlugin = objectstore.NewAssetProviderClient(conn) f.herder.pluginSocket = sock _, err = f.fetch(t.Context(), assetEntry{URL: "s3://" + testAssetBucket + "/kata-assets/vmlinux", SHA256: strings.Repeat("a", 64)}) if apierror.Code(err) != codes.FailedPrecondition { t.Fatalf("fetchAsset with an old plugin = %v (code %s), want %s", err, apierror.Code(err), codes.FailedPrecondition) } - for _, want := range []string{"s3://" + testAssetBucket + "/kata-assets/vmlinux", sock, "objectstore.v1.AssetProvider"} { + for _, want := range []string{"s3://" + testAssetBucket + "/kata-assets/vmlinux", sock, "substrate.objectstore.v1.AssetProvider"} { if !strings.Contains(err.Error(), want) { t.Errorf("error %q does not name %q", err, want) } @@ -352,7 +352,7 @@ type fakeAssetClient struct { err error } -func (c fakeAssetClient) FetchAsset(_ context.Context, in *objectstorev1.FetchAssetRequest, _ ...grpc.CallOption) (*objectstorev1.FetchAssetResponse, error) { +func (c fakeAssetClient) FetchAsset(_ context.Context, in *objectstore.FetchAssetRequest, _ ...grpc.CallOption) (*objectstore.FetchAssetResponse, error) { if c.data != nil { if err := os.WriteFile(in.GetWritePath(), c.data, 0o600); err != nil { return nil, err @@ -361,7 +361,7 @@ func (c fakeAssetClient) FetchAsset(_ context.Context, in *objectstorev1.FetchAs if c.err != nil { return nil, c.err } - return &objectstorev1.FetchAssetResponse{}, nil + return &objectstore.FetchAssetResponse{}, nil } // TestFetchAssetAnonymousFallback covers when atelet reads an asset @@ -557,7 +557,7 @@ type cancelingAssetClient struct { err error } -func (c cancelingAssetClient) FetchAsset(context.Context, *objectstorev1.FetchAssetRequest, ...grpc.CallOption) (*objectstorev1.FetchAssetResponse, error) { +func (c cancelingAssetClient) FetchAsset(context.Context, *objectstore.FetchAssetRequest, ...grpc.CallOption) (*objectstore.FetchAssetResponse, error) { c.cancel() return nil, c.err } @@ -609,7 +609,7 @@ func TestFetchAssetKeepsCredentialsOutOfErrors(t *testing.T) { sum := strings.Repeat("a", 64) for _, tc := range []struct { name string - plugin objectstorev1.AssetProviderClient + plugin objectstore.AssetProviderClient wantCode codes.Code }{ {"in-tree plugin rejects the URL", nil, codes.Internal}, diff --git a/cmd/atelet/sandbox_runtime_index.go b/cmd/atelet/sandbox_runtime_index.go index 4c5124df48..eb1b872687 100644 --- a/cmd/atelet/sandbox_runtime_index.go +++ b/cmd/atelet/sandbox_runtime_index.go @@ -23,11 +23,11 @@ import ( "os" "sync" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/atelet/internal/atomicfile" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/hardware" "go.ate.dev/substrate/internal/proto/ateletpb" - "go.ate.dev/substrate/pkg/api/v1alpha1" ) // runtimeIndex is this node's view of the sandbox runtimes its workers @@ -88,7 +88,7 @@ type indexedRuntime struct { // config's runtimes. A pool runs one class today, so a worker advertises // one; the shape admits the several a pool will be allowed to run. type workerRuntime struct { - classes map[v1alpha1.SandboxClass]*classRuntime + classes map[atev1.SandboxClass]*classRuntime } // classRuntime is what a worker advertises for one sandbox class. @@ -100,7 +100,7 @@ type classRuntime struct { } // class returns what the worker advertises for c. -func (w *workerRuntime) class(c v1alpha1.SandboxClass) (*classRuntime, bool) { +func (w *workerRuntime) class(c atev1.SandboxClass) (*classRuntime, bool) { cr, ok := w.classes[c] return cr, ok } @@ -108,7 +108,7 @@ func (w *workerRuntime) class(c v1alpha1.SandboxClass) (*classRuntime, bool) { // advertisedClass is one sandbox class a worker advertises: the config its // pool runs for the class, with the config's versions hashed. type advertisedClass struct { - class v1alpha1.SandboxClass + class atev1.SandboxClass config string hashed []hashedVersion } @@ -191,7 +191,7 @@ func (x *runtimeIndex) writeIndex(extraHash string, extra *indexedRuntime) error func (x *runtimeIndex) register(podUID string, advertised ...advertisedClass) error { x.mu.Lock() defer x.mu.Unlock() - wr := &workerRuntime{classes: make(map[v1alpha1.SandboxClass]*classRuntime, len(advertised))} + wr := &workerRuntime{classes: make(map[atev1.SandboxClass]*classRuntime, len(advertised))} for _, a := range advertised { cr := &classRuntime{config: a.config} seen := make(map[string]bool, len(a.hashed)) diff --git a/cmd/atelet/sandbox_runtime_index_test.go b/cmd/atelet/sandbox_runtime_index_test.go index 57d4f9a60a..c70713428d 100644 --- a/cmd/atelet/sandbox_runtime_index_test.go +++ b/cmd/atelet/sandbox_runtime_index_test.go @@ -22,10 +22,10 @@ import ( "slices" "testing" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/hardware" "go.ate.dev/substrate/internal/proto/ateletpb" - "go.ate.dev/substrate/pkg/api/v1alpha1" "google.golang.org/grpc/codes" ) @@ -48,7 +48,7 @@ func TestRuntimeIndex(t *testing.T) { x := newRuntimeIndex() v1, v2 := hashedTestVersion(t, "v1", true, shaA), hashedTestVersion(t, "v2", false, shaB) - gvisor := v1alpha1.SandboxClassGvisor + gvisor := atev1.SandboxClassGvisor x.register("pod-1", advertisedClass{class: gvisor, config: "config-x", hashed: []hashedVersion{v1, v2}}) for _, v := range []hashedVersion{v1, v2} { rt, ok := x.lookup(v.hash) @@ -64,7 +64,7 @@ func TestRuntimeIndex(t *testing.T) { if !ok || cr.config != "config-x" || cr.defaultHash != v1.hash || !slices.Equal(cr.hashes, []string{v1.hash, v2.hash}) { t.Errorf("worker(pod-1).class(gvisor) = %+v, %v; want config-x with %s default and both hashes", cr, ok, v1.hash) } - if _, ok := wr.class(v1alpha1.SandboxClassMicroVM); ok { + if _, ok := wr.class(atev1.SandboxClassMicroVM); ok { t.Error("worker(pod-1) advertises a class its pool does not run") } @@ -116,7 +116,7 @@ func TestRuntimeIndexRegisterRuntimes(t *testing.T) { shaC = "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" ) x := newRuntimeIndex() - gvisor := v1alpha1.SandboxClassGvisor + gvisor := atev1.SandboxClassGvisor old := hashedTestVersion(t, "v1", true, shaA) x.register("pod-1", advertisedClass{class: gvisor, config: "config-x", hashed: []hashedVersion{old}}) @@ -153,7 +153,7 @@ func TestResolveRuntime(t *testing.T) { if _, err := s.advertisedRuntime(t.Context(), placed); apierror.Code(err) != codes.FailedPrecondition { t.Fatalf("advertisedRuntime before any worker advertises it = %v, want %s", err, codes.FailedPrecondition) } - s.runtimes.register("pod-1", advertisedClass{class: v1alpha1.SandboxClassGvisor, config: "config-x", hashed: []hashedVersion{advertised}}) + s.runtimes.register("pod-1", advertisedClass{class: atev1.SandboxClassGvisor, config: "config-x", hashed: []hashedVersion{advertised}}) rec, err := s.advertisedRuntime(t.Context(), placed) if err != nil { t.Fatalf("advertisedRuntime: %v", err) @@ -200,7 +200,7 @@ func TestRuntimeIndexPersists(t *testing.T) { if err := x.registerRuntimes("config-x", []hashedVersion{v1}); err != nil { t.Fatal(err) } - if err := x.register("pod-1", advertisedClass{class: v1alpha1.SandboxClassGvisor, config: "config-x", hashed: []hashedVersion{v1, v2}}); err != nil { + if err := x.register("pod-1", advertisedClass{class: atev1.SandboxClassGvisor, config: "config-x", hashed: []hashedVersion{v1, v2}}); err != nil { t.Fatal(err) } diff --git a/cmd/atelet/snapshot_transfer.go b/cmd/atelet/snapshot_transfer.go index fedac43674..8af1a74276 100644 --- a/cmd/atelet/snapshot_transfer.go +++ b/cmd/atelet/snapshot_transfer.go @@ -20,8 +20,8 @@ import ( "os" "path/filepath" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/internal/pluginsocket" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -59,7 +59,7 @@ func (s *Atelet) fetchSnapshotFiles(ctx context.Context, actor actorRef, snapsho if err != nil { return pluginsocket.CallError(err) } - _, err = s.objectStorePlugin.FetchSnapshot(ctx, &objectstorev1.FetchSnapshotRequest{ + _, err = s.objectStorePlugin.FetchSnapshot(ctx, &objectstore.FetchSnapshotRequest{ SnapshotUri: snapshotURI, WritePath: dstDir, Files: files, @@ -81,7 +81,7 @@ func (s *Atelet) uploadSnapshotFiles(ctx context.Context, actor actorRef, snapsh if err != nil { return err } - _, err = s.objectStorePlugin.UploadSnapshot(ctx, &objectstorev1.UploadSnapshotRequest{ + _, err = s.objectStorePlugin.UploadSnapshot(ctx, &objectstore.UploadSnapshotRequest{ SnapshotUri: snapshotURI, LocalPath: srcDir, Files: files, diff --git a/cmd/atelet/snapshot_transfer_test.go b/cmd/atelet/snapshot_transfer_test.go index d46518c376..0477142e91 100644 --- a/cmd/atelet/snapshot_transfer_test.go +++ b/cmd/atelet/snapshot_transfer_test.go @@ -27,6 +27,7 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/cmd/atelet/internal/snapshottracker" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" @@ -36,7 +37,6 @@ import ( "go.ate.dev/substrate/internal/pluginsocket" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/pkg/objectstorage" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/connectivity" @@ -62,6 +62,7 @@ func newPluginHerder(t *testing.T, store objectstorage.ObjectStorage) *Atelet { snapshots: snapshottracker.New(t.Context(), nil, clock.RealClock{}), sandboxAssetCache: newTestAssetCache(t), runtimes: newRuntimeIndex(), + checkpointTimeout: defaultCheckpointTimeout, } } @@ -161,11 +162,11 @@ type failingNodePlugin struct { err error } -func (p failingNodePlugin) FetchSnapshot(context.Context, *objectstorev1.FetchSnapshotRequest, ...grpc.CallOption) (*objectstorev1.FetchSnapshotResponse, error) { +func (p failingNodePlugin) FetchSnapshot(context.Context, *objectstore.FetchSnapshotRequest, ...grpc.CallOption) (*objectstore.FetchSnapshotResponse, error) { return nil, p.err } -func (p failingNodePlugin) UploadSnapshot(context.Context, *objectstorev1.UploadSnapshotRequest, ...grpc.CallOption) (*objectstorev1.UploadSnapshotResponse, error) { +func (p failingNodePlugin) UploadSnapshot(context.Context, *objectstore.UploadSnapshotRequest, ...grpc.CallOption) (*objectstore.UploadSnapshotResponse, error) { return nil, p.err } @@ -416,7 +417,7 @@ func (s *pluginSidecar) start() { return } srv := grpc.NewServer() - objectstorev1.RegisterNodeProviderServer(srv, s.plugin) + objectstore.RegisterNodeProviderServer(srv, s.plugin) healthpb.RegisterHealthServer(srv, health.NewServer()) go srv.Serve(lis) s.mu.Lock() @@ -455,7 +456,7 @@ func TestCheckpointUploadWaitsOutPluginOutage(t *testing.T) { t.Fatalf("WaitReady = %v", err) } s := &Atelet{ - objectStorePlugin: objectstorev1.NewNodeProviderClient(conn), + objectStorePlugin: objectstore.NewNodeProviderClient(conn), workerActorJWTs: testWorkerActorJWTs(), snapshotScratchDir: t.TempDir(), } diff --git a/cmd/atelet/snapshotcache.go b/cmd/atelet/snapshotcache.go index d7eeb28769..3cf2474fef 100644 --- a/cmd/atelet/snapshotcache.go +++ b/cmd/atelet/snapshotcache.go @@ -43,13 +43,13 @@ import ( "github.com/spf13/pflag" "golang.org/x/sync/errgroup" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/atelet/internal/ateletpath" "go.ate.dev/substrate/cmd/atelet/internal/filecache" "go.ate.dev/substrate/cmd/atelet/internal/filecachegc" "go.ate.dev/substrate/internal/nodepath" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" ) var ( @@ -152,10 +152,10 @@ const ( // every other restore too. A copy is still one download per snapshot per // node. func cacheModeFor(sandboxClass string) cacheMode { - switch atev1alpha1.SandboxClass(sandboxClass) { - case atev1alpha1.SandboxClassGvisor: + switch atev1.SandboxClass(sandboxClass) { + case atev1.SandboxClassGvisor: return cacheModeLink - case atev1alpha1.SandboxClassMicroVM: + case atev1.SandboxClassMicroVM: return cacheModeCopy default: return cacheModeOff diff --git a/cmd/atelet/snapshotcache_test.go b/cmd/atelet/snapshotcache_test.go index 109315c78d..10aa4c8219 100644 --- a/cmd/atelet/snapshotcache_test.go +++ b/cmd/atelet/snapshotcache_test.go @@ -26,9 +26,9 @@ import ( "testing" "time" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/atelet/internal/filecache" "go.ate.dev/substrate/internal/proto/ateletpb" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" "go.ate.dev/substrate/pkg/objectstorage" ) @@ -169,13 +169,13 @@ func TestSnapshotCacheMode(t *testing.T) { } func TestCacheModeFor(t *testing.T) { - if got := cacheModeFor(string(atev1alpha1.SandboxClassGvisor)); got != cacheModeLink { + if got := cacheModeFor(string(atev1.SandboxClassGvisor)); got != cacheModeLink { t.Errorf("gVisor consumes restore state read-only; want cacheModeLink, got %v", got) } // ateworker-microvm keeps memory-ranges open for the VM's life, merges // deltas into it, and drops it from the page cache; through a link each // of those would reach the cache's entry, so it gets private copies. - if got := cacheModeFor(string(atev1alpha1.SandboxClassMicroVM)); got != cacheModeCopy { + if got := cacheModeFor(string(atev1.SandboxClassMicroVM)); got != cacheModeCopy { t.Errorf("micro-VM keeps and reworks its restore files; want cacheModeCopy, got %v", got) } if got := cacheModeFor(""); got != cacheModeOff { diff --git a/cmd/atelet/snapshotreport.go b/cmd/atelet/snapshotreport.go index 2ae96e6b2f..82fc7ced01 100644 --- a/cmd/atelet/snapshotreport.go +++ b/cmd/atelet/snapshotreport.go @@ -17,15 +17,15 @@ package main import ( "context" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/atelet/internal/snapshottracker" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // trackerReporter is the snapshottracker.Reporter that reports to the control // plane's WorkerService, with atelet's own client certificate. -type trackerReporter struct{ workers ateapipb.WorkerServiceClient } +type trackerReporter struct{ workers ateapi.WorkerServiceClient } var _ snapshottracker.Reporter = (*trackerReporter)(nil) @@ -34,7 +34,7 @@ var _ snapshottracker.Reporter = (*trackerReporter)(nil) // error unwrapped, so the tracker can tell a refusal from a failure to reach // it. func (r *trackerReporter) ReportActorSnapshotState(ctx context.Context, actorUID string, actor resources.ActorRef, state *ateletpb.ActorSnapshotState) error { - _, err := r.workers.ReportActorSnapshotState(ctx, &ateapipb.ReportActorSnapshotStateRequest{ + _, err := r.workers.ReportActorSnapshotState(ctx, &ateapi.ReportActorSnapshotStateRequest{ Actor: actor.ToObjectRef(), ActorUid: actorUID, State: toAteAPIActorSnapshotState(state), @@ -46,11 +46,11 @@ func (r *trackerReporter) ReportActorSnapshotState(ctx context.Context, actorUID // control plane's, which carries each snapshot's fields inline. A snapshot // atelet does not hold stays unset, since the control plane reads a state with // neither latest_local nor uploading as a detach. -func toAteAPIActorSnapshotState(in *ateletpb.ActorSnapshotState) *ateapipb.ActorSnapshotState { +func toAteAPIActorSnapshotState(in *ateletpb.ActorSnapshotState) *ateapi.ActorSnapshotState { if in == nil { return nil } - return &ateapipb.ActorSnapshotState{ + return &ateapi.ActorSnapshotState{ LatestLocal: toAteAPISnapshotReport(in.GetLatestLocal()), Uploading: toAteAPISnapshotReport(in.GetUploading()), LatestDurable: toAteAPISnapshotReport(in.GetLatestDurable()), @@ -60,12 +60,12 @@ func toAteAPIActorSnapshotState(in *ateletpb.ActorSnapshotState) *ateapipb.Actor // toAteAPISnapshotReport converts one of atelet's SnapshotReports to the // control plane's. A report that names no snapshot converts to nil. -func toAteAPISnapshotReport(in *ateletpb.SnapshotReport) *ateapipb.SnapshotReport { +func toAteAPISnapshotReport(in *ateletpb.SnapshotReport) *ateapi.SnapshotReport { snap := in.GetSnapshot() if snap == nil { return nil } - out := &ateapipb.SnapshotReport{ + out := &ateapi.SnapshotReport{ Uuid: snap.GetSnapshotUuid(), Generation: snap.GetGeneration(), Fidelity: toAteAPIFidelity(snap.GetFidelity()), @@ -73,7 +73,7 @@ func toAteAPISnapshotReport(in *ateletpb.SnapshotReport) *ateapipb.SnapshotRepor DurableCompleteTime: in.GetDurableCompleteTime(), } if obj := snap.GetObject(); obj != nil { - out.Object = &ateapipb.ObjectSnapshot{SnapshotUri: obj.GetSnapshotUri()} + out.Object = &ateapi.ObjectSnapshot{SnapshotUri: obj.GetSnapshotUri()} } return out } @@ -81,15 +81,15 @@ func toAteAPISnapshotReport(in *ateletpb.SnapshotReport) *ateapipb.SnapshotRepor // toAteAPIFidelity maps atelet's fidelity enum onto the identical public one, // level by level. Anything else goes out as UNSPECIFIED, which the control // plane rejects. -func toAteAPIFidelity(in ateletpb.SnapshotFidelity) ateapipb.SnapshotFidelity { +func toAteAPIFidelity(in ateletpb.SnapshotFidelity) ateapi.SnapshotFidelity { switch in { case ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES: - return ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES + return ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES case ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS: - return ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS + return ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS case ateletpb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY: - return ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY + return ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY default: - return ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED + return ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED } } diff --git a/cmd/atelet/snapshotreport_test.go b/cmd/atelet/snapshotreport_test.go index 4285864dc6..6814e5e803 100644 --- a/cmd/atelet/snapshotreport_test.go +++ b/cmd/atelet/snapshotreport_test.go @@ -19,11 +19,11 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/atelet/internal/ateletpath" "go.ate.dev/substrate/cmd/atelet/internal/snapshottracker" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -35,22 +35,22 @@ import ( // fakeReportService is a WorkerServiceClient that records the snapshot state // reports it receives, and fails them with err. type fakeReportService struct { - ateapipb.WorkerServiceClient + ateapi.WorkerServiceClient - reports chan *ateapipb.ReportActorSnapshotStateRequest + reports chan *ateapi.ReportActorSnapshotStateRequest err error } func newFakeReportService() *fakeReportService { - return &fakeReportService{reports: make(chan *ateapipb.ReportActorSnapshotStateRequest, 10)} + return &fakeReportService{reports: make(chan *ateapi.ReportActorSnapshotStateRequest, 10)} } -func (s *fakeReportService) ReportActorSnapshotState(_ context.Context, in *ateapipb.ReportActorSnapshotStateRequest, _ ...grpc.CallOption) (*ateapipb.ReportActorSnapshotStateResponse, error) { +func (s *fakeReportService) ReportActorSnapshotState(_ context.Context, in *ateapi.ReportActorSnapshotStateRequest, _ ...grpc.CallOption) (*ateapi.ReportActorSnapshotStateResponse, error) { s.reports <- in if s.err != nil { return nil, s.err } - return &ateapipb.ReportActorSnapshotStateResponse{}, nil + return &ateapi.ReportActorSnapshotStateResponse{}, nil } // TestTrackerReporterSendsState reports the actor's state as the control @@ -68,12 +68,12 @@ func TestTrackerReporterSendsState(t *testing.T) { } durable := local("s1", 1) durable.DurableCompleteTime = upload - reported := func(name string, generation int32) *ateapipb.SnapshotReport { - return &ateapipb.SnapshotReport{ + reported := func(name string, generation int32) *ateapi.SnapshotReport { + return &ateapi.SnapshotReport{ Uuid: name, Generation: generation, - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: "gs://test-bucket/atespaces/ate-demo/actors/" + pluginActorUID + "/snapshots/" + name}, + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + Object: &ateapi.ObjectSnapshot{SnapshotUri: "gs://test-bucket/atespaces/ate-demo/actors/" + pluginActorUID + "/snapshots/" + name}, LocalCommitTime: commit, } } @@ -83,7 +83,7 @@ func TestTrackerReporterSendsState(t *testing.T) { for _, tc := range []struct { name string state *ateletpb.ActorSnapshotState - want *ateapipb.ActorSnapshotState + want *ateapi.ActorSnapshotState }{ { name: "every snapshot", @@ -93,7 +93,7 @@ func TestTrackerReporterSendsState(t *testing.T) { LatestDurable: durable, UploadDueTime: due, }, - want: &ateapipb.ActorSnapshotState{ + want: &ateapi.ActorSnapshotState{ LatestLocal: reported("s3", 3), Uploading: reported("s2", 2), LatestDurable: reportedDurable, @@ -103,7 +103,7 @@ func TestTrackerReporterSendsState(t *testing.T) { { name: "detached", state: &ateletpb.ActorSnapshotState{LatestDurable: durable}, - want: &ateapipb.ActorSnapshotState{LatestDurable: reportedDurable}, + want: &ateapi.ActorSnapshotState{LatestDurable: reportedDurable}, }, } { t.Run(tc.name, func(t *testing.T) { @@ -112,8 +112,8 @@ func TestTrackerReporterSendsState(t *testing.T) { if err := (&trackerReporter{workers: workers}).ReportActorSnapshotState(t.Context(), pluginActorUID, actor, tc.state); err != nil { t.Fatalf("ReportActorSnapshotState: %v", err) } - want := &ateapipb.ReportActorSnapshotStateRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "ate-demo", Name: "counter"}, + want := &ateapi.ReportActorSnapshotStateRequest{ + Actor: &ateapi.ObjectRef{Atespace: "ate-demo", Name: "counter"}, ActorUid: pluginActorUID, State: tc.want, } @@ -146,7 +146,7 @@ func TestToAteAPIFidelity(t *testing.T) { t.Errorf("toAteAPIFidelity(%s) = %s, want the public fidelity of the same name", name, got) } } - if got := toAteAPIFidelity(ateletpb.SnapshotFidelity(99)); got != ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED { + if got := toAteAPIFidelity(ateletpb.SnapshotFidelity(99)); got != ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED { t.Errorf("toAteAPIFidelity(99) = %s, want UNSPECIFIED", got) } } @@ -155,9 +155,9 @@ func TestToAteAPIFidelity(t *testing.T) { // and returns it. The tracker's queues arm their timers from a clock reading // taken just before, so a step that lands in between leaves the timer late; // further steps get past it. -func nextReport(t *testing.T, clk *clocktesting.FakeClock, workers *fakeReportService) *ateapipb.ReportActorSnapshotStateRequest { +func nextReport(t *testing.T, clk *clocktesting.FakeClock, workers *fakeReportService) *ateapi.ReportActorSnapshotStateRequest { t.Helper() - var got *ateapipb.ReportActorSnapshotStateRequest + var got *ateapi.ReportActorSnapshotStateRequest waitFor(t, "a snapshot state report", func() bool { select { case got = <-workers.reports: @@ -193,7 +193,7 @@ func TestBackgroundUploadAndDetachAreReported(t *testing.T) { if _, err := a.checkpoint(t, a.snapshot("pause-snap-1", 1), ateletpb.UploadMode_UPLOAD_MODE_DEFERRED); err != nil { t.Fatalf("Checkpoint: %v", err) } - wantActor := &ateapipb.ObjectRef{Atespace: "ate-demo", Name: "counter"} + wantActor := &ateapi.ObjectRef{Atespace: "ate-demo", Name: "counter"} uploaded := nextReport(t, clk, workers) if !proto.Equal(uploaded.GetActor(), wantActor) || uploaded.GetActorUid() != pluginActorUID { diff --git a/cmd/atelet/volumes_test.go b/cmd/atelet/volumes_test.go index 605a4c8d1d..db09ebb531 100644 --- a/cmd/atelet/volumes_test.go +++ b/cmd/atelet/volumes_test.go @@ -24,11 +24,11 @@ import ( "testing" "github.com/google/go-cmp/cmp" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/atelet/internal/actordirs" "go.ate.dev/substrate/cmd/atelet/internal/ateletpath" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/volume" - "go.ate.dev/substrate/pkg/api/v1alpha1" "go.ate.dev/substrate/pkg/client/clientset/versioned/fake" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -514,11 +514,11 @@ func TestVolumeHostDirectoryCleanup(t *testing.T) { } func TestDirectCSIDriverConfigGetter(t *testing.T) { - fakeClient := fake.NewSimpleClientset(&v1alpha1.CSIDriverConfig{ + fakeClient := fake.NewSimpleClientset(&atev1.CSIDriverConfig{ ObjectMeta: metav1.ObjectMeta{ Name: "test.csi.k8s.io", }, - Spec: v1alpha1.CSIDriverConfigSpec{ + Spec: atev1.CSIDriverConfigSpec{ DriverName: "test.csi.k8s.io", ControllerEndpoint: "tcp://127.0.0.1:9000", }, diff --git a/cmd/atelet/worker_actor_jwt.go b/cmd/atelet/worker_actor_jwt.go index 00b89c49c9..d4290b2063 100644 --- a/cmd/atelet/worker_actor_jwt.go +++ b/cmd/atelet/worker_actor_jwt.go @@ -22,8 +22,8 @@ import ( "google.golang.org/grpc/status" "k8s.io/utils/lru" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/objectstoreplugin/exchange" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // actorRef identifies the actor a transfer is for, as atelet's RPCs carry it. @@ -50,12 +50,12 @@ type cachedWorkerActorJWT struct { // them per actor UID. The node plugin trades one for storage credentials // scoped to the actor, so atelet sends one with every snapshot transfer. type workerActorJWTs struct { - workers ateapipb.WorkerServiceClient + workers ateapi.WorkerServiceClient now func() time.Time cache *lru.Cache } -func newWorkerActorJWTs(workers ateapipb.WorkerServiceClient) *workerActorJWTs { +func newWorkerActorJWTs(workers ateapi.WorkerServiceClient) *workerActorJWTs { return &workerActorJWTs{workers: workers, now: time.Now, cache: lru.New(workerActorJWTCacheSize)} } @@ -75,8 +75,8 @@ func (j *workerActorJWTs) get(ctx context.Context, actor actorRef) (string, erro return c.jwt, nil } } - resp, err := j.workers.MintWorkerActorJwt(ctx, &ateapipb.MintWorkerActorJwtRequest{ - Actor: &ateapipb.ObjectRef{Atespace: actor.atespace, Name: actor.name}, + resp, err := j.workers.MintWorkerActorJwt(ctx, &ateapi.MintWorkerActorJwtRequest{ + Actor: &ateapi.ObjectRef{Atespace: actor.atespace, Name: actor.name}, ActorUid: actor.uid, Audiences: []string{exchange.ActorJWTAudience}, }) diff --git a/cmd/atelet/worker_actor_jwt_test.go b/cmd/atelet/worker_actor_jwt_test.go index c0af8d883e..e646143c03 100644 --- a/cmd/atelet/worker_actor_jwt_test.go +++ b/cmd/atelet/worker_actor_jwt_test.go @@ -25,9 +25,9 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/internal/objectstoreplugin/exchange" - "go.ate.dev/substrate/pkg/proto/ateapipb" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" ) // testActor is the actor the transfer tests act for. @@ -37,23 +37,23 @@ var testActor = actorRef{atespace: "ate-demo", name: "bot", uid: "9f1e0b2a-9e4f- // what it was asked for. A restore fetches its files in parallel, and each // fetch mints while the cache is cold, so the record is locked. type fakeJWTMinter struct { - ateapipb.WorkerServiceClient + ateapi.WorkerServiceClient jwt string expiry time.Time err error mu sync.Mutex - got []*ateapipb.MintWorkerActorJwtRequest + got []*ateapi.MintWorkerActorJwtRequest } -func (m *fakeJWTMinter) MintWorkerActorJwt(_ context.Context, in *ateapipb.MintWorkerActorJwtRequest, _ ...grpc.CallOption) (*ateapipb.MintWorkerActorJwtResponse, error) { +func (m *fakeJWTMinter) MintWorkerActorJwt(_ context.Context, in *ateapi.MintWorkerActorJwtRequest, _ ...grpc.CallOption) (*ateapi.MintWorkerActorJwtResponse, error) { m.mu.Lock() m.got = append(m.got, in) m.mu.Unlock() if m.err != nil { return nil, m.err } - return &ateapipb.MintWorkerActorJwtResponse{ActorJwt: m.jwt, ExpireTime: timestamppb.New(m.expiry)}, nil + return &ateapi.MintWorkerActorJwtResponse{ActorJwt: m.jwt, ExpireTime: timestamppb.New(m.expiry)}, nil } // testWorkerActorJWTs is the JWT source transfer tests give an Atelet. @@ -134,19 +134,19 @@ func TestWorkerActorJWTs_Errors(t *testing.T) { // recordingNodePlugin captures the transfer requests atelet sends. type recordingNodePlugin struct { - objectstorev1.NodeProviderClient - fetches []*objectstorev1.FetchSnapshotRequest - uploads []*objectstorev1.UploadSnapshotRequest + objectstore.NodeProviderClient + fetches []*objectstore.FetchSnapshotRequest + uploads []*objectstore.UploadSnapshotRequest } -func (p *recordingNodePlugin) FetchSnapshot(_ context.Context, in *objectstorev1.FetchSnapshotRequest, _ ...grpc.CallOption) (*objectstorev1.FetchSnapshotResponse, error) { +func (p *recordingNodePlugin) FetchSnapshot(_ context.Context, in *objectstore.FetchSnapshotRequest, _ ...grpc.CallOption) (*objectstore.FetchSnapshotResponse, error) { p.fetches = append(p.fetches, in) - return &objectstorev1.FetchSnapshotResponse{}, nil + return &objectstore.FetchSnapshotResponse{}, nil } -func (p *recordingNodePlugin) UploadSnapshot(_ context.Context, in *objectstorev1.UploadSnapshotRequest, _ ...grpc.CallOption) (*objectstorev1.UploadSnapshotResponse, error) { +func (p *recordingNodePlugin) UploadSnapshot(_ context.Context, in *objectstore.UploadSnapshotRequest, _ ...grpc.CallOption) (*objectstore.UploadSnapshotResponse, error) { p.uploads = append(p.uploads, in) - return &objectstorev1.UploadSnapshotResponse{}, nil + return &objectstore.UploadSnapshotResponse{}, nil } func TestTransfersCarryTheActorJWT(t *testing.T) { diff --git a/cmd/atelet/worker_sandbox_syncer.go b/cmd/atelet/worker_sandbox_syncer.go index 81ff49866f..fb94e04d29 100644 --- a/cmd/atelet/worker_sandbox_syncer.go +++ b/cmd/atelet/worker_sandbox_syncer.go @@ -47,11 +47,11 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/atelet/internal/ateletpath" "go.ate.dev/substrate/internal/hardware" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/api/v1alpha1" - informersv1alpha1 "go.ate.dev/substrate/pkg/client/informers/externalversions/api/v1alpha1" + ateinformers "go.ate.dev/substrate/pkg/client/informers/externalversions/ate/v1" ) // podUIDIndex indexes this node's worker pods by UID, the syncer's queue key. @@ -225,7 +225,7 @@ func (s *workerSandboxSyncer) syncDefaultRuntimeDirs(uid string, defaults []stri // or a list/watch fails (e.g. Forbidden while an RBAC rollout lags the // binary), existing files and index entries stay as they are and only // changes wait. -func startWorkerSandboxSyncer(ctx context.Context, pods coreinformers.PodInformer, workerPools informersv1alpha1.WorkerPoolInformer, configs informersv1alpha1.SandboxConfigInformer, assets sandboxAssetFetcher, workersDir string, index *runtimeIndex, prewarm runtimePrewarm) (*workerSandboxSyncer, error) { +func startWorkerSandboxSyncer(ctx context.Context, pods coreinformers.PodInformer, workerPools ateinformers.WorkerPoolInformer, configs ateinformers.SandboxConfigInformer, assets sandboxAssetFetcher, workersDir string, index *runtimeIndex, prewarm runtimePrewarm) (*workerSandboxSyncer, error) { if err := pods.Informer().AddIndexers(cache.Indexers{podUIDIndex: func(obj any) ([]string, error) { pod, ok := obj.(*corev1.Pod) if !ok { @@ -289,13 +289,13 @@ func (s *workerSandboxSyncer) podHandler() cache.ResourceEventHandler { func (s *workerSandboxSyncer) workerPoolHandler() cache.ResourceEventHandler { return cache.ResourceEventHandlerFuncs{ AddFunc: func(obj any) { - if pool, ok := obj.(*v1alpha1.WorkerPool); ok { + if pool, ok := obj.(*atev1.WorkerPool); ok { s.enqueuePool(pool, 0) } }, UpdateFunc: func(oldObj, newObj any) { - oldPool, oldOK := oldObj.(*v1alpha1.WorkerPool) - newPool, newOK := newObj.(*v1alpha1.WorkerPool) + oldPool, oldOK := oldObj.(*atev1.WorkerPool) + newPool, newOK := newObj.(*atev1.WorkerPool) if oldOK && newOK && oldPool.ResolvedSandboxConfig() != newPool.ResolvedSandboxConfig() { s.enqueuePool(newPool, s.maxJitter) } @@ -306,7 +306,7 @@ func (s *workerSandboxSyncer) workerPoolHandler() cache.ResourceEventHandler { // sandboxConfigHandler enqueues the local pods of every pool that runs the // config, when it appears and when its spec changes. func (s *workerSandboxSyncer) sandboxConfigHandler() cache.ResourceEventHandler { - enqueue := func(cfg *v1alpha1.SandboxConfig) { + enqueue := func(cfg *atev1.SandboxConfig) { pools, err := s.resolver.workerPools.List(labels.Everything()) if err != nil { return @@ -319,13 +319,13 @@ func (s *workerSandboxSyncer) sandboxConfigHandler() cache.ResourceEventHandler } return cache.ResourceEventHandlerFuncs{ AddFunc: func(obj any) { - if cfg, ok := obj.(*v1alpha1.SandboxConfig); ok { + if cfg, ok := obj.(*atev1.SandboxConfig); ok { enqueue(cfg) } }, UpdateFunc: func(oldObj, newObj any) { - oldCfg, oldOK := oldObj.(*v1alpha1.SandboxConfig) - newCfg, newOK := newObj.(*v1alpha1.SandboxConfig) + oldCfg, oldOK := oldObj.(*atev1.SandboxConfig) + newCfg, newOK := newObj.(*atev1.SandboxConfig) // Generation moves on spec changes only. if oldOK && newOK && oldCfg.Generation != newCfg.Generation { enqueue(newCfg) @@ -341,7 +341,7 @@ func (s *workerSandboxSyncer) sandboxConfigHandler() cache.ResourceEventHandler // config's runtimes as soon as the listers do rather than once the files // are rewritten. A request for a runtime the index does not know fails the // actor, and the registration costs no IO. -func (s *workerSandboxSyncer) enqueuePool(pool *v1alpha1.WorkerPool, maxDelay time.Duration) { +func (s *workerSandboxSyncer) enqueuePool(pool *atev1.WorkerPool, maxDelay time.Duration) { pods, err := corelisters.NewPodLister(s.pods).Pods(pool.Namespace).List(labels.SelectorFromSet(labels.Set{workerPoolLabel: pool.Name})) if err != nil || len(pods) == 0 { return @@ -364,7 +364,7 @@ func (s *workerSandboxSyncer) enqueuePool(pool *v1alpha1.WorkerPool, maxDelay ti // is cheap enough for an event handler. Only the hashes are registered; what // a pod advertises changes when its sync writes the file. A pool that does // not plan is left to the syncs, which report and retry it. -func (s *workerSandboxSyncer) registerAhead(pool *v1alpha1.WorkerPool) { +func (s *workerSandboxSyncer) registerAhead(pool *atev1.WorkerPool) { plan, err := s.resolver.planPool(pool) if err != nil { return diff --git a/cmd/atelet/worker_sandbox_syncer_test.go b/cmd/atelet/worker_sandbox_syncer_test.go index d139fd804b..f88a146df0 100644 --- a/cmd/atelet/worker_sandbox_syncer_test.go +++ b/cmd/atelet/worker_sandbox_syncer_test.go @@ -36,11 +36,11 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/sandboxruntimes" - "go.ate.dev/substrate/pkg/api/v1alpha1" atefake "go.ate.dev/substrate/pkg/client/clientset/versioned/fake" "go.ate.dev/substrate/pkg/client/informers/externalversions" - listersv1alpha1 "go.ate.dev/substrate/pkg/client/listers/api/v1alpha1" + atelisters "go.ate.dev/substrate/pkg/client/listers/ate/v1" ) const ( @@ -122,20 +122,20 @@ func workerPod(uid, pool string) *corev1.Pod { // resolvedPool is a gVisor WorkerPool whose class resolved to config, or has // not resolved when config is "". -func resolvedPool(name, config string) *v1alpha1.WorkerPool { - return resolvedPoolOf(v1alpha1.SandboxClassGvisor, name, config) +func resolvedPool(name, config string) *atev1.WorkerPool { + return resolvedPoolOf(atev1.SandboxClassGvisor, name, config) } // resolvedPoolOf is a WorkerPool of the given sandbox class whose class // resolved to config, or has not resolved when config is "". -func resolvedPoolOf(class v1alpha1.SandboxClass, name, config string) *v1alpha1.WorkerPool { - pool := &v1alpha1.WorkerPool{ObjectMeta: metav1.ObjectMeta{Namespace: "workers", Name: name}} - pool.Spec.SandboxClasses = []v1alpha1.WorkerPoolSandboxClass{{Name: class}} - status := v1alpha1.WorkerPoolSandboxClassStatus{Name: class} +func resolvedPoolOf(class atev1.SandboxClass, name, config string) *atev1.WorkerPool { + pool := &atev1.WorkerPool{ObjectMeta: metav1.ObjectMeta{Namespace: "workers", Name: name}} + pool.Spec.SandboxClasses = []atev1.WorkerPoolSandboxClass{{Name: class}} + status := atev1.WorkerPoolSandboxClassStatus{Name: class} if config != "" { - status.ConfigRef = &v1alpha1.SandboxConfigReference{Name: config} + status.ConfigRef = &atev1.SandboxConfigReference{Name: config} } - pool.Status.SandboxClasses = []v1alpha1.WorkerPoolSandboxClassStatus{status} + pool.Status.SandboxClasses = []atev1.WorkerPoolSandboxClassStatus{status} return pool } @@ -158,9 +158,9 @@ func newTestSyncer(t *testing.T, objs ...any) *workerSandboxSyncer { switch obj.(type) { case *corev1.Pod: err = pods.Add(obj) - case *v1alpha1.WorkerPool: + case *atev1.WorkerPool: err = pools.Add(obj) - case *v1alpha1.SandboxConfig: + case *atev1.SandboxConfig: err = configs.Add(obj) default: t.Fatalf("unexpected object %T", obj) @@ -170,8 +170,8 @@ func newTestSyncer(t *testing.T, objs ...any) *workerSandboxSyncer { } } s := newWorkerSandboxSyncer(&workerSandboxResolver{ - workerPools: listersv1alpha1.NewWorkerPoolLister(pools), - configs: listersv1alpha1.NewSandboxConfigLister(configs), + workerPools: atelisters.NewWorkerPoolLister(pools), + configs: atelisters.NewSandboxConfigLister(configs), }, pods, newTestAssetFetcher(), t.TempDir(), newRuntimeIndex(), nil) // The queue starts a goroutine; stop it with the test. t.Cleanup(s.queue.ShutDown) @@ -202,12 +202,12 @@ func TestWorkerSandboxSyncerEvents(t *testing.T) { // one of a same-named pool in another namespace. pods := []any{workerPod("pod-a", "pool"), workerPod("pod-b", "pool"), workerPod("pod-c", "pool-b"), otherNSPod} pools := []any{resolvedPool("pool", "gvisor-release"), resolvedPool("pool-b", "gvisor-other")} - withConfig := func(pool *v1alpha1.WorkerPool, config string) *v1alpha1.WorkerPool { + withConfig := func(pool *atev1.WorkerPool, config string) *atev1.WorkerPool { pool = pool.DeepCopy() - pool.Status.SandboxClasses[0].ConfigRef = &v1alpha1.SandboxConfigReference{Name: config} + pool.Status.SandboxClasses[0].ConfigRef = &atev1.SandboxConfigReference{Name: config} return pool } - withGeneration := func(cfg *v1alpha1.SandboxConfig, gen int64) *v1alpha1.SandboxConfig { + withGeneration := func(cfg *atev1.SandboxConfig, gen int64) *atev1.SandboxConfig { cfg = cfg.DeepCopy() cfg.Generation = gen return cfg @@ -259,7 +259,7 @@ func TestWorkerSandboxSyncerEvents(t *testing.T) { event: func(s *workerSandboxSyncer) { changed := resolvedPool("pool", "gvisor-release") changed.Status.Replicas = 3 - changed.Status.SandboxClasses[0].PendingConfigRef = &v1alpha1.SandboxConfigReference{Name: "gvisor-next"} + changed.Status.SandboxClasses[0].PendingConfigRef = &atev1.SandboxConfigReference{Name: "gvisor-next"} s.workerPoolHandler().OnUpdate(resolvedPool("pool", "gvisor-release"), changed) }, }, { @@ -311,7 +311,7 @@ func TestWorkerSandboxSyncerEvents(t *testing.T) { func TestWorkerSandboxSyncerJitter(t *testing.T) { pods := []any{workerPod("pod-a", "pool"), workerPod("pod-b", "pool")} pool := resolvedPool("pool", "gvisor-release") - withGeneration := func(gen int64) *v1alpha1.SandboxConfig { + withGeneration := func(gen int64) *atev1.SandboxConfig { cfg := multiVersionConfig() cfg.Generation = gen return cfg @@ -849,8 +849,8 @@ func TestStartWorkerSandboxSyncer(t *testing.T) { useTempAssetScratch(t) s, err := startWorkerSandboxSyncer(ctx, podFactory.Core().V1().Pods(), - ateFactory.Api().V1alpha1().WorkerPools(), - ateFactory.Api().V1alpha1().SandboxConfigs(), + ateFactory.Ate().V1().WorkerPools(), + ateFactory.Ate().V1().SandboxConfigs(), newScriptAssetFetcher(t), dir, newRuntimeIndex(), nil) if err != nil { @@ -899,7 +899,7 @@ func TestWorkerSandboxSyncerRunIndexesExistingPods(t *testing.T) { waitFor(t, "pod-live to be indexed", func() bool { _, ok := s.index.worker("pod-live"); return ok }) wr, _ := s.index.worker("pod-live") - cr, ok := wr.class(v1alpha1.SandboxClassGvisor) + cr, ok := wr.class(atev1.SandboxClassGvisor) if !ok || cr.config != "gvisor-release" || cr.defaultHash == "" { t.Errorf("index.worker(pod-live).class(gvisor) = %+v, %v; want gvisor-release with a default runtime", cr, ok) } diff --git a/cmd/atelet/worker_sandbox_versions.go b/cmd/atelet/worker_sandbox_versions.go index cb5e468a34..57ee9d2281 100644 --- a/cmd/atelet/worker_sandbox_versions.go +++ b/cmd/atelet/worker_sandbox_versions.go @@ -44,11 +44,11 @@ import ( corev1 "k8s.io/api/core/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/hardware" "go.ate.dev/substrate/internal/nodepath" "go.ate.dev/substrate/internal/sandboxruntimes" - "go.ate.dev/substrate/pkg/api/v1alpha1" - listersv1alpha1 "go.ate.dev/substrate/pkg/client/listers/api/v1alpha1" + atelisters "go.ate.dev/substrate/pkg/client/listers/ate/v1" ) // errPermanent marks a failure that retrying cannot fix, so the syncer drops @@ -79,8 +79,8 @@ var errUnresolved = errors.New("unresolved sandbox config") // sandboxPlan is what one worker's sandbox runtimes file is built from. type sandboxPlan struct { config string - sandboxClass v1alpha1.SandboxClass // the config's; decides which attributes its runtimes report - versions []versionPlan // the default first + sandboxClass atev1.SandboxClass // the config's; decides which attributes its runtimes report + versions []versionPlan // the default first } // versionPlan is one SandboxConfig version projected onto this node's @@ -95,14 +95,14 @@ type versionPlan struct { // the worker pod's WorkerPool, and the config the atecontroller resolved for // the pool's sandbox class into the pool's status. type workerSandboxResolver struct { - workerPools listersv1alpha1.WorkerPoolLister - configs listersv1alpha1.SandboxConfigLister + workerPools atelisters.WorkerPoolLister + configs atelisters.SandboxConfigLister } // resolve returns the SandboxConfig of a worker pod on this node. Apart from // a pod in no pool, every failure can succeed once an informer catches up or // the atecontroller resolves the pool. -func (r *workerSandboxResolver) resolve(pod *corev1.Pod) (*v1alpha1.SandboxConfig, error) { +func (r *workerSandboxResolver) resolve(pod *corev1.Pod) (*atev1.SandboxConfig, error) { pool, err := r.pool(pod) if err != nil { return nil, err @@ -111,7 +111,7 @@ func (r *workerSandboxResolver) resolve(pod *corev1.Pod) (*v1alpha1.SandboxConfi } // pool returns the WorkerPool a worker pod on this node belongs to. -func (r *workerSandboxResolver) pool(pod *corev1.Pod) (*v1alpha1.WorkerPool, error) { +func (r *workerSandboxResolver) pool(pod *corev1.Pod) (*atev1.WorkerPool, error) { poolName := pod.Labels[workerPoolLabel] if poolName == "" { return nil, fmt.Errorf("%w: worker pod %s/%s has no %s label", errPermanent, pod.Namespace, pod.Name, workerPoolLabel) @@ -124,7 +124,7 @@ func (r *workerSandboxResolver) pool(pod *corev1.Pod) (*v1alpha1.WorkerPool, err } // config returns the SandboxConfig the workers of pool run. -func (r *workerSandboxResolver) config(pool *v1alpha1.WorkerPool) (*v1alpha1.SandboxConfig, error) { +func (r *workerSandboxResolver) config(pool *atev1.WorkerPool) (*atev1.SandboxConfig, error) { configName := pool.ResolvedSandboxConfig() if configName == "" { return nil, fmt.Errorf("%w: WorkerPool %s/%s has not resolved a SandboxConfig for sandbox class %q", errUnresolved, pool.Namespace, pool.Name, pool.Spec.DefaultSandboxClass()) @@ -147,7 +147,7 @@ func (r *workerSandboxResolver) plan(pod *corev1.Pod) (*sandboxPlan, error) { // planPool is plan for a pool already in hand: the config its workers run // and the versions of it this node can run. -func (r *workerSandboxResolver) planPool(pool *v1alpha1.WorkerPool) (*sandboxPlan, error) { +func (r *workerSandboxResolver) planPool(pool *atev1.WorkerPool) (*sandboxPlan, error) { cfg, err := r.config(pool) if err != nil { return nil, err @@ -163,7 +163,7 @@ func (r *workerSandboxResolver) planPool(pool *v1alpha1.WorkerPool) (*sandboxPla // default version first, then the other Enabled versions in spec order. // Versions with no assets for this node's architecture are left out, except // the default, which every worker of the pool must be able to start actors on. -func planVersions(cfg *v1alpha1.SandboxConfig) ([]versionPlan, error) { +func planVersions(cfg *atev1.SandboxConfig) ([]versionPlan, error) { def, ok := cfg.Spec.DefaultVersionConfig() if !ok { // The CRD rejects this shape, so this should not be reachable. @@ -176,7 +176,7 @@ func planVersions(cfg *v1alpha1.SandboxConfig) ([]versionPlan, error) { vers := []versionPlan{{name: def.Name, isDefault: true, rec: defRec}} for i := range cfg.Spec.Versions { v := &cfg.Spec.Versions[i] - if v.Name == def.Name || (v.State != nil && *v.State == v1alpha1.SandboxVersionStateDisabled) { + if v.Name == def.Name || (v.State != nil && *v.State == atev1.SandboxVersionStateDisabled) { continue } if rec, ok := recordForArch(cfg, v); ok { @@ -189,7 +189,7 @@ func planVersions(cfg *v1alpha1.SandboxConfig) ([]versionPlan, error) { // recordForArch projects the assets of one version of a SandboxConfig onto // this node's architecture. It reports false when the version lists no assets // for this architecture. -func recordForArch(cfg *v1alpha1.SandboxConfig, ver *v1alpha1.SandboxVersionConfig) (*sandboxAssetsRecord, bool) { +func recordForArch(cfg *atev1.SandboxConfig, ver *atev1.SandboxVersionConfig) (*sandboxAssetsRecord, bool) { files := ver.Assets[runtime.GOARCH] if len(files) == 0 { return nil, false @@ -282,19 +282,19 @@ func (s *workerSandboxSyncer) buildFile(ctx context.Context, plan *sandboxPlan, // sandbox_bundle_hash is hash: architecture and the hash for every class, // the host CPU identity for a microVM runtime, and the runsc binary's // cpu_features for a gVisor one. -func (s *workerSandboxSyncer) versionAttrs(ctx context.Context, class v1alpha1.SandboxClass, rec *sandboxAssetsRecord, hash string) (sandboxruntimes.Attributes, error) { +func (s *workerSandboxSyncer) versionAttrs(ctx context.Context, class atev1.SandboxClass, rec *sandboxAssetsRecord, hash string) (sandboxruntimes.Attributes, error) { attrs := sandboxruntimes.Attributes{ hardware.AttrArchitecture: runtime.GOARCH, hardware.AttrSandboxBundleHash: hash, } switch class { - case v1alpha1.SandboxClassMicroVM: + case atev1.SandboxClassMicroVM: vendor, model, err := s.hostCPUIdentity() if err != nil { return nil, fmt.Errorf("while probing host CPU identity: %w", err) } attrs[hardware.AttrCPUVendor], attrs[hardware.AttrCPUModel] = vendor, model - case v1alpha1.SandboxClassGvisor: + case atev1.SandboxClassGvisor: mask, err := s.gvisorCPUFeatures(ctx, rec) if err != nil { return nil, err diff --git a/cmd/atelet/worker_sandbox_versions_test.go b/cmd/atelet/worker_sandbox_versions_test.go index abcbf9f3ed..f381b0fc12 100644 --- a/cmd/atelet/worker_sandbox_versions_test.go +++ b/cmd/atelet/worker_sandbox_versions_test.go @@ -32,34 +32,34 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/hardware" "go.ate.dev/substrate/internal/sandboxruntimes" - "go.ate.dev/substrate/pkg/api/v1alpha1" ) // multiVersionConfig is a gVisor config whose default version "v2" is listed // after an Enabled "v1", a Disabled "v0", and an Enabled "other-arch" with no // assets for this node. -func multiVersionConfig() *v1alpha1.SandboxConfig { - version := func(name, sha string, state *v1alpha1.SandboxVersionState) v1alpha1.SandboxVersionConfig { - return v1alpha1.SandboxVersionConfig{ +func multiVersionConfig() *atev1.SandboxConfig { + version := func(name, sha string, state *atev1.SandboxVersionState) atev1.SandboxVersionConfig { + return atev1.SandboxVersionConfig{ Name: name, State: state, - Assets: map[string]map[string]v1alpha1.AssetFile{ + Assets: map[string]map[string]atev1.AssetFile{ runtime.GOARCH: {gvisorAssetName: {URL: "gs://bucket/" + name, SHA256: sha}}, }, } } otherArch := version("other-arch", "sha-other", nil) - otherArch.Assets = map[string]map[string]v1alpha1.AssetFile{"other-arch": otherArch.Assets[runtime.GOARCH]} - return &v1alpha1.SandboxConfig{ + otherArch.Assets = map[string]map[string]atev1.AssetFile{"other-arch": otherArch.Assets[runtime.GOARCH]} + return &atev1.SandboxConfig{ ObjectMeta: metav1.ObjectMeta{Name: "gvisor-release"}, - Spec: v1alpha1.SandboxConfigSpec{ - SandboxClass: v1alpha1.SandboxClassGvisor, + Spec: atev1.SandboxConfigSpec{ + SandboxClass: atev1.SandboxClassGvisor, DefaultVersion: "v2", - Versions: []v1alpha1.SandboxVersionConfig{ - version("v0", "sha-v0", ptr.To(v1alpha1.SandboxVersionStateDisabled)), - version("v1", "sha-v1", ptr.To(v1alpha1.SandboxVersionStateEnabled)), + Versions: []atev1.SandboxVersionConfig{ + version("v0", "sha-v0", ptr.To(atev1.SandboxVersionStateDisabled)), + version("v1", "sha-v1", ptr.To(atev1.SandboxVersionStateEnabled)), otherArch, version("v2", "sha-v2", nil), }, @@ -71,18 +71,18 @@ func TestRecordForArch(t *testing.T) { sha := fmt.Sprintf("%x", sha256.Sum256([]byte("gvisor release"))) tests := []struct { name string - assets map[string]map[string]v1alpha1.AssetFile + assets map[string]map[string]atev1.AssetFile want *sandboxAssetsRecord }{{ name: "assets for this architecture", - assets: map[string]map[string]v1alpha1.AssetFile{runtime.GOARCH: {gvisorAssetName: {URL: "gs://bucket/gvisor", SHA256: sha}}}, + assets: map[string]map[string]atev1.AssetFile{runtime.GOARCH: {gvisorAssetName: {URL: "gs://bucket/gvisor", SHA256: sha}}}, want: &sandboxAssetsRecord{ - SandboxClass: string(v1alpha1.SandboxClassGvisor), + SandboxClass: string(atev1.SandboxClassGvisor), Assets: map[string]assetEntry{gvisorAssetName: {URL: "gs://bucket/gvisor", SHA256: sha}}, }, }, { name: "assets for another architecture only", - assets: map[string]map[string]v1alpha1.AssetFile{"other-arch": {gvisorAssetName: {URL: "gs://bucket/gvisor", SHA256: sha}}}, + assets: map[string]map[string]atev1.AssetFile{"other-arch": {gvisorAssetName: {URL: "gs://bucket/gvisor", SHA256: sha}}}, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -179,9 +179,9 @@ func TestWorkerSandboxResolverResolve(t *testing.T) { // A pending config is one the atecontroller has claimed but not yet // confirmed exists and is not being deleted. name: "pool is only switching to a config", - objs: []any{func() *v1alpha1.WorkerPool { + objs: []any{func() *atev1.WorkerPool { pool := resolvedPool("pool", "") - pool.Status.SandboxClasses[0].PendingConfigRef = &v1alpha1.SandboxConfigReference{Name: "gvisor-default"} + pool.Status.SandboxClasses[0].PendingConfigRef = &atev1.SandboxConfigReference{Name: "gvisor-default"} return pool }(), cfg}, pod: workerPod("pod-a", "pool"), @@ -190,9 +190,9 @@ func TestWorkerSandboxResolverResolve(t *testing.T) { }, { // The class comes from the pool's spec, not from the status entry. name: "status resolved another class than the pool's", - objs: []any{func() *v1alpha1.WorkerPool { + objs: []any{func() *atev1.WorkerPool { pool := resolvedPool("pool", "gvisor-default") - pool.Spec.SandboxClasses[0].Name = v1alpha1.SandboxClassMicroVM + pool.Spec.SandboxClasses[0].Name = atev1.SandboxClassMicroVM return pool }(), cfg}, pod: workerPod("pod-a", "pool"), @@ -245,7 +245,7 @@ func wantRuntimeWithFeatures(name, cpuFeatures string) sandboxruntimes.Attribute // classFile is the file content of a worker in a pool of the given class: // one entry, with the given default and restorable runtimes. -func classFile(class v1alpha1.SandboxClass, def sandboxruntimes.Attributes, restorable ...sandboxruntimes.Attributes) *sandboxruntimes.File { +func classFile(class atev1.SandboxClass, def sandboxruntimes.Attributes, restorable ...sandboxruntimes.Attributes) *sandboxruntimes.File { c := sandboxruntimes.Class{SandboxClass: string(class), DefaultRuntime: sandboxruntimes.Runtime{Version: def}} for _, r := range restorable { c.RestorableRuntimes = append(c.RestorableRuntimes, sandboxruntimes.Runtime{Version: r}) @@ -255,7 +255,7 @@ func classFile(class v1alpha1.SandboxClass, def sandboxruntimes.Attributes, rest // gvisorFile is classFile for a gVisor pool. func gvisorFile(def sandboxruntimes.Attributes, restorable ...sandboxruntimes.Attributes) *sandboxruntimes.File { - return classFile(v1alpha1.SandboxClassGvisor, def, restorable...) + return classFile(atev1.SandboxClassGvisor, def, restorable...) } // wantVersions is the file content for multiVersionConfig. @@ -274,7 +274,7 @@ func planAndBuild(s *workerSandboxSyncer, pod *corev1.Pod) (*sandboxruntimes.Fil func TestPlanAndBuild(t *testing.T) { defaultNoArch := multiVersionConfig() - defaultNoArch.Spec.Versions[3].Assets = map[string]map[string]v1alpha1.AssetFile{"other-arch": defaultNoArch.Spec.Versions[3].Assets[runtime.GOARCH]} + defaultNoArch.Spec.Versions[3].Assets = map[string]map[string]atev1.AssetFile{"other-arch": defaultNoArch.Spec.Versions[3].Assets[runtime.GOARCH]} onlyDefault := gvisorFile(wantRuntime("v2")) @@ -292,13 +292,13 @@ func TestPlanAndBuild(t *testing.T) { unsupportedClass.Spec.SandboxClass = "unknown" noGVisorAsset := multiVersionConfig() - noGVisorAsset.Spec.Versions[3].Assets = map[string]map[string]v1alpha1.AssetFile{ + noGVisorAsset.Spec.Versions[3].Assets = map[string]map[string]atev1.AssetFile{ runtime.GOARCH: {"other": {URL: "gs://bucket/other", SHA256: "sha-other"}}, } tests := []struct { name string - cfg *v1alpha1.SandboxConfig + cfg *atev1.SandboxConfig want *sandboxruntimes.File wantErr bool wantPermanent bool @@ -359,21 +359,21 @@ func TestPlanAndBuild(t *testing.T) { } func TestPlanAndBuildMicroVM(t *testing.T) { - pool := resolvedPoolOf(v1alpha1.SandboxClassMicroVM, "microvm-pool", "microvm-release") - version := func(name, sha string) v1alpha1.SandboxVersionConfig { - return v1alpha1.SandboxVersionConfig{ + pool := resolvedPoolOf(atev1.SandboxClassMicroVM, "microvm-pool", "microvm-release") + version := func(name, sha string) atev1.SandboxVersionConfig { + return atev1.SandboxVersionConfig{ Name: name, - Assets: map[string]map[string]v1alpha1.AssetFile{ + Assets: map[string]map[string]atev1.AssetFile{ runtime.GOARCH: {"kernel": {URL: "gs://bucket/kernel-" + name, SHA256: sha}}, }, } } - cfg := &v1alpha1.SandboxConfig{ + cfg := &atev1.SandboxConfig{ ObjectMeta: metav1.ObjectMeta{Name: "microvm-release"}, - Spec: v1alpha1.SandboxConfigSpec{ - SandboxClass: v1alpha1.SandboxClassMicroVM, + Spec: atev1.SandboxConfigSpec{ + SandboxClass: atev1.SandboxClassMicroVM, DefaultVersion: "v2", - Versions: []v1alpha1.SandboxVersionConfig{ + Versions: []atev1.SandboxVersionConfig{ version("v1", "sha-v1"), version("v2", "sha-v2"), }, @@ -414,7 +414,7 @@ func TestPlanAndBuildMicroVM(t *testing.T) { // Once a probe succeeds, every later sync reuses it. probeErr = nil - want := classFile(v1alpha1.SandboxClassMicroVM, wantMicroVM("sha-v2"), wantMicroVM("sha-v1")) + want := classFile(atev1.SandboxClassMicroVM, wantMicroVM("sha-v2"), wantMicroVM("sha-v1")) for _, uid := range []string{"pod-a", "pod-b"} { got, err := planAndBuild(s, workerPod(uid, "microvm-pool")) if err != nil { @@ -438,7 +438,7 @@ func TestGVisorCPUFeaturesMemoizationAndErrors(t *testing.T) { cfg := multiVersionConfig() v3 := *cfg.Spec.Versions[1].DeepCopy() v3.Name = "v3" - v3.Assets[runtime.GOARCH][gvisorAssetName] = v1alpha1.AssetFile{URL: "gs://other-bucket/v1", SHA256: "sha-v1"} + v3.Assets[runtime.GOARCH][gvisorAssetName] = atev1.AssetFile{URL: "gs://other-bucket/v1", SHA256: "sha-v1"} cfg.Spec.Versions = append(cfg.Spec.Versions, v3) s := newTestSyncer(t, resolvedPool("pool", "gvisor-release"), cfg) @@ -466,7 +466,7 @@ func TestGVisorCPUFeaturesMemoizationAndErrors(t *testing.T) { // uses the same runsc binary. v3 := *cfg.Spec.Versions[1].DeepCopy() v3.Name = "v3" - v3.Assets[runtime.GOARCH]["extra"] = v1alpha1.AssetFile{URL: "gs://bucket/extra", SHA256: "sha-extra"} + v3.Assets[runtime.GOARCH]["extra"] = atev1.AssetFile{URL: "gs://bucket/extra", SHA256: "sha-extra"} cfg.Spec.Versions = append(cfg.Spec.Versions, v3) s := newTestSyncer(t, resolvedPool("pool", "gvisor-release"), cfg) @@ -652,7 +652,7 @@ func TestSyncPodAdvertisesWhatItWrote(t *testing.T) { if !ok { t.Fatal("pod-a has no index entry") } - cr, ok := wr.class(v1alpha1.SandboxClassGvisor) + cr, ok := wr.class(atev1.SandboxClassGvisor) if !ok { t.Fatal("pod-a advertises nothing for gvisor") } diff --git a/cmd/atelet/workersupport.go b/cmd/atelet/workersupport.go index e852af7dd7..44fd8dab52 100644 --- a/cmd/atelet/workersupport.go +++ b/cmd/atelet/workersupport.go @@ -20,11 +20,11 @@ import ( "fmt" "log/slog" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/atelet/internal/apivalidation" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/substratex509" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/peer" @@ -33,8 +33,8 @@ import ( type workerSupportServer struct { ateletpb.UnimplementedWorkerSupportServer - workers ateapipb.WorkerServiceClient - control ateapipb.ControlClient + workers ateapi.WorkerServiceClient + control ateapi.ControlClient } func (b *workerSupportServer) MintActorCertificate(ctx context.Context, req *ateletpb.MintActorCertificateRequest) (*ateletpb.MintActorCertificateResponse, error) { @@ -52,10 +52,10 @@ func (b *workerSupportServer) MintActorCertificate(ctx context.Context, req *ate return nil, resources.ToGRPCStatusError(errs) } - resp, err := b.workers.MintWorkerActorCertificate(ctx, &ateapipb.MintWorkerActorCertificateRequest{ + resp, err := b.workers.MintWorkerActorCertificate(ctx, &ateapi.MintWorkerActorCertificateRequest{ // Workers are global-scoped and named by their pod UID. - Worker: &ateapipb.ObjectRef{Name: workerIdentity.PodUID}, - Actor: &ateapipb.ObjectRef{ + Worker: &ateapi.ObjectRef{Name: workerIdentity.PodUID}, + Actor: &ateapi.ObjectRef{ Atespace: req.GetActorAtespace(), Name: req.GetActorName(), }, @@ -116,9 +116,9 @@ func (s *workerSupportServer) AcquireWorkerEpoch(ctx context.Context, _ *ateletp if err != nil { return nil, err } - resp, err := s.workers.AcquireWorkerEpoch(ctx, &ateapipb.AcquireWorkerEpochRequest{ + resp, err := s.workers.AcquireWorkerEpoch(ctx, &ateapi.AcquireWorkerEpochRequest{ // Workers are global-scoped and named by their pod UID. - Worker: &ateapipb.ObjectRef{Name: workerIdentity.PodUID}, + Worker: &ateapi.ObjectRef{Name: workerIdentity.PodUID}, }) if err != nil { return nil, err @@ -142,9 +142,9 @@ func (s *workerSupportServer) RegisterWorker(ctx context.Context, req *ateletpb. if errs := apivalidation.ValidateRegisterWorkerRequest(ctx, req); len(errs) > 0 { return nil, resources.ToGRPCStatusError(errs) } - if _, err := s.workers.RegisterWorker(ctx, &ateapipb.RegisterWorkerRequest{ + if _, err := s.workers.RegisterWorker(ctx, &ateapi.RegisterWorkerRequest{ // Workers are global-scoped and named by their pod UID. - Worker: &ateapipb.ObjectRef{Name: workerIdentity.PodUID}, + Worker: &ateapi.ObjectRef{Name: workerIdentity.PodUID}, Epoch: req.GetEpoch(), Ips: req.GetIps(), Capacity: toWorkerResources(req.GetCapacity()), @@ -171,8 +171,8 @@ func (s *workerSupportServer) SetWorkerSandboxRuntimes(ctx context.Context, req if errs := apivalidation.ValidateSetWorkerSandboxRuntimesRequest(ctx, req); len(errs) > 0 { return nil, resources.ToGRPCStatusError(errs) } - if _, err := s.workers.SetWorkerSandboxRuntimes(ctx, &ateapipb.SetWorkerSandboxRuntimesRequest{ - Worker: &ateapipb.ObjectRef{Name: workerIdentity.PodUID}, + if _, err := s.workers.SetWorkerSandboxRuntimes(ctx, &ateapi.SetWorkerSandboxRuntimesRequest{ + Worker: &ateapi.ObjectRef{Name: workerIdentity.PodUID}, Epoch: req.GetEpoch(), SandboxClasses: toAteAPISandboxClasses(req.GetSandboxClasses()), }); err != nil { @@ -187,11 +187,11 @@ func (s *workerSupportServer) SetWorkerSandboxRuntimes(ctx context.Context, req // toWorkerResources converts atelet's WorkerResources to the control plane's, // which it mirrors field for field. -func toWorkerResources(in *ateletpb.WorkerResources) *ateapipb.WorkerResources { +func toWorkerResources(in *ateletpb.WorkerResources) *ateapi.WorkerResources { if in == nil { return nil } - return &ateapipb.WorkerResources{ + return &ateapi.WorkerResources{ CpuMillicores: in.GetCpuMillicores(), MemoryBytes: in.GetMemoryBytes(), Actors: in.GetActors(), @@ -200,13 +200,13 @@ func toWorkerResources(in *ateletpb.WorkerResources) *ateapipb.WorkerResources { // toAteAPISandboxClasses converts atelet's WorkerSandboxClass list to the // control plane's, which it mirrors field for field. -func toAteAPISandboxClasses(in []*ateletpb.WorkerSandboxClass) []*ateapipb.WorkerSandboxClass { +func toAteAPISandboxClasses(in []*ateletpb.WorkerSandboxClass) []*ateapi.WorkerSandboxClass { if in == nil { return nil } - out := make([]*ateapipb.WorkerSandboxClass, 0, len(in)) + out := make([]*ateapi.WorkerSandboxClass, 0, len(in)) for _, c := range in { - out = append(out, &ateapipb.WorkerSandboxClass{ + out = append(out, &ateapi.WorkerSandboxClass{ SandboxClass: c.GetSandboxClass(), DefaultRuntime: toAteAPISandboxRuntime(c.GetDefaultRuntime()), RestorableRuntimes: toAteAPISandboxRuntimes(c.GetRestorableRuntimes()), @@ -217,18 +217,18 @@ func toAteAPISandboxClasses(in []*ateletpb.WorkerSandboxClass) []*ateapipb.Worke // toAteAPISandboxRuntime converts atelet's WorkerSandboxRuntime to the control // plane's, which it mirrors field for field. -func toAteAPISandboxRuntime(in *ateletpb.WorkerSandboxRuntime) *ateapipb.WorkerSandboxRuntime { +func toAteAPISandboxRuntime(in *ateletpb.WorkerSandboxRuntime) *ateapi.WorkerSandboxRuntime { if in == nil { return nil } - return &ateapipb.WorkerSandboxRuntime{Version: toAteAPICompat(in.GetVersion())} + return &ateapi.WorkerSandboxRuntime{Version: toAteAPICompat(in.GetVersion())} } -func toAteAPISandboxRuntimes(in []*ateletpb.WorkerSandboxRuntime) []*ateapipb.WorkerSandboxRuntime { +func toAteAPISandboxRuntimes(in []*ateletpb.WorkerSandboxRuntime) []*ateapi.WorkerSandboxRuntime { if in == nil { return nil } - out := make([]*ateapipb.WorkerSandboxRuntime, 0, len(in)) + out := make([]*ateapi.WorkerSandboxRuntime, 0, len(in)) for _, rt := range in { out = append(out, toAteAPISandboxRuntime(rt)) } @@ -237,13 +237,13 @@ func toAteAPISandboxRuntimes(in []*ateletpb.WorkerSandboxRuntime) []*ateapipb.Wo // toAteAPICompat converts atelet's VersionedSandboxCompat to the control // plane's, which it mirrors field for field. -func toAteAPICompat(in *ateletpb.VersionedSandboxCompat) *ateapipb.VersionedSandboxCompat { +func toAteAPICompat(in *ateletpb.VersionedSandboxCompat) *ateapi.VersionedSandboxCompat { if in == nil { return nil } - out := &ateapipb.VersionedSandboxCompat{SchemaVersion: in.GetSchemaVersion()} + out := &ateapi.VersionedSandboxCompat{SchemaVersion: in.GetSchemaVersion()} for _, a := range in.GetAttributes() { - out.Attributes = append(out.Attributes, &ateapipb.AttributeEntry{Key: a.GetKey(), Value: a.GetValue()}) + out.Attributes = append(out.Attributes, &ateapi.AttributeEntry{Key: a.GetKey(), Value: a.GetValue()}) } return out } @@ -271,10 +271,10 @@ func (s *workerSupportServer) RequestActorSuspend(ctx context.Context, req *atel if errs := apivalidation.ValidateRequestActorSuspendRequest(ctx, req); len(errs) > 0 { return nil, resources.ToGRPCStatusError(errs) } - if _, err := s.workers.RequestActorSuspend(ctx, &ateapipb.RequestActorSuspendRequest{ + if _, err := s.workers.RequestActorSuspend(ctx, &ateapi.RequestActorSuspendRequest{ // Workers are global-scoped and named by their pod UID. - Worker: &ateapipb.ObjectRef{Name: workerIdentity.PodUID}, - Actor: &ateapipb.ObjectRef{ + Worker: &ateapi.ObjectRef{Name: workerIdentity.PodUID}, + Actor: &ateapi.ObjectRef{ Atespace: req.GetActorAtespace(), Name: req.GetActorName(), }, @@ -306,8 +306,8 @@ func (s *workerSupportServer) GetActorEgressPolicy( // TODO(bowei): add validation for which Actor requested this. - policy, err := s.control.GetActorEgressPolicy(ctx, &ateapipb.GetActorEgressPolicyRequest{ - Actor: &ateapipb.ObjectRef{ + policy, err := s.control.GetActorEgressPolicy(ctx, &ateapi.GetActorEgressPolicyRequest{ + Actor: &ateapi.ObjectRef{ Atespace: req.GetActorAtespace(), Name: req.GetActorName(), }, @@ -345,9 +345,9 @@ func (s *workerSupportServer) ReportActorCrashed(ctx context.Context, req *atele if errs := apivalidation.ValidateReportActorCrashedRequest(ctx, req); len(errs) > 0 { return nil, resources.ToGRPCStatusError(errs) } - if _, err := s.workers.ReportActorCrashed(ctx, &ateapipb.ReportActorCrashedRequest{ - Worker: &ateapipb.ObjectRef{Name: workerIdentity.PodUID}, - Actor: &ateapipb.ObjectRef{ + if _, err := s.workers.ReportActorCrashed(ctx, &ateapi.ReportActorCrashedRequest{ + Worker: &ateapi.ObjectRef{Name: workerIdentity.PodUID}, + Actor: &ateapi.ObjectRef{ Atespace: req.GetActorAtespace(), Name: req.GetActorName(), }, diff --git a/cmd/atelet/workersupport_test.go b/cmd/atelet/workersupport_test.go index 7913ae973b..73d2c42972 100644 --- a/cmd/atelet/workersupport_test.go +++ b/cmd/atelet/workersupport_test.go @@ -26,10 +26,10 @@ import ( "time" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/substratex509" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -86,42 +86,42 @@ func workerCertificate(t *testing.T, podUID, nodeName string) *x509.Certificate // // https://google.github.io/styleguide/go/best-practices.html#use-real-transports type fakeWorkerService struct { - ateapipb.WorkerServiceClient + ateapi.WorkerServiceClient - got []*ateapipb.RegisterWorkerRequest - acquireGot []*ateapipb.AcquireWorkerEpochRequest - runtimesGot []*ateapipb.SetWorkerSandboxRuntimesRequest + got []*ateapi.RegisterWorkerRequest + acquireGot []*ateapi.AcquireWorkerEpochRequest + runtimesGot []*ateapi.SetWorkerSandboxRuntimesRequest epoch int64 - mintGot []*ateapipb.MintWorkerActorCertificateRequest - mintResp *ateapipb.MintWorkerActorCertificateResponse + mintGot []*ateapi.MintWorkerActorCertificateRequest + mintResp *ateapi.MintWorkerActorCertificateResponse err error } -func (s *fakeWorkerService) AcquireWorkerEpoch(_ context.Context, in *ateapipb.AcquireWorkerEpochRequest, _ ...grpc.CallOption) (*ateapipb.AcquireWorkerEpochResponse, error) { +func (s *fakeWorkerService) AcquireWorkerEpoch(_ context.Context, in *ateapi.AcquireWorkerEpochRequest, _ ...grpc.CallOption) (*ateapi.AcquireWorkerEpochResponse, error) { if s.err != nil { return nil, s.err } s.acquireGot = append(s.acquireGot, in) - return &ateapipb.AcquireWorkerEpochResponse{Epoch: s.epoch}, nil + return &ateapi.AcquireWorkerEpochResponse{Epoch: s.epoch}, nil } -func (s *fakeWorkerService) RegisterWorker(_ context.Context, in *ateapipb.RegisterWorkerRequest, _ ...grpc.CallOption) (*ateapipb.RegisterWorkerResponse, error) { +func (s *fakeWorkerService) RegisterWorker(_ context.Context, in *ateapi.RegisterWorkerRequest, _ ...grpc.CallOption) (*ateapi.RegisterWorkerResponse, error) { if s.err != nil { return nil, s.err } s.got = append(s.got, in) - return &ateapipb.RegisterWorkerResponse{}, nil + return &ateapi.RegisterWorkerResponse{}, nil } -func (s *fakeWorkerService) SetWorkerSandboxRuntimes(_ context.Context, in *ateapipb.SetWorkerSandboxRuntimesRequest, _ ...grpc.CallOption) (*ateapipb.SetWorkerSandboxRuntimesResponse, error) { +func (s *fakeWorkerService) SetWorkerSandboxRuntimes(_ context.Context, in *ateapi.SetWorkerSandboxRuntimesRequest, _ ...grpc.CallOption) (*ateapi.SetWorkerSandboxRuntimesResponse, error) { if s.err != nil { return nil, s.err } s.runtimesGot = append(s.runtimesGot, in) - return &ateapipb.SetWorkerSandboxRuntimesResponse{}, nil + return &ateapi.SetWorkerSandboxRuntimesResponse{}, nil } -func (s *fakeWorkerService) MintWorkerActorCertificate(_ context.Context, in *ateapipb.MintWorkerActorCertificateRequest, _ ...grpc.CallOption) (*ateapipb.MintWorkerActorCertificateResponse, error) { +func (s *fakeWorkerService) MintWorkerActorCertificate(_ context.Context, in *ateapi.MintWorkerActorCertificateRequest, _ ...grpc.CallOption) (*ateapi.MintWorkerActorCertificateResponse, error) { if s.err != nil { return nil, s.err } @@ -129,7 +129,7 @@ func (s *fakeWorkerService) MintWorkerActorCertificate(_ context.Context, in *at if s.mintResp != nil { return s.mintResp, nil } - return &ateapipb.MintWorkerActorCertificateResponse{}, nil + return &ateapi.MintWorkerActorCertificateResponse{}, nil } func TestAcquireWorkerEpoch(t *testing.T) { @@ -139,12 +139,12 @@ func TestAcquireWorkerEpoch(t *testing.T) { serviceErr error wantCode codes.Code wantEpoch int64 - wantForwarded []*ateapipb.AcquireWorkerEpochRequest + wantForwarded []*ateapi.AcquireWorkerEpochRequest }{{ // The Worker is named after the worker pod UID from the certificate. name: "acquires for the calling worker", wantEpoch: 7, - wantForwarded: []*ateapipb.AcquireWorkerEpochRequest{{Worker: &ateapipb.ObjectRef{Name: "pod-a"}}}, + wantForwarded: []*ateapi.AcquireWorkerEpochRequest{{Worker: &ateapi.ObjectRef{Name: "pod-a"}}}, }, { name: "requires a certificate", unauthenticated: true, @@ -179,12 +179,12 @@ func TestAcquireWorkerEpoch(t *testing.T) { func TestRegisterWorker(t *testing.T) { ips := []string{"10.0.0.1"} - forwarded := func(capacity *ateapipb.WorkerResources) []*ateapipb.RegisterWorkerRequest { + forwarded := func(capacity *ateapi.WorkerResources) []*ateapi.RegisterWorkerRequest { // The Worker is named after the worker pod UID, taken from the // certificate rather than the request; epoch, IPs and capacity come // from what the worker reported. - return []*ateapipb.RegisterWorkerRequest{{ - Worker: &ateapipb.ObjectRef{Name: "pod-a"}, + return []*ateapi.RegisterWorkerRequest{{ + Worker: &ateapi.ObjectRef{Name: "pod-a"}, Epoch: 3, Ips: ips, Capacity: capacity, @@ -199,7 +199,7 @@ func TestRegisterWorker(t *testing.T) { serviceErr error req *ateletpb.RegisterWorkerRequest wantCode codes.Code - wantForwarded []*ateapipb.RegisterWorkerRequest + wantForwarded []*ateapi.RegisterWorkerRequest }{{ name: "records what the worker says", req: &ateletpb.RegisterWorkerRequest{ @@ -207,15 +207,15 @@ func TestRegisterWorker(t *testing.T) { Ips: ips, Capacity: &ateletpb.WorkerResources{Actors: 4, CpuMillicores: 2000, MemoryBytes: 4 << 30}, }, - wantForwarded: forwarded(&ateapipb.WorkerResources{Actors: 4, CpuMillicores: 2000, MemoryBytes: 4294967296}), + wantForwarded: forwarded(&ateapi.WorkerResources{Actors: 4, CpuMillicores: 2000, MemoryBytes: 4294967296}), }, { name: "omits undetermined compute", req: &ateletpb.RegisterWorkerRequest{Epoch: 3, Ips: ips, Capacity: &ateletpb.WorkerResources{Actors: 1}}, - wantForwarded: forwarded(&ateapipb.WorkerResources{Actors: 1}), + wantForwarded: forwarded(&ateapi.WorkerResources{Actors: 1}), }, { name: "forwards empty capacity", req: &ateletpb.RegisterWorkerRequest{Epoch: 3, Ips: ips, Capacity: &ateletpb.WorkerResources{}}, - wantForwarded: forwarded(&ateapipb.WorkerResources{}), + wantForwarded: forwarded(&ateapi.WorkerResources{}), }, { name: "rejects invalid capacity without forwarding", req: &ateletpb.RegisterWorkerRequest{ @@ -272,10 +272,10 @@ func TestSetWorkerSandboxRuntimes(t *testing.T) { }, } } - wantCompat := func(hash string) *ateapipb.VersionedSandboxCompat { - return &ateapipb.VersionedSandboxCompat{ + wantCompat := func(hash string) *ateapi.VersionedSandboxCompat { + return &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{ + Attributes: []*ateapi.AttributeEntry{ {Key: "architecture", Value: "amd64"}, {Key: "sandbox_bundle_hash", Value: hash}, }, @@ -294,21 +294,21 @@ func TestSetWorkerSandboxRuntimes(t *testing.T) { } return []*ateletpb.WorkerSandboxClass{c} } - forwarded := func(restorable ...*ateapipb.VersionedSandboxCompat) []*ateapipb.SetWorkerSandboxRuntimesRequest { + forwarded := func(restorable ...*ateapi.VersionedSandboxCompat) []*ateapi.SetWorkerSandboxRuntimesRequest { // The Worker is named after the worker pod UID, taken from the // certificate rather than the request; epoch and sandbox classes come // from what the worker reported. - c := &ateapipb.WorkerSandboxClass{ + c := &ateapi.WorkerSandboxClass{ SandboxClass: "gvisor", - DefaultRuntime: &ateapipb.WorkerSandboxRuntime{Version: wantDefault}, + DefaultRuntime: &ateapi.WorkerSandboxRuntime{Version: wantDefault}, } for _, r := range restorable { - c.RestorableRuntimes = append(c.RestorableRuntimes, &ateapipb.WorkerSandboxRuntime{Version: r}) + c.RestorableRuntimes = append(c.RestorableRuntimes, &ateapi.WorkerSandboxRuntime{Version: r}) } - return []*ateapipb.SetWorkerSandboxRuntimesRequest{{ - Worker: &ateapipb.ObjectRef{Name: "pod-a"}, + return []*ateapi.SetWorkerSandboxRuntimesRequest{{ + Worker: &ateapi.ObjectRef{Name: "pod-a"}, Epoch: 3, - SandboxClasses: []*ateapipb.WorkerSandboxClass{c}, + SandboxClasses: []*ateapi.WorkerSandboxClass{c}, }} } @@ -320,7 +320,7 @@ func TestSetWorkerSandboxRuntimes(t *testing.T) { serviceErr error req *ateletpb.SetWorkerSandboxRuntimesRequest wantCode codes.Code - wantForwarded []*ateapipb.SetWorkerSandboxRuntimesRequest + wantForwarded []*ateapi.SetWorkerSandboxRuntimesRequest }{{ name: "records what the worker says", req: &ateletpb.SetWorkerSandboxRuntimesRequest{Epoch: 3, SandboxClasses: reqClasses()}, @@ -391,27 +391,27 @@ func TestSetWorkerSandboxRuntimes(t *testing.T) { } type fakeSuspendService struct { - ateapipb.WorkerServiceClient + ateapi.WorkerServiceClient - got []*ateapipb.RequestActorSuspendRequest - gotCrashed []*ateapipb.ReportActorCrashedRequest + got []*ateapi.RequestActorSuspendRequest + gotCrashed []*ateapi.ReportActorCrashedRequest err error } -func (s *fakeSuspendService) ReportActorCrashed(_ context.Context, in *ateapipb.ReportActorCrashedRequest, _ ...grpc.CallOption) (*ateapipb.ReportActorCrashedResponse, error) { +func (s *fakeSuspendService) ReportActorCrashed(_ context.Context, in *ateapi.ReportActorCrashedRequest, _ ...grpc.CallOption) (*ateapi.ReportActorCrashedResponse, error) { if s.err != nil { return nil, s.err } s.gotCrashed = append(s.gotCrashed, in) - return &ateapipb.ReportActorCrashedResponse{}, nil + return &ateapi.ReportActorCrashedResponse{}, nil } -func (s *fakeSuspendService) RequestActorSuspend(_ context.Context, in *ateapipb.RequestActorSuspendRequest, _ ...grpc.CallOption) (*ateapipb.RequestActorSuspendResponse, error) { +func (s *fakeSuspendService) RequestActorSuspend(_ context.Context, in *ateapi.RequestActorSuspendRequest, _ ...grpc.CallOption) (*ateapi.RequestActorSuspendResponse, error) { if s.err != nil { return nil, s.err } s.got = append(s.got, in) - return &ateapipb.RequestActorSuspendResponse{}, nil + return &ateapi.RequestActorSuspendResponse{}, nil } func TestRequestActorSuspendNamesTheCallingWorker(t *testing.T) { @@ -427,12 +427,12 @@ func TestRequestActorSuspendNamesTheCallingWorker(t *testing.T) { t.Fatalf("RequestActorSuspend() failed: %v", err) } - want := []*ateapipb.RequestActorSuspendRequest{{ + want := []*ateapi.RequestActorSuspendRequest{{ // The Worker is named after the worker pod UID, taken from the // certificate rather than the request: a worker may speak for the // actors it hosts, and only the control plane knows which those are. - Worker: &ateapipb.ObjectRef{Name: "pod-a"}, - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "actor-1"}, + Worker: &ateapi.ObjectRef{Name: "pod-a"}, + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "actor-1"}, ActorUid: "01234567-89ab-cdef-0123-456789abcdef", }} if diff := cmp.Diff(want, workers.got, protocmp.Transform()); diff != "" { @@ -477,7 +477,7 @@ func TestRequestActorSuspendSurfacesRefusal(t *testing.T) { func TestMintActorCertificateForwardsToWorkerService(t *testing.T) { wantCerts := [][]byte{[]byte("cert-der-bytes")} workers := &fakeWorkerService{ - mintResp: &ateapipb.MintWorkerActorCertificateResponse{ + mintResp: &ateapi.MintWorkerActorCertificateResponse{ ActorCertificates: wantCerts, }, } @@ -494,10 +494,10 @@ func TestMintActorCertificateForwardsToWorkerService(t *testing.T) { t.Fatalf("MintActorCertificate() failed: %v", err) } - want := []*ateapipb.MintWorkerActorCertificateRequest{{ + want := []*ateapi.MintWorkerActorCertificateRequest{{ // The worker comes from the caller's certificate. - Worker: &ateapipb.ObjectRef{Name: "pod-a"}, - Actor: &ateapipb.ObjectRef{ + Worker: &ateapi.ObjectRef{Name: "pod-a"}, + Actor: &ateapi.ObjectRef{ Atespace: "team-a", Name: "actor-1", }, @@ -531,14 +531,14 @@ func TestMintActorCertificateRequiresCertificate(t *testing.T) { } type fakeEgressPolicyControl struct { - ateapipb.ControlClient + ateapi.ControlClient - got []*ateapipb.GetActorEgressPolicyRequest - resp *ateapipb.EgressPolicy + got []*ateapi.GetActorEgressPolicyRequest + resp *ateapi.EgressPolicy err error } -func (c *fakeEgressPolicyControl) GetActorEgressPolicy(_ context.Context, in *ateapipb.GetActorEgressPolicyRequest, _ ...grpc.CallOption) (*ateapipb.EgressPolicy, error) { +func (c *fakeEgressPolicyControl) GetActorEgressPolicy(_ context.Context, in *ateapi.GetActorEgressPolicyRequest, _ ...grpc.CallOption) (*ateapi.EgressPolicy, error) { c.got = append(c.got, in) if c.err != nil { return nil, c.err @@ -547,11 +547,11 @@ func (c *fakeEgressPolicyControl) GetActorEgressPolicy(_ context.Context, in *at } func TestGetActorEgressPolicy(t *testing.T) { - policy := &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "default"}, - Rules: []*ateapipb.EgressRule{{Http: &ateapipb.HttpRule{ + policy := &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "default"}, + Rules: []*ateapi.EgressRule{{Http: &ateapi.HttpRule{ Hostnames: []string{"api.example.com"}, - Ports: &ateapipb.Ports{Numbers: []int32{80}}, + Ports: &ateapi.Ports{Numbers: []int32{80}}, }}}, } // The copy toAteletEgressPolicy makes; TestToAteletEgressPolicy covers it. @@ -560,8 +560,8 @@ func TestGetActorEgressPolicy(t *testing.T) { Ports: &ateletpb.EgressPorts{Numbers: []int32{80}}, }}}} req := &ateletpb.GetActorEgressPolicyRequest{ActorAtespace: "team-a", ActorName: "actor-1"} - forwarded := []*ateapipb.GetActorEgressPolicyRequest{{ - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "actor-1"}, + forwarded := []*ateapi.GetActorEgressPolicyRequest{{ + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "actor-1"}, Name: resources.SingletonName, }} @@ -571,10 +571,10 @@ func TestGetActorEgressPolicy(t *testing.T) { unauthenticated bool req *ateletpb.GetActorEgressPolicyRequest // resp and serviceErr are what the control plane answers with. - resp *ateapipb.EgressPolicy + resp *ateapi.EgressPolicy serviceErr error wantCode codes.Code - wantForwarded []*ateapipb.GetActorEgressPolicyRequest + wantForwarded []*ateapi.GetActorEgressPolicyRequest // wantPolicy is the policy the worker gets back; nil means unset. wantPolicy *ateletpb.EgressPolicy }{{ @@ -647,9 +647,9 @@ func TestReportActorCrashedNamesTheCallingWorker(t *testing.T) { }); err != nil { t.Fatalf("ReportActorCrashed() failed: %v", err) } - want := []*ateapipb.ReportActorCrashedRequest{{ - Worker: &ateapipb.ObjectRef{Name: "pod-a"}, - Actor: &ateapipb.ObjectRef{Atespace: "team-a", Name: "actor-1"}, + want := []*ateapi.ReportActorCrashedRequest{{ + Worker: &ateapi.ObjectRef{Name: "pod-a"}, + Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "actor-1"}, ActorUid: "01234567-89ab-cdef-0123-456789abcdef", Message: "cloud-hypervisor exited", }} diff --git a/cmd/atenet/internal/router/egress/actorjwt/actorjwt.go b/cmd/atenet/internal/router/egress/actorjwt/actorjwt.go index 6ac39429ea..d2d5e42856 100644 --- a/cmd/atenet/internal/router/egress/actorjwt/actorjwt.go +++ b/cmd/atenet/internal/router/egress/actorjwt/actorjwt.go @@ -25,15 +25,15 @@ import ( "google.golang.org/protobuf/proto" "k8s.io/apimachinery/pkg/util/cache" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // Minter mints actor JWTs and reuses each token until a third of its lifetime // remains. Tokens are cached by actor name, so an actor recreated under the // same name can get its predecessor's token until then. type Minter struct { - client ateapipb.ControlClient + client ateapi.ControlClient // tokens maps a tokenKey to a JWT until the token's refresh point. tokens *cache.Expiring // flight collapses concurrent mints of one token into a single call. @@ -41,14 +41,14 @@ type Minter struct { } // New returns a Minter that mints through client. -func New(client ateapipb.ControlClient) *Minter { +func New(client ateapi.ControlClient) *Minter { return &Minter{client: client, tokens: cache.NewExpiring()} } // Token returns a JWT for the actor ref names, bound to src's audiences and // lifetime. MintActorJwt errors are returned wrapped. -func (m *Minter) Token(ctx context.Context, ref resources.ActorRef, src *ateapipb.ActorJwtSource) (string, error) { - req := &ateapipb.MintActorJwtRequest{ +func (m *Minter) Token(ctx context.Context, ref resources.ActorRef, src *ateapi.ActorJwtSource) (string, error) { + req := &ateapi.MintActorJwtRequest{ Actor: ref.ToObjectRef(), Audiences: slices.Sorted(slices.Values(src.GetAudiences())), ExpirationSeconds: src.GetExpirationSeconds(), @@ -80,7 +80,7 @@ func (m *Minter) Token(ctx context.Context, ref resources.ActorRef, src *ateapip // mint sends req and caches the token under key, unless a flight that just // finished has already stored one. -func (m *Minter) mint(ctx context.Context, key string, ref resources.ActorRef, req *ateapipb.MintActorJwtRequest) (string, error) { +func (m *Minter) mint(ctx context.Context, key string, ref resources.ActorRef, req *ateapi.MintActorJwtRequest) (string, error) { if jwt, ok := m.cached(key); ok { return jwt, nil } @@ -101,7 +101,7 @@ func (m *Minter) cached(key string) (string, bool) { // tokenKey identifies the token req mints by req's own encoding. Deterministic // encoding is stable within one binary, which is all an in-process cache needs. -func tokenKey(req *ateapipb.MintActorJwtRequest) (string, error) { +func tokenKey(req *ateapi.MintActorJwtRequest) (string, error) { b, err := proto.MarshalOptions{Deterministic: true}.Marshal(req) if err != nil { return "", fmt.Errorf("encoding the token key: %w", err) diff --git a/cmd/atenet/internal/router/egress/actorjwt/actorjwt_test.go b/cmd/atenet/internal/router/egress/actorjwt/actorjwt_test.go index 07a8a49f08..892c4198be 100644 --- a/cmd/atenet/internal/router/egress/actorjwt/actorjwt_test.go +++ b/cmd/atenet/internal/router/egress/actorjwt/actorjwt_test.go @@ -33,8 +33,8 @@ import ( "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) var testActor = resources.ActorRef{Atespace: "default", Name: "my-actor"} @@ -43,14 +43,14 @@ var testActor = resources.ActorRef{Atespace: "default", Name: "my-actor"} // expiration_seconds from now. err, when set, is returned instead, and gate, // when non-nil, blocks each call until it is closed. type fakeControl struct { - ateapipb.UnimplementedControlServer + ateapi.UnimplementedControlServer calls atomic.Int32 - last atomic.Pointer[ateapipb.MintActorJwtRequest] + last atomic.Pointer[ateapi.MintActorJwtRequest] err error gate chan struct{} } -func (f *fakeControl) MintActorJwt(ctx context.Context, req *ateapipb.MintActorJwtRequest) (*ateapipb.MintActorJwtResponse, error) { +func (f *fakeControl) MintActorJwt(ctx context.Context, req *ateapi.MintActorJwtRequest) (*ateapi.MintActorJwtResponse, error) { n := f.calls.Add(1) f.last.Store(req) if f.gate != nil { @@ -63,7 +63,7 @@ func (f *fakeControl) MintActorJwt(ctx context.Context, req *ateapipb.MintActorJ if f.err != nil { return nil, f.err } - return &ateapipb.MintActorJwtResponse{ + return &ateapi.MintActorJwtResponse{ ActorJwt: fmt.Sprintf("jwt-%d", n), ExpireTime: timestamppb.New(time.Now().Add(time.Duration(req.GetExpirationSeconds()) * time.Second)), }, nil @@ -75,7 +75,7 @@ func newMinter(t *testing.T, ctl *fakeControl) *Minter { t.Helper() lis := bufconn.Listen(1 << 20) srv := grpc.NewServer() - ateapipb.RegisterControlServer(srv, ctl) + ateapi.RegisterControlServer(srv, ctl) go func() { _ = srv.Serve(lis) }() t.Cleanup(srv.Stop) @@ -86,15 +86,15 @@ func newMinter(t *testing.T, ctl *fakeControl) *Minter { t.Fatalf("grpc.NewClient: %v", err) } t.Cleanup(func() { _ = conn.Close() }) - return New(ateapipb.NewControlClient(conn)) + return New(ateapi.NewControlClient(conn)) } -func jwtSource(lifetime int64, audiences ...string) *ateapipb.ActorJwtSource { - return &ateapipb.ActorJwtSource{Audiences: audiences, ExpirationSeconds: lifetime} +func jwtSource(lifetime int64, audiences ...string) *ateapi.ActorJwtSource { + return &ateapi.ActorJwtSource{Audiences: audiences, ExpirationSeconds: lifetime} } // wantToken calls m.Token and fails the test unless it returns want. -func wantToken(t *testing.T, m *Minter, ref resources.ActorRef, src *ateapipb.ActorJwtSource, want string) { +func wantToken(t *testing.T, m *Minter, ref resources.ActorRef, src *ateapi.ActorJwtSource, want string) { t.Helper() got, err := m.Token(context.Background(), ref, src) if err != nil { @@ -112,8 +112,8 @@ func TestReuseTokenUntilAThirdOfItsLifetimeRemains(t *testing.T) { src := jwtSource(900, "https://b.example", "https://a.example") wantToken(t, m, testActor, src, "jwt-1") - want := &ateapipb.MintActorJwtRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "default", Name: "my-actor"}, + want := &ateapi.MintActorJwtRequest{ + Actor: &ateapi.ObjectRef{Atespace: "default", Name: "my-actor"}, Audiences: []string{"https://a.example", "https://b.example"}, ExpirationSeconds: 900, } diff --git a/cmd/atenet/internal/router/egress/credentials.go b/cmd/atenet/internal/router/egress/credentials.go index 283819c7b6..4814a155ad 100644 --- a/cmd/atenet/internal/router/egress/credentials.go +++ b/cmd/atenet/internal/router/egress/credentials.go @@ -26,11 +26,11 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/api/credprovider/v1" "go.ate.dev/substrate/cmd/atenet/internal/router/extproc" "go.ate.dev/substrate/internal/egresspolicy" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" - "go.ate.dev/substrate/pkg/proto/credproviderpb" ) // injectionTimeout caps resolving a request's credentials, under the ext_proc @@ -79,8 +79,8 @@ func mapActorJWTError(err error) error { // Any failure to produce a credential the request needs denies it, including // having no provider configured for a credential_uri entry. Actor JWTs need no // provider. -func (h *Handler) applyEffects(ctx context.Context, ref resources.ActorRef, dest egresspolicy.Destination, headers map[string]string, effects *ateapipb.HttpRuleEffects) ([]*corev3.HeaderValueOption, error) { - var injections []*ateapipb.CredentialHeader +func (h *Handler) applyEffects(ctx context.Context, ref resources.ActorRef, dest egresspolicy.Destination, headers map[string]string, effects *ateapi.HttpRuleEffects) ([]*corev3.HeaderValueOption, error) { + var injections []*ateapi.CredentialHeader for _, inj := range effects.GetReplaceHeaders() { if _, ok := headers[strings.ToLower(inj.GetHeader())]; ok { injections = append(injections, inj) @@ -126,7 +126,7 @@ func (h *Handler) applyEffects(ctx context.Context, ref resources.ActorRef, dest // actorJWT mints the JWT src asks for. Every error it returns is already a // client-facing denial. -func (h *Handler) actorJWT(ctx context.Context, ref resources.ActorRef, dest egresspolicy.Destination, src *ateapipb.ActorJwtSource) ([]byte, error) { +func (h *Handler) actorJWT(ctx context.Context, ref resources.ActorRef, dest egresspolicy.Destination, src *ateapi.ActorJwtSource) ([]byte, error) { jwt, err := h.actorJWTs.Token(ctx, ref, src) if err != nil { slog.ErrorContext(ctx, "egress denied: actor JWT mint failed", @@ -166,7 +166,7 @@ func (h *Handler) providerCredential(ctx context.Context, ref resources.ActorRef // Atunnel connected to us with a worker-for-actor SPIFFE ID; translate it // to a pure actor SPIFFE ID for plugins to make decisions on. - resp, err := h.provider.FetchSecret(ctx, &credproviderpb.FetchSecretRequest{ + resp, err := h.provider.FetchSecret(ctx, &credprovider.FetchSecretRequest{ Uri: uri, ActorSpiffeId: resources.ActorSPIFFEID(ref).String(), }) diff --git a/cmd/atenet/internal/router/egress/credentials_test.go b/cmd/atenet/internal/router/egress/credentials_test.go index 32723686a8..b69fb4af84 100644 --- a/cmd/atenet/internal/router/egress/credentials_test.go +++ b/cmd/atenet/internal/router/egress/credentials_test.go @@ -29,9 +29,9 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/api/credprovider/v1" "go.ate.dev/substrate/cmd/atenet/internal/router/extproc" - "go.ate.dev/substrate/pkg/proto/ateapipb" - "go.ate.dev/substrate/pkg/proto/credproviderpb" ) // credentialInjectionPolicySample injects "authorization: Bearer " from @@ -40,23 +40,23 @@ const injectionProviderName = "k8s" // fakeProvider is a stub CredentialProviderClient recording the last request. type fakeProvider struct { - resp *credproviderpb.FetchSecretResponse + resp *credprovider.FetchSecretResponse err error - got *credproviderpb.FetchSecretRequest + got *credprovider.FetchSecretRequest } -func (f *fakeProvider) FetchSecret(_ context.Context, req *credproviderpb.FetchSecretRequest, _ ...grpc.CallOption) (*credproviderpb.FetchSecretResponse, error) { +func (f *fakeProvider) FetchSecret(_ context.Context, req *credprovider.FetchSecretRequest, _ ...grpc.CallOption) (*credprovider.FetchSecretResponse, error) { f.got = req return f.resp, f.err } // bearerTokenResponse is a FetchSecretResponse carrying a bearer-token // credential as its opaque secret bytes. -func bearerTokenResponse(token string) *credproviderpb.FetchSecretResponse { - return &credproviderpb.FetchSecretResponse{OpaqueBytes: []byte(token)} +func bearerTokenResponse(token string) *credprovider.FetchSecretResponse { + return &credprovider.FetchSecretResponse{OpaqueBytes: []byte(token)} } -func injectionHandlerFor(policy *ateapipb.EgressPolicy, provider credproviderpb.CredentialProviderClient, providerName string) *Handler { +func injectionHandlerFor(policy *ateapi.EgressPolicy, provider credprovider.CredentialProviderClient, providerName string) *Handler { return New(&egressMockClient{actor: runningActor(), policy: policy}, nil, 0, provider, providerName) } @@ -73,7 +73,7 @@ func TestInjectionOnRequestLegs(t *testing.T) { for _, tc := range []struct { name string leg string - policy *ateapipb.EgressPolicy + policy *ateapi.EgressPolicy }{ {name: "https", leg: extproc.EgressTLSMITMFilterChainName, policy: credentialInjectionPolicySample("api.example.com")}, {name: "http", leg: extproc.EgressCleartextFilterChainName, policy: cleartextInjectionPolicy("api.example.com")}, @@ -116,16 +116,16 @@ func TestInjectionOnRequestLegs(t *testing.T) { // A request that does not carry the header a rule replaces goes out unchanged: // nothing is fetched, added, or denied, even where injecting would fail. func TestInjectionSkippedWithoutHeader(t *testing.T) { - jwtPolicy := &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{{Https: &ateapipb.HttpsRule{ + jwtPolicy := &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{{Https: &ateapi.HttpsRule{ Hostnames: []string{"api.example.com"}, - Effects: &ateapipb.HttpRuleEffects{ReplaceHeaders: []*ateapipb.CredentialHeader{{ + Effects: &ateapi.HttpRuleEffects{ReplaceHeaders: []*ateapi.CredentialHeader{{ Header: "authorization", - ActorJwt: &ateapipb.ActorJwtSource{Audiences: []string{"https://api.example.com"}}, + ActorJwt: &ateapi.ActorJwtSource{Audiences: []string{"https://api.example.com"}}, }}}, }}}} for _, tc := range []struct { name string - policy *ateapipb.EgressPolicy + policy *ateapi.EgressPolicy provider *fakeProvider // nil means no provider configured }{ {name: "provider configured", policy: credentialInjectionPolicySample("api.example.com"), provider: &fakeProvider{resp: bearerTokenResponse("s3cr3t")}}, @@ -133,7 +133,7 @@ func TestInjectionSkippedWithoutHeader(t *testing.T) { {name: "actor JWT", policy: jwtPolicy, provider: &fakeProvider{resp: bearerTokenResponse("s3cr3t")}}, } { t.Run(tc.name, func(t *testing.T) { - var provider credproviderpb.CredentialProviderClient + var provider credprovider.CredentialProviderClient if tc.provider != nil { provider = tc.provider } @@ -156,9 +156,9 @@ func TestInjectionSkippedWithoutHeader(t *testing.T) { // Of a rule's replacements, only those whose header the request carries are // applied, matching the header name case-insensitively. func TestInjectionReplacesOnlyCarriedHeaders(t *testing.T) { - policy := &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{{Https: &ateapipb.HttpsRule{ + policy := &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{{Https: &ateapi.HttpsRule{ Hostnames: []string{"api.example.com"}, - Effects: &ateapipb.HttpRuleEffects{ReplaceHeaders: []*ateapipb.CredentialHeader{ + Effects: &ateapi.HttpRuleEffects{ReplaceHeaders: []*ateapi.CredentialHeader{ {Header: "authorization", Prefix: "Bearer ", CredentialUri: "ate-secret://k8s/default/token"}, {Header: "X-Api-Key", CredentialUri: "ate-secret://k8s/default/api-key"}, }}, @@ -189,7 +189,7 @@ func TestInjectionReplacesOnlyCarriedHeaders(t *testing.T) { func TestInjectionDenials(t *testing.T) { tests := []struct { name string - provider credproviderpb.CredentialProviderClient + provider credprovider.CredentialProviderClient providerName string want envoy_type.StatusCode }{ @@ -259,7 +259,7 @@ func TestInjectionDenials(t *testing.T) { // blockingProvider never answers, like a provider stuck dialing type blockingProvider struct{} -func (blockingProvider) FetchSecret(ctx context.Context, _ *credproviderpb.FetchSecretRequest, _ ...grpc.CallOption) (*credproviderpb.FetchSecretResponse, error) { +func (blockingProvider) FetchSecret(ctx context.Context, _ *credprovider.FetchSecretRequest, _ ...grpc.CallOption) (*credprovider.FetchSecretResponse, error) { <-ctx.Done() return nil, status.FromContextError(ctx.Err()).Err() } @@ -280,24 +280,24 @@ func TestInjectionProviderHangs(t *testing.T) { } // actorJWTHeader replaces header with an actor JWT bound to api.example.com. -func actorJWTHeader(header string) *ateapipb.CredentialHeader { - return &ateapipb.CredentialHeader{ +func actorJWTHeader(header string) *ateapi.CredentialHeader { + return &ateapi.CredentialHeader{ Header: header, Prefix: "Bearer ", - ActorJwt: &ateapipb.ActorJwtSource{Audiences: []string{"https://api.example.com"}, ExpirationSeconds: 900}, + ActorJwt: &ateapi.ActorJwtSource{Audiences: []string{"https://api.example.com"}, ExpirationSeconds: 900}, } } // replaceHeadersPolicy is a rule for api.example.com on leg's protocol (https // for the MITM leg, http for the cleartext one) that replaces headers with // entries. -func replaceHeadersPolicy(leg string, entries ...*ateapipb.CredentialHeader) *ateapipb.EgressPolicy { +func replaceHeadersPolicy(leg string, entries ...*ateapi.CredentialHeader) *ateapi.EgressPolicy { hosts := []string{"api.example.com"} - effects := &ateapipb.HttpRuleEffects{ReplaceHeaders: entries} + effects := &ateapi.HttpRuleEffects{ReplaceHeaders: entries} if leg == extproc.EgressCleartextFilterChainName { - return &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{{Http: &ateapipb.HttpRule{Hostnames: hosts, Effects: effects}}}} + return &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{{Http: &ateapi.HttpRule{Hostnames: hosts, Effects: effects}}}} } - return &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{{Https: &ateapipb.HttpsRule{Hostnames: hosts, Effects: effects}}}} + return &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{{Https: &ateapi.HttpsRule{Hostnames: hosts, Effects: effects}}}} } var requestLegs = []string{extproc.EgressTLSMITMFilterChainName, extproc.EgressCleartextFilterChainName} @@ -310,7 +310,7 @@ func TestActorJWTInjection(t *testing.T) { t.Run(leg, func(t *testing.T) { client := &egressMockClient{actor: runningActor(), policy: replaceHeadersPolicy(leg, actorJWTHeader("authorization"), - &ateapipb.CredentialHeader{Header: "x-api-key", CredentialUri: "ate-secret://k8s/default/token"}, + &ateapi.CredentialHeader{Header: "x-api-key", CredentialUri: "ate-secret://k8s/default/token"}, )} h := New(client, nil, 0, nil, "") @@ -333,8 +333,8 @@ func TestActorJWTInjection(t *testing.T) { if h0.GetAppendAction() != corev3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD { t.Errorf("append action = %v, want OVERWRITE_IF_EXISTS_OR_ADD", h0.GetAppendAction()) } - want := &ateapipb.MintActorJwtRequest{ - Actor: &ateapipb.ObjectRef{Atespace: testEgressAtespace, Name: testEgressActor}, + want := &ateapi.MintActorJwtRequest{ + Actor: &ateapi.ObjectRef{Atespace: testEgressAtespace, Name: testEgressActor}, Audiences: []string{"https://api.example.com"}, ExpirationSeconds: 900, } diff --git a/cmd/atenet/internal/router/egress/egress.go b/cmd/atenet/internal/router/egress/egress.go index 207c0a6d03..9e8de155ff 100644 --- a/cmd/atenet/internal/router/egress/egress.go +++ b/cmd/atenet/internal/router/egress/egress.go @@ -41,12 +41,12 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/structpb" + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/api/credprovider/v1" "go.ate.dev/substrate/cmd/atenet/internal/router/egress/actorjwt" "go.ate.dev/substrate/cmd/atenet/internal/router/extproc" "go.ate.dev/substrate/internal/egresspolicy" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" - "go.ate.dev/substrate/pkg/proto/credproviderpb" ) const ( @@ -77,7 +77,7 @@ const deniedBody = "egress denied" // Handler authenticates the actor behind each egress CONNECT and authorizes // the traffic inside the tunnel against the actor's EgressPolicy. type Handler struct { - apiClient ateapipb.ControlClient + apiClient ateapi.ControlClient // loadActorIdentityRoots yields the actor-identity CA bundle every actor // certificate must chain to. An error fails the CONNECT closed. loadActorIdentityRoots func() (*x509.CertPool, error) @@ -87,7 +87,7 @@ type Handler struct { actorJWTs *actorjwt.Minter // provider resolves an egress policy's credential_uri injections. Nil // means none are configured, and a request that needs one is denied. - provider credproviderpb.CredentialProviderClient + provider credprovider.CredentialProviderClient // providerName, when set, is the provider this gateway serves (the host of // its ate-secret:// credential URIs); a credential URI naming another // provider is refused. @@ -105,7 +105,7 @@ type Handler struct { // denied. Actor JWT injections need no provider. providerName, when set, is // the provider this gateway serves; a credential URI naming another provider // is refused. -func New(apiClient ateapipb.ControlClient, loadActorIdentityRoots func() (*x509.CertPool, error), policyCacheTTL time.Duration, provider credproviderpb.CredentialProviderClient, providerName string) *Handler { +func New(apiClient ateapi.ControlClient, loadActorIdentityRoots func() (*x509.CertPool, error), policyCacheTTL time.Duration, provider credprovider.CredentialProviderClient, providerName string) *Handler { if loadActorIdentityRoots == nil { loadActorIdentityRoots = func() (*x509.CertPool, error) { return nil, errors.New("no actor-identity CA configured") @@ -171,7 +171,7 @@ func (h *Handler) handleConnect(ctx context.Context, md *extproc.RequestMetadata "egress denied: invalid actor certificate") } - if err := h.validateActor(ctx, actorRef); err != nil { + if err := h.validateActor(ctx, actorRef, md.Host); err != nil { return extproc.Result{}, err } @@ -276,24 +276,32 @@ func (h *Handler) lookupPolicy(ctx context.Context, leg string, ref resources.Ac } // validateActor checks the actor certified by the certificate against the control -// plane's current view of that actor: it still exists and it is running. Every -// error it returns is already a client-facing ext_proc denial. -func (h *Handler) validateActor(ctx context.Context, actorRef resources.ActorRef) error { +// plane's current view of that actor: it still exists and it is placed on a +// worker. A refusal is logged with destination. Every error it returns is +// already a client-facing ext_proc denial. +func (h *Handler) validateActor(ctx context.Context, actorRef resources.ActorRef, destination string) error { // Confirm the certified actor still exists. // TODO: this can cause heavy load on ate api server. Change it based on https://github.com/agent-substrate/substrate/issues/592. - actor, err := h.apiClient.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: actorRef.Atespace, Name: actorRef.Name}, + actor, err := h.apiClient.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: actorRef.Atespace, Name: actorRef.Name}, }) if err != nil { return mapEgressIdentityError(actorRef.Atespace, actorRef.Name, err) } - // The actor performing egress must actually be running. - if actor.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { + // The actor performing egress must be placed on a worker. RESUMING is + // saved together with the worker assignment, so a booting workload can + // reach the network before it answers its wakeup probe. Every other state + // has left its worker or is leaving it. + switch state := actor.GetStatus().GetState(); state { + case ateapi.ActorState_ACTOR_STATE_RUNNING, ateapi.ActorState_ACTOR_STATE_RESUMING: + return nil + default: + slog.WarnContext(ctx, "egress denied: actor is not placed on a worker", + slog.Any("actor", actorRef), slog.String("state", state.String()), slog.String("destination", destination)) return extproc.NewReqError(envoy_type.StatusCode_Forbidden, - "egress denied: actor %q/%q is %s, not running", actorRef.Atespace, actorRef.Name, actor.GetStatus().GetState()) + "egress denied: actor %q/%q is %s, not placed on a worker", actorRef.Atespace, actorRef.Name, state) } - return nil } // authenticateActorCertificate turns the mTLS peer certificate Envoy recorded diff --git a/cmd/atenet/internal/router/egress/egress_test.go b/cmd/atenet/internal/router/egress/egress_test.go index 7f367cd3bf..79d475cb83 100644 --- a/cmd/atenet/internal/router/egress/egress_test.go +++ b/cmd/atenet/internal/router/egress/egress_test.go @@ -42,10 +42,10 @@ import ( "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/atenet/internal/router/extproc" "go.ate.dev/substrate/internal/egresspolicy" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const ( @@ -166,19 +166,19 @@ func xfccHeaderDER(chain ...[]byte) string { // egressHandler builds a Handler with an allow-everything policy, so the // identity tests are about identity alone. -func egressHandler(loadRoots func() (*x509.CertPool, error), actor *ateapipb.Actor, err error) *Handler { +func egressHandler(loadRoots func() (*x509.CertPool, error), actor *ateapi.Actor, err error) *Handler { return New(&egressMockClient{actor: actor, err: err, policy: allowAllPolicy()}, loadRoots, DefaultPolicyCacheTTL, nil, "") } // egressMockClient is the slice of ateapi the egress handler talks to. type egressMockClient struct { - ateapipb.ControlClient - actor *ateapipb.Actor + ateapi.ControlClient + actor *ateapi.Actor err error // policy is what GetActorEgressPolicy returns; nil answers NotFound. // policyErr, when set, is returned instead. - policy *ateapipb.EgressPolicy + policy *ateapi.EgressPolicy policyErr error // policyCalls counts GetActorEgressPolicy calls, for the cache tests. policyCalls atomic.Int32 @@ -189,18 +189,18 @@ type egressMockClient struct { // The nth MintActorJwt call returns "jwt-", expiring // expiration_seconds from now. mintErr, when set, is returned instead. mintCalls atomic.Int32 - lastMint atomic.Pointer[ateapipb.MintActorJwtRequest] + lastMint atomic.Pointer[ateapi.MintActorJwtRequest] mintErr error } -func (m *egressMockClient) GetActor(context.Context, *ateapipb.GetActorRequest, ...grpc.CallOption) (*ateapipb.Actor, error) { +func (m *egressMockClient) GetActor(context.Context, *ateapi.GetActorRequest, ...grpc.CallOption) (*ateapi.Actor, error) { if m.err != nil { return nil, m.err } return m.actor, nil } -func (m *egressMockClient) GetActorEgressPolicy(ctx context.Context, req *ateapipb.GetActorEgressPolicyRequest, _ ...grpc.CallOption) (*ateapipb.EgressPolicy, error) { +func (m *egressMockClient) GetActorEgressPolicy(ctx context.Context, req *ateapi.GetActorEgressPolicyRequest, _ ...grpc.CallOption) (*ateapi.EgressPolicy, error) { m.policyCalls.Add(1) if req.GetName() != resources.SingletonName { return nil, status.Errorf(codes.InvalidArgument, "name must be %q", resources.SingletonName) @@ -221,13 +221,13 @@ func (m *egressMockClient) GetActorEgressPolicy(ctx context.Context, req *ateapi return m.policy, nil } -func (m *egressMockClient) MintActorJwt(_ context.Context, req *ateapipb.MintActorJwtRequest, _ ...grpc.CallOption) (*ateapipb.MintActorJwtResponse, error) { +func (m *egressMockClient) MintActorJwt(_ context.Context, req *ateapi.MintActorJwtRequest, _ ...grpc.CallOption) (*ateapi.MintActorJwtResponse, error) { n := m.mintCalls.Add(1) m.lastMint.Store(req) if m.mintErr != nil { return nil, m.mintErr } - return &ateapipb.MintActorJwtResponse{ + return &ateapi.MintActorJwtResponse{ ActorJwt: fmt.Sprintf("jwt-%d", n), ExpireTime: timestamppb.New(time.Now().Add(time.Duration(req.GetExpirationSeconds()) * time.Second)), }, nil @@ -235,52 +235,52 @@ func (m *egressMockClient) MintActorJwt(_ context.Context, req *ateapipb.MintAct // allowAllPolicy allows every name and address: cleartext HTTP on any port // and HTTPS on 443. -func allowAllPolicy() *ateapipb.EgressPolicy { +func allowAllPolicy() *ateapi.EgressPolicy { return combined(httpPolicyOnPorts(allPorts(), "*"), httpsPolicy("*")) } -func httpPolicy(patterns ...string) *ateapipb.EgressPolicy { - return &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{{ - Http: &ateapipb.HttpRule{Hostnames: patterns}, +func httpPolicy(patterns ...string) *ateapi.EgressPolicy { + return &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{{ + Http: &ateapi.HttpRule{Hostnames: patterns}, }}} } -func httpPolicyOnPorts(ports *ateapipb.Ports, patterns ...string) *ateapipb.EgressPolicy { - return &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{{ - Http: &ateapipb.HttpRule{Hostnames: patterns, Ports: ports}, +func httpPolicyOnPorts(ports *ateapi.Ports, patterns ...string) *ateapi.EgressPolicy { + return &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{{ + Http: &ateapi.HttpRule{Hostnames: patterns, Ports: ports}, }}} } -func httpsPolicy(patterns ...string) *ateapipb.EgressPolicy { - return &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{{ - Https: &ateapipb.HttpsRule{Hostnames: patterns}, +func httpsPolicy(patterns ...string) *ateapi.EgressPolicy { + return &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{{ + Https: &ateapi.HttpsRule{Hostnames: patterns}, }}} } -func httpsPolicyOnPorts(ports *ateapipb.Ports, patterns ...string) *ateapipb.EgressPolicy { - return &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{{ - Https: &ateapipb.HttpsRule{Hostnames: patterns, Ports: ports}, +func httpsPolicyOnPorts(ports *ateapi.Ports, patterns ...string) *ateapi.EgressPolicy { + return &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{{ + Https: &ateapi.HttpsRule{Hostnames: patterns, Ports: ports}, }}} } -func passthroughPolicy(ports *ateapipb.Ports, patterns ...string) *ateapipb.EgressPolicy { - return &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{{ - TlsPassthrough: &ateapipb.TlsPassthroughRule{Hostnames: patterns, Ports: ports}, +func passthroughPolicy(ports *ateapi.Ports, patterns ...string) *ateapi.EgressPolicy { + return &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{{ + TlsPassthrough: &ateapi.TlsPassthroughRule{Hostnames: patterns, Ports: ports}, }}} } -func ports(numbers ...int32) *ateapipb.Ports { return &ateapipb.Ports{Numbers: numbers} } +func ports(numbers ...int32) *ateapi.Ports { return &ateapi.Ports{Numbers: numbers} } -func allPorts() *ateapipb.Ports { return &ateapipb.Ports{All: &ateapipb.AllPorts{}} } +func allPorts() *ateapi.Ports { return &ateapi.Ports{All: &ateapi.AllPorts{}} } -func runningActor() *ateapipb.Actor { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ +func runningActor() *ateapi.Actor { + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: testEgressAtespace, Name: testEgressActor, Uid: testEgressActorUID, }, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, } } @@ -382,7 +382,7 @@ func TestConnectLegOpensForAnyRules(t *testing.T) { } tests := []struct { name string - policy *ateapipb.EgressPolicy + policy *ateapi.EgressPolicy // dialed is the CONNECT authority; port 443 unless set. dialed string want []egresspolicy.SNIRule @@ -716,19 +716,19 @@ func TestHandleRequestHeadersAuthorization(t *testing.T) { tests := []struct { name string - actor *ateapipb.Actor + actor *ateapi.Actor err error want envoy_type.StatusCode }{ { - name: "actor is not running", - actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ + name: "actor is suspended", + actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: testEgressAtespace, Name: testEgressActor, Uid: testEgressActorUID, }, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }, want: envoy_type.StatusCode_Forbidden, }, @@ -754,6 +754,37 @@ func TestHandleRequestHeadersAuthorization(t *testing.T) { } } +// Egress follows the actor's placement on a worker: a resuming actor is booting +// or restoring there and may fetch what it needs to become ready; every other +// state has left its worker or is leaving it. +func TestHandleRequestHeadersActorState(t *testing.T) { + ca := newTestCA(t, "actor-identity-ca") + allowed := map[ateapi.ActorState]bool{ + ateapi.ActorState_ACTOR_STATE_RESUMING: true, + ateapi.ActorState_ACTOR_STATE_RUNNING: true, + } + for value := range ateapi.ActorState_name { + state := ateapi.ActorState(value) + if state == ateapi.ActorState_ACTOR_STATE_UNSPECIFIED { + continue + } + t.Run(state.String(), func(t *testing.T) { + actor := runningActor() + actor.Status.State = state + h := egressHandler(ca.loadRoots, actor, nil) + leaf := ca.issueActorCert(t, "spiffe://substrate-actor.local/worker-for-actor/foo/bar", actorCertOptions{}) + _, err := h.HandleRequestHeaders(context.Background(), egressMetadata(xfccHeader(leaf))) + if allowed[state] { + if err != nil { + t.Fatalf("HandleRequestHeaders() error = %v, want nil", err) + } + return + } + wantStatus(t, err, envoy_type.StatusCode_Forbidden) + }) + } +} + // Without actor-identity roots the gateway must fail closed rather than tunnel // unauthenticated traffic. An ingress-only router has no CA configured, and a // configured bundle can become unreadable after startup. diff --git a/cmd/atenet/internal/router/egress/policycache.go b/cmd/atenet/internal/router/egress/policycache.go index 28f6f29e02..c597b09d65 100644 --- a/cmd/atenet/internal/router/egress/policycache.go +++ b/cmd/atenet/internal/router/egress/policycache.go @@ -26,9 +26,9 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/egresspolicy" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // DefaultPolicyCacheTTL is how long a fetched policy stays usable, and so how @@ -47,7 +47,7 @@ var errNoPolicy = errors.New("actor has no egress policy") // policyCache holds each actor's compiled EgressPolicy for one TTL. Every leg // reads through it, so the CONNECT warms the entry for the requests inside. type policyCache struct { - client ateapipb.ControlClient + client ateapi.ControlClient // ttl of 0 disables caching: every call fetches. ttl time.Duration now func() time.Time @@ -73,7 +73,7 @@ type policyEntry struct { expires time.Time } -func newPolicyCache(client ateapipb.ControlClient, ttl time.Duration) *policyCache { +func newPolicyCache(client ateapi.ControlClient, ttl time.Duration) *policyCache { return &policyCache{ client: client, ttl: ttl, @@ -137,7 +137,7 @@ func (c *policyCache) cached(ref resources.ActorRef) (*egresspolicy.Policy, bool // fetch loads and compiles one actor's policy and stores the result. A nil // policy with a nil error is the stored form of "no policy". func (c *policyCache) fetch(ctx context.Context, ref resources.ActorRef) (*egresspolicy.Policy, error) { - resp, err := c.client.GetActorEgressPolicy(ctx, &ateapipb.GetActorEgressPolicyRequest{Actor: ref.ToObjectRef(), Name: resources.SingletonName}) + resp, err := c.client.GetActorEgressPolicy(ctx, &ateapi.GetActorEgressPolicyRequest{Actor: ref.ToObjectRef(), Name: resources.SingletonName}) var policy *egresspolicy.Policy switch { case err == nil: diff --git a/cmd/atenet/internal/router/egress/request_test.go b/cmd/atenet/internal/router/egress/request_test.go index 548d3075ab..89d8527717 100644 --- a/cmd/atenet/internal/router/egress/request_test.go +++ b/cmd/atenet/internal/router/egress/request_test.go @@ -26,8 +26,8 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/structpb" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/atenet/internal/router/extproc" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // testActorSPIFFEID is the identity filter state the CONNECT chain shares. @@ -42,30 +42,30 @@ func testDialed(leg string) string { return "93.184.216.34:80" } -func sampleEffects() *ateapipb.HttpRuleEffects { - return &ateapipb.HttpRuleEffects{ReplaceHeaders: []*ateapipb.CredentialHeader{{ +func sampleEffects() *ateapi.HttpRuleEffects { + return &ateapi.HttpRuleEffects{ReplaceHeaders: []*ateapi.CredentialHeader{{ Header: "authorization", Prefix: "Bearer ", CredentialUri: "ate-secret://k8s/default/token", }}} } // credentialInjectionPolicySample is an https rule for pattern that replaces // the authorization header, which only the MITM leg can honor. -func credentialInjectionPolicySample(pattern string) *ateapipb.EgressPolicy { - return &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{{ - Https: &ateapipb.HttpsRule{Hostnames: []string{pattern}, Effects: sampleEffects()}, +func credentialInjectionPolicySample(pattern string) *ateapi.EgressPolicy { + return &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{{ + Https: &ateapi.HttpsRule{Hostnames: []string{pattern}, Effects: sampleEffects()}, }}} } // cleartextInjectionPolicy is the same replacement on an http rule. -func cleartextInjectionPolicy(pattern string) *ateapipb.EgressPolicy { - return &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{{ - Http: &ateapipb.HttpRule{Hostnames: []string{pattern}, Effects: sampleEffects()}, +func cleartextInjectionPolicy(pattern string) *ateapi.EgressPolicy { + return &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{{ + Http: &ateapi.HttpRule{Hostnames: []string{pattern}, Effects: sampleEffects()}, }}} } // policyHandler builds a Handler for an actor whose policy is policy (nil // means none) with the cache disabled, so each callout sees the mock as is. -func policyHandler(policy *ateapipb.EgressPolicy) *Handler { +func policyHandler(policy *ateapi.EgressPolicy) *Handler { return New(&egressMockClient{actor: runningActor(), policy: policy}, nil, 0, nil, "") } @@ -130,8 +130,8 @@ func TestHandleRequestHeadersRefusesUnknownFilterChain(t *testing.T) { } // combined is one policy with the rules of policies, in order. -func combined(policies ...*ateapipb.EgressPolicy) *ateapipb.EgressPolicy { - out := &ateapipb.EgressPolicy{} +func combined(policies ...*ateapi.EgressPolicy) *ateapi.EgressPolicy { + out := &ateapi.EgressPolicy{} for _, p := range policies { out.Rules = append(out.Rules, p.Rules...) } @@ -205,7 +205,7 @@ func TestRequestLegAnswersTheNameToDial(t *testing.T) { func TestRequestLegDecidesHostAndDialedPort(t *testing.T) { tests := []struct { name string - policy *ateapipb.EgressPolicy + policy *ateapi.EgressPolicy authority string attrs map[string]string noAuthority bool // a dataplane that does not share the CONNECT authority @@ -267,7 +267,7 @@ func TestMITMLegDecidesSNIThenAuthority(t *testing.T) { two := combined(httpsPolicy("api.example.com"), httpsPolicy("cdn.example.com")) tests := []struct { name string - policy *ateapipb.EgressPolicy + policy *ateapi.EgressPolicy sni string authority string want envoy_type.StatusCode // 0 means allowed @@ -309,7 +309,7 @@ func TestRequestLegServesBothDecryptedChains(t *testing.T) { // http rules and the MITM chain by the https rules, never the other way. func TestRequestLegPicksRulesByLeg(t *testing.T) { for _, tc := range []struct { - policy *ateapipb.EgressPolicy + policy *ateapi.EgressPolicy leg string want envoy_type.StatusCode // 0 means allowed }{ @@ -345,7 +345,7 @@ func TestRequestLegDeniesHTTP1WebSocketUpgrade(t *testing.T) { } func TestRequestLegDeniesConnect(t *testing.T) { - for name, policy := range map[string]*ateapipb.EgressPolicy{ + for name, policy := range map[string]*ateapi.EgressPolicy{ "allow-all policy": allowAllPolicy(), "no policy": nil, } { @@ -414,7 +414,7 @@ func TestRequestLegPolicyLookup(t *testing.T) { want envoy_type.StatusCode }{ {name: "no policy", client: &egressMockClient{}, want: envoy_type.StatusCode_Forbidden}, - {name: "policy with no rules", client: &egressMockClient{policy: &ateapipb.EgressPolicy{}}, want: envoy_type.StatusCode_Forbidden}, + {name: "policy with no rules", client: &egressMockClient{policy: &ateapi.EgressPolicy{}}, want: envoy_type.StatusCode_Forbidden}, {name: "control plane unavailable", client: &egressMockClient{policyErr: status.Error(codes.Unavailable, "down")}, want: envoy_type.StatusCode_ServiceUnavailable}, {name: "control plane refuses", client: &egressMockClient{policyErr: status.Error(codes.PermissionDenied, "no")}, want: envoy_type.StatusCode_ServiceUnavailable}, } @@ -441,7 +441,7 @@ func TestConnectLegRequiresAPolicy(t *testing.T) { {name: "policy present", client: &egressMockClient{actor: runningActor(), policy: allowAllPolicy()}}, {name: "http-only policy still opens the tunnel", client: &egressMockClient{actor: runningActor(), policy: httpPolicy("api.example.com")}}, {name: "no policy", client: &egressMockClient{actor: runningActor()}, want: envoy_type.StatusCode_Forbidden}, - {name: "policy with no rules", client: &egressMockClient{actor: runningActor(), policy: &ateapipb.EgressPolicy{Rules: []*ateapipb.EgressRule{}}}, want: envoy_type.StatusCode_Forbidden}, + {name: "policy with no rules", client: &egressMockClient{actor: runningActor(), policy: &ateapi.EgressPolicy{Rules: []*ateapi.EgressRule{}}}, want: envoy_type.StatusCode_Forbidden}, {name: "control plane unavailable", client: &egressMockClient{actor: runningActor(), policyErr: status.Error(codes.Unavailable, "down")}, want: envoy_type.StatusCode_ServiceUnavailable}, } for _, tc := range tests { diff --git a/cmd/atenet/internal/router/extproc/metrics.go b/cmd/atenet/internal/router/extproc/metrics.go index 3f6a07ddb5..bbf479821a 100644 --- a/cmd/atenet/internal/router/extproc/metrics.go +++ b/cmd/atenet/internal/router/extproc/metrics.go @@ -95,6 +95,8 @@ func classifyOutcome(err error) string { return ateattr.RouterOutcomeNotFound case codes.Unavailable: return ateattr.RouterOutcomeUnavailable + case codes.PermissionDenied: + return ateattr.RouterOutcomeDenied } var re *ReqError if errors.As(err, &re) { @@ -106,13 +108,15 @@ func classifyOutcome(err error) string { // ResourceExhausted cause, since status.Code unwraps through // ReqError.Cause. A 503 that reaches here has no such cause: a // shed request whose resume did not fail with ResourceExhausted, - // a denied egress request, or a failed policy or credential - // lookup. None of these mean the fleet is full. + // or a failed policy or credential lookup. None of these mean + // the fleet is full. return ateattr.RouterOutcomeUnavailable case envoy_type.StatusCode_GatewayTimeout: return ateattr.RouterOutcomeTimeout case envoy_type.StatusCode_TooManyRequests: return ateattr.RouterOutcomeRateLimited + case envoy_type.StatusCode_Forbidden: + return ateattr.RouterOutcomeDenied } } return ateattr.RouterOutcomeResumeError diff --git a/cmd/atenet/internal/router/extproc/metrics_test.go b/cmd/atenet/internal/router/extproc/metrics_test.go index 2e081f9bfa..81fb8fbafe 100644 --- a/cmd/atenet/internal/router/extproc/metrics_test.go +++ b/cmd/atenet/internal/router/extproc/metrics_test.go @@ -101,11 +101,36 @@ func TestClassifyOutcome(t *testing.T) { err: NewReqError(envoy_type.StatusCode_TooManyRequests, "rate limited"), expected: "rate_limited", }, + { + name: "PermissionDenied gRPC code maps to denied", + err: status.Error(codes.PermissionDenied, "access denied"), + expected: "denied", + }, + { + name: "StatusCode_Forbidden ReqError maps to denied", + err: NewReqError(envoy_type.StatusCode_Forbidden, "egress denied"), + expected: "denied", + }, + { + name: "StatusCode_Forbidden ReqError with an uncoded cause maps to denied", + err: WrapReqError(envoy_type.StatusCode_Forbidden, errors.New("invalid actor certificate"), "egress denied"), + expected: "denied", + }, { name: "Unknown error maps to resume_error", err: errors.New("internal storage glitch"), expected: "resume_error", }, + { + name: "Internal gRPC code maps to resume_error", + err: status.Error(codes.Internal, "resume failed"), + expected: "resume_error", + }, + { + name: "StatusCode_InternalServerError ReqError maps to resume_error", + err: NewReqError(envoy_type.StatusCode_InternalServerError, "resume failed"), + expected: "resume_error", + }, } for _, tc := range tests { diff --git a/cmd/atenet/internal/router/health.go b/cmd/atenet/internal/router/health.go index 7505ff8b96..1cc2d8699a 100644 --- a/cmd/atenet/internal/router/health.go +++ b/cmd/atenet/internal/router/health.go @@ -25,7 +25,7 @@ import ( "sync" "time" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "k8s.io/apimachinery/pkg/version" "k8s.io/client-go/kubernetes" @@ -63,12 +63,12 @@ type routerHealth struct { interval time.Duration clientset kubernetes.Interface - apiClient ateapipb.ControlClient + apiClient ateapi.ControlClient cfg routerConfig dataplaneClient *http.Client } -func newRouterHealth(interval time.Duration, clientset kubernetes.Interface, apiClient ateapipb.ControlClient, cfg routerConfig) *routerHealth { +func newRouterHealth(interval time.Duration, clientset kubernetes.Interface, apiClient ateapi.ControlClient, cfg routerConfig) *routerHealth { if interval <= 0 { interval = time.Second } @@ -229,7 +229,7 @@ func (rh *routerHealth) checkAteAPI(ctx context.Context) (bool, string) { timeoutCtx, cancel := context.WithTimeout(ctx, dependencyHealthCheckTimeout) defer cancel() - _, err := rh.apiClient.ListActors(timeoutCtx, &ateapipb.ListActorsRequest{Options: &ateapipb.ListOptions{PageSize: 1}}) + _, err := rh.apiClient.ListActors(timeoutCtx, &ateapi.ListActorsRequest{Options: &ateapi.ListOptions{PageSize: 1}}) if err != nil { return false, err.Error() } diff --git a/cmd/atenet/internal/router/health_test.go b/cmd/atenet/internal/router/health_test.go index ccac1a4c72..88c608bfdc 100644 --- a/cmd/atenet/internal/router/health_test.go +++ b/cmd/atenet/internal/router/health_test.go @@ -25,7 +25,7 @@ import ( "testing" "time" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/grpc" "k8s.io/client-go/kubernetes" kubernetesfake "k8s.io/client-go/kubernetes/fake" @@ -39,15 +39,15 @@ func (f healthRoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error } type healthControlClient struct { - ateapipb.ControlClient - listActorsFn func(context.Context, *ateapipb.ListActorsRequest, ...grpc.CallOption) (*ateapipb.ListActorsResponse, error) + ateapi.ControlClient + listActorsFn func(context.Context, *ateapi.ListActorsRequest, ...grpc.CallOption) (*ateapi.ListActorsResponse, error) } func (c *healthControlClient) ListActors( ctx context.Context, - req *ateapipb.ListActorsRequest, + req *ateapi.ListActorsRequest, opts ...grpc.CallOption, -) (*ateapipb.ListActorsResponse, error) { +) (*ateapi.ListActorsResponse, error) { return c.listActorsFn(ctx, req, opts...) } @@ -262,11 +262,11 @@ func TestHealthChecksRunConcurrently(t *testing.T) { defer server.Close() apiClient := &healthControlClient{ - listActorsFn: func(ctx context.Context, _ *ateapipb.ListActorsRequest, _ ...grpc.CallOption) (*ateapipb.ListActorsResponse, error) { + listActorsFn: func(ctx context.Context, _ *ateapi.ListActorsRequest, _ ...grpc.CallOption) (*ateapi.ListActorsResponse, error) { started <- "ateapi" select { case <-release: - return &ateapipb.ListActorsResponse{}, nil + return &ateapi.ListActorsResponse{}, nil case <-ctx.Done(): return nil, ctx.Err() } diff --git a/cmd/atenet/internal/router/ingress/flight.go b/cmd/atenet/internal/router/ingress/flight.go index 7afd444b01..2460e554fa 100644 --- a/cmd/atenet/internal/router/ingress/flight.go +++ b/cmd/atenet/internal/router/ingress/flight.go @@ -17,7 +17,7 @@ package ingress import ( "sync/atomic" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -75,7 +75,7 @@ func (f *resumeActorFlight) retryErr() error { // resume reports "unknown": the gRPC code alone does not carry the fact. A // canceled leader's flight outlives its request and keeps restoring the actor, // and a DeadlineExceeded can land in the middle of a restore. -func (f *resumeActorFlight) callerResult(reqID uint64) (*ateapipb.Actor, ResumeOutcome, error) { +func (f *resumeActorFlight) callerResult(reqID uint64) (*ateapi.Actor, ResumeOutcome, error) { res := f.result if res == nil { return nil, ResumeOutcomeUnknown, status.Error(codes.Internal, "resume call returned nil result") diff --git a/cmd/atenet/internal/router/ingress/ingress.go b/cmd/atenet/internal/router/ingress/ingress.go index 58dd9f5dec..9557bff5e3 100644 --- a/cmd/atenet/internal/router/ingress/ingress.go +++ b/cmd/atenet/internal/router/ingress/ingress.go @@ -36,10 +36,10 @@ import ( "go.opentelemetry.io/otel" "google.golang.org/protobuf/types/known/structpb" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/atenet/internal/router/extproc" "go.ate.dev/substrate/internal/atenet" atunnelingress "go.ate.dev/substrate/internal/atunnel/ingress" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // defaultActorPort is the actor's port when a request names no other one. @@ -64,7 +64,7 @@ type Handler struct { parking *parkingLot } -func New(apiClient ateapipb.ControlClient, parkCfg ParkedRequestConfig, parkMetrics *ParkingMetrics) *Handler { +func New(apiClient ateapi.ControlClient, parkCfg ParkedRequestConfig, parkMetrics *ParkingMetrics) *Handler { lot := newParkingLot(parkCfg, parkMetrics) return &Handler{ resumer: NewActorResumer(apiClient, withParking(parkCfg), withParkingLot(lot)), diff --git a/cmd/atenet/internal/router/ingress/ingress_test.go b/cmd/atenet/internal/router/ingress/ingress_test.go index 760b55f0b8..e27475b34a 100644 --- a/cmd/atenet/internal/router/ingress/ingress_test.go +++ b/cmd/atenet/internal/router/ingress/ingress_test.go @@ -33,19 +33,19 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/structpb" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/atenet/internal/router/extproc" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/atenet" atunnelingress "go.ate.dev/substrate/internal/atunnel/ingress" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) type mockClient struct { - ateapipb.ControlClient - resumeFn func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) + ateapi.ControlClient + resumeFn func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) } -func (m *mockClient) ResumeActor(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { +func (m *mockClient) ResumeActor(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { return m.resumeFn(ctx, in, opts...) } @@ -58,15 +58,15 @@ func requestMetadata(actorName, atespace string, headers ...*corev3.HeaderValue) func TestHandleRequestHeadersAcceptsMixedCaseRoutingHeaders(t *testing.T) { clientMock := &mockClient{ - resumeFn: func(_ context.Context, in *ateapipb.ResumeActorRequest, _ ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(_ context.Context, in *ateapi.ResumeActorRequest, _ ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { if got, want := in.GetActor().GetName(), "actor-1"; got != want { t.Errorf("actor name = %q, want %q", got, want) } if got, want := in.GetActor().GetAtespace(), "team-a"; got != want { t.Errorf("atespace = %q, want %q", got, want) } - return &ateapipb.ResumeActorResponse{Actor: &ateapipb.Actor{ - Status: &ateapipb.ActorStatus{WorkerAssignment: &ateapipb.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.52"}}}, + return &ateapi.ResumeActorResponse{Actor: &ateapi.Actor{ + Status: &ateapi.ActorStatus{WorkerAssignment: &ateapi.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.52"}}}, }}, nil }, } @@ -122,7 +122,7 @@ func TestHandleRequestHeadersRejectsDuplicateOrCommaHeaders(t *testing.T) { t.Run(tt.name, func(t *testing.T) { var resumeCalls int32 clientMock := &mockClient{ - resumeFn: func(_ context.Context, _ *ateapipb.ResumeActorRequest, _ ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(_ context.Context, _ *ateapi.ResumeActorRequest, _ ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { atomic.AddInt32(&resumeCalls, 1) return nil, errors.New("should not be called") }, @@ -155,10 +155,10 @@ func TestHandleRequestHeadersConnectAttributeOverridesInnerHeader(t *testing.T) const testUUID = "123e4567-e89b-12d3-a456-426614174000" var gotActorRef string clientMock := &mockClient{ - resumeFn: func(_ context.Context, in *ateapipb.ResumeActorRequest, _ ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(_ context.Context, in *ateapi.ResumeActorRequest, _ ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { gotActorRef = in.GetActor().GetAtespace() + "/" + in.GetActor().GetName() - return &ateapipb.ResumeActorResponse{Actor: &ateapipb.Actor{ - Status: &ateapipb.ActorStatus{WorkerAssignment: &ateapipb.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.52"}}}, + return &ateapi.ResumeActorResponse{Actor: &ateapi.Actor{ + Status: &ateapi.ActorStatus{WorkerAssignment: &ateapi.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.52"}}}, }}, nil }, } @@ -227,8 +227,8 @@ func TestHandleRequestHeadersDoesNotLogSensitiveData(t *testing.T) { t.Cleanup(func() { slog.SetDefault(prev) }) h := New(&mockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { - return &ateapipb.ResumeActorResponse{Actor: &ateapipb.Actor{Status: &ateapipb.ActorStatus{WorkerAssignment: &ateapipb.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.52"}}}}}, nil + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { + return &ateapi.ResumeActorResponse{Actor: &ateapi.Actor{Status: &ateapi.ActorStatus{WorkerAssignment: &ateapi.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.52"}}}}}, nil }, }, ParkedRequestConfig{}, nil) @@ -272,7 +272,7 @@ func TestHandleRequestHeaders(t *testing.T) { actorName string atespace string authority string - resumeResp *ateapipb.ResumeActorResponse + resumeResp *ateapi.ResumeActorResponse resumeErr error expectErr bool expectedErrStr string @@ -332,9 +332,9 @@ func TestHandleRequestHeaders(t *testing.T) { { name: "Bad Actor IP from resume returns 500 without leaking IP", authority: testUUID + ".team-a.actors.resources.substrate.ate.dev", - resumeResp: &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{ - Status: &ateapipb.ActorStatus{WorkerAssignment: &ateapipb.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"invalid-ip"}}}, + resumeResp: &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{ + Status: &ateapi.ActorStatus{WorkerAssignment: &ateapi.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"invalid-ip"}}}, }, }, expectErr: true, @@ -344,9 +344,9 @@ func TestHandleRequestHeaders(t *testing.T) { { name: "No Actor IPs from resume returns 500", authority: testUUID + ".team-a.actors.resources.substrate.ate.dev", - resumeResp: &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{ - Status: &ateapipb.ActorStatus{WorkerAssignment: &ateapipb.WorkerAssignment{}}, + resumeResp: &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{ + Status: &ateapi.ActorStatus{WorkerAssignment: &ateapi.WorkerAssignment{}}, }, }, expectErr: true, @@ -356,9 +356,9 @@ func TestHandleRequestHeaders(t *testing.T) { { name: "No worker SPIFFE ID from resume returns 500", authority: testUUID + ".team-a.actors.resources.substrate.ate.dev", - resumeResp: &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{ - Status: &ateapipb.ActorStatus{WorkerAssignment: &ateapipb.WorkerAssignment{WorkerPodIps: []string{"10.0.0.52"}}}, + resumeResp: &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{ + Status: &ateapi.ActorStatus{WorkerAssignment: &ateapi.WorkerAssignment{WorkerPodIps: []string{"10.0.0.52"}}}, }, }, expectErr: true, @@ -368,9 +368,9 @@ func TestHandleRequestHeaders(t *testing.T) { { name: "successful resume ignores host and port for actor routing", authority: "127.0.0.1:44681", - resumeResp: &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{ - Status: &ateapipb.ActorStatus{WorkerAssignment: &ateapipb.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.52"}}}, + resumeResp: &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{ + Status: &ateapi.ActorStatus{WorkerAssignment: &ateapi.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.52"}}}, }, }, expectErr: false, @@ -380,9 +380,9 @@ func TestHandleRequestHeaders(t *testing.T) { { name: "dual-stack resume routes to the first IP", authority: "127.0.0.1:44681", - resumeResp: &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{ - Status: &ateapipb.ActorStatus{WorkerAssignment: &ateapipb.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"fd00::52", "10.0.0.52"}}}, + resumeResp: &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{ + Status: &ateapi.ActorStatus{WorkerAssignment: &ateapi.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"fd00::52", "10.0.0.52"}}}, }, }, expectErr: false, @@ -402,7 +402,7 @@ func TestHandleRequestHeaders(t *testing.T) { atespace = "team-a" } clientMock := &mockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { if in.GetActor().GetName() != testUUID { t.Errorf("unexpected identifier parsed in test context: %s", in.GetActor().GetName()) } @@ -493,8 +493,8 @@ func TestHandleRequestHeadersHandlesConnectMethod(t *testing.T) { authority := testUUID + ".team-a.actors.resources.substrate.ate.dev:9090" clientMock := &mockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { - return &ateapipb.ResumeActorResponse{Actor: &ateapipb.Actor{Status: &ateapipb.ActorStatus{WorkerAssignment: &ateapipb.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.52"}}}}}, nil + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { + return &ateapi.ResumeActorResponse{Actor: &ateapi.Actor{Status: &ateapi.ActorStatus{WorkerAssignment: &ateapi.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.52"}}}}}, nil }, } h := New(clientMock, ParkedRequestConfig{}, nil) @@ -525,9 +525,9 @@ func TestHandleRequestHeadersHandlesConnectMethod(t *testing.T) { func TestHandleRequestHeadersUsesRetainedConnectAuthorityForPort(t *testing.T) { const testUUID = "123e4567-e89b-12d3-a456-426614174000" clientMock := &mockClient{ - resumeFn: func(context.Context, *ateapipb.ResumeActorRequest, ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { - return &ateapipb.ResumeActorResponse{Actor: &ateapipb.Actor{ - Status: &ateapipb.ActorStatus{WorkerAssignment: &ateapipb.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.52"}}}, + resumeFn: func(context.Context, *ateapi.ResumeActorRequest, ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { + return &ateapi.ResumeActorResponse{Actor: &ateapi.Actor{ + Status: &ateapi.ActorStatus{WorkerAssignment: &ateapi.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.52"}}}, }}, nil }, } @@ -675,11 +675,11 @@ func TestHandleRequestHeadersConnectRequiresOuterTargetActor(t *testing.T) { var gotActorRef string var resumeCalls int32 clientMock := &mockClient{ - resumeFn: func(_ context.Context, in *ateapipb.ResumeActorRequest, _ ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(_ context.Context, in *ateapi.ResumeActorRequest, _ ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { atomic.AddInt32(&resumeCalls, 1) gotActorRef = in.GetActor().GetAtespace() + "/" + in.GetActor().GetName() - return &ateapipb.ResumeActorResponse{Actor: &ateapipb.Actor{ - Status: &ateapipb.ActorStatus{WorkerAssignment: &ateapipb.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.52"}}}, + return &ateapi.ResumeActorResponse{Actor: &ateapi.Actor{ + Status: &ateapi.ActorStatus{WorkerAssignment: &ateapi.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.52"}}}, }}, nil }, } @@ -736,15 +736,15 @@ func TestHandleRequestHeaders_FullLotServesRunningActor(t *testing.T) { clientMock := &mockClient{ resumeFn: func( ctx context.Context, - in *ateapipb.ResumeActorRequest, + in *ateapi.ResumeActorRequest, opts ...grpc.CallOption, - ) (*ateapipb.ResumeActorResponse, error) { + ) (*ateapi.ResumeActorResponse, error) { resumeCalled = true - return &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{ - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.1"}}, + return &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{ + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{WorkerSpiffeId: testWorkerSPIFFEID, WorkerPodIps: []string{"10.0.0.1"}}, }, }, }, nil @@ -830,9 +830,9 @@ func TestHandleRequestHeaders_FullLotShedsParkedRequest(t *testing.T) { clientMock := &mockClient{ resumeFn: func( ctx context.Context, - in *ateapipb.ResumeActorRequest, + in *ateapi.ResumeActorRequest, opts ...grpc.CallOption, - ) (*ateapipb.ResumeActorResponse, error) { + ) (*ateapi.ResumeActorResponse, error) { resumeCalls.Add(1) return nil, tc.resumeErr }, diff --git a/cmd/atenet/internal/router/ingress/resumer.go b/cmd/atenet/internal/router/ingress/resumer.go index d522d3df1a..0ccbff2cea 100644 --- a/cmd/atenet/internal/router/ingress/resumer.go +++ b/cmd/atenet/internal/router/ingress/resumer.go @@ -21,10 +21,10 @@ import ( "sync/atomic" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/atenet/internal/router/extproc" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/trace" "google.golang.org/grpc/codes" @@ -77,7 +77,7 @@ const ( ) type resumeCallResult struct { - actor *ateapipb.Actor + actor *ateapi.Actor // resumed is true if ResumeActor call executed a cold activation // false if the actor was already running resumed bool @@ -90,7 +90,7 @@ type resumeCallResult struct { // ActorResumer coordinates safe, deduplicated resumption of actors. type ActorResumer struct { - apiClient ateapipb.ControlClient + apiClient ateapi.ControlClient // mu guards flights, the per-actor registry of in-flight resumes. mu sync.Mutex @@ -143,7 +143,7 @@ func withParkingLot(lot *parkingLot) resumerOption { return func(r *ActorResumer) { r.lot = lot } } -func NewActorResumer(apiClient ateapipb.ControlClient, opts ...resumerOption) *ActorResumer { +func NewActorResumer(apiClient ateapi.ControlClient, opts ...resumerOption) *ActorResumer { r := &ActorResumer{ apiClient: apiClient, flights: make(map[string]*resumeActorFlight), @@ -181,7 +181,7 @@ func (r *ActorResumer) retryable(err error) bool { // ResumeActor ensures the actor is running. // This method will block until the actor is resumed or error. -func (r *ActorResumer) ResumeActor(ctx context.Context, actorRef resources.ActorRef) (*ateapipb.Actor, ResumeOutcome, error) { +func (r *ActorResumer) ResumeActor(ctx context.Context, actorRef resources.ActorRef) (*ateapi.Actor, ResumeOutcome, error) { ctx, span := otel.Tracer(extproc.ServiceName).Start(ctx, "ResumeActor", trace.WithAttributes(ateattr.ActorRefAttributes(actorRef)...)) defer span.End() @@ -221,12 +221,12 @@ func (r *ActorResumer) runFlight(f *resumeActorFlight, key string, actorRef reso backoff := r.backoff - var resumeResp *ateapipb.ResumeActorResponse + var resumeResp *ateapi.ResumeActorResponse var lastRetryErr error err := wait.ExponentialBackoffWithContext(bgCtx, backoff, func(context.Context) (bool, error) { var err error - resumeResp, err = r.apiClient.ResumeActor(attemptCtx, &ateapipb.ResumeActorRequest{ + resumeResp, err = r.apiClient.ResumeActor(attemptCtx, &ateapi.ResumeActorRequest{ Actor: actorRef.ToObjectRef(), }) if err == nil { @@ -250,7 +250,7 @@ func (r *ActorResumer) runFlight(f *resumeActorFlight, key string, actorRef reso // flightResult classifies the retry loop's terminal state into the shared // result every caller attached to the flight receives. bgCtx is the flight's // budget context, consulted only for whether the budget expired. -func flightResult(bgCtx context.Context, resumeResp *ateapipb.ResumeActorResponse, err, lastRetryErr error, reqID uint64) *resumeCallResult { +func flightResult(bgCtx context.Context, resumeResp *ateapi.ResumeActorResponse, err, lastRetryErr error, reqID uint64) *resumeCallResult { result := &resumeCallResult{leaderID: reqID} switch { case err == nil: @@ -271,7 +271,7 @@ func flightResult(bgCtx context.Context, resumeResp *ateapipb.ResumeActorRespons // two-phase: while the flight is resolving the caller holds nothing; once the // flight is retrying (or already was), the caller must hold a parking-lot slot // to keep waiting and is shed with a 503 when the lot is full. -func (r *ActorResumer) awaitFlight(ctx context.Context, f *resumeActorFlight, actorRef resources.ActorRef, reqID uint64) (*ateapipb.Actor, ResumeOutcome, error) { +func (r *ActorResumer) awaitFlight(ctx context.Context, f *resumeActorFlight, actorRef resources.ActorRef, reqID uint64) (*ateapi.Actor, ResumeOutcome, error) { select { case <-ctx.Done(): // The caller's request context was canceled before the shared resume diff --git a/cmd/atenet/internal/router/ingress/resumer_test.go b/cmd/atenet/internal/router/ingress/resumer_test.go index 3579ddf4dd..c37a0f9254 100644 --- a/cmd/atenet/internal/router/ingress/resumer_test.go +++ b/cmd/atenet/internal/router/ingress/resumer_test.go @@ -25,10 +25,10 @@ import ( "time" envoy_type "github.com/envoyproxy/go-control-plane/envoy/type/v3" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/atenet/internal/router/extproc" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel/trace" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -36,11 +36,11 @@ import ( ) type resumerMockClient struct { - ateapipb.ControlClient - resumeFn func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) + ateapi.ControlClient + resumeFn func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) } -func (m *resumerMockClient) ResumeActor(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { +func (m *resumerMockClient) ResumeActor(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { if m.resumeFn != nil { return m.resumeFn(ctx, in, opts...) } @@ -57,11 +57,11 @@ func TestActorResumer_ResumeActor(t *testing.T) { t.Run("SuspendedResumedSuccessfully", func(t *testing.T) { var resumeCalled int mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { resumeCalled++ - return &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{ - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapipb.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}, + return &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{ + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapi.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}, }, Resumed: true, }, nil @@ -86,11 +86,11 @@ func TestActorResumer_ResumeActor(t *testing.T) { t.Run("WarmRouting_Disambiguation", func(t *testing.T) { mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { - return &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: testActorName}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapipb.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}, + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { + return &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: testActorName}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapi.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}, }, Resumed: false, }, nil @@ -110,14 +110,14 @@ func TestActorResumer_ResumeActor(t *testing.T) { t.Run("RetryOnAbortedConflict", func(t *testing.T) { var resumeCalled int mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { resumeCalled++ if resumeCalled < 3 { return nil, status.Error(codes.Aborted, "concurrent update conflict") } - return &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{ - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapipb.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}, + return &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{ + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapi.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}, }, Resumed: true, }, nil @@ -142,7 +142,7 @@ func TestActorResumer_ResumeActor(t *testing.T) { t.Run("ActorNotFound", func(t *testing.T) { mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { return nil, status.Error(codes.NotFound, "not found") }, } @@ -169,9 +169,9 @@ func TestActorResumer_ResumeActor(t *testing.T) { defer close(gate) mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { <-gate - return &ateapipb.ResumeActorResponse{Resumed: true}, nil + return &ateapi.ResumeActorResponse{Resumed: true}, nil }, } @@ -194,7 +194,7 @@ func TestActorResumer_ResumeActor(t *testing.T) { gate := make(chan struct{}) mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { resumeCalled.Add(1) <-gate return nil, status.Error(codes.ResourceExhausted, "no worker has room for the actor") @@ -242,14 +242,14 @@ func TestActorResumer_ResumeActor(t *testing.T) { var mu sync.Mutex mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { mu.Lock() resumeCalled++ mu.Unlock() time.Sleep(20 * time.Millisecond) - return &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{ - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapipb.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}, + return &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{ + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapi.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}, }, Resumed: true, }, nil @@ -260,7 +260,7 @@ func TestActorResumer_ResumeActor(t *testing.T) { var wg sync.WaitGroup const concurrentRequests = 10 - results := make([]*ateapipb.Actor, concurrentRequests) + results := make([]*ateapi.Actor, concurrentRequests) outcomes := make([]ResumeOutcome, concurrentRequests) errs := make([]error, concurrentRequests) @@ -321,7 +321,7 @@ func TestActorResumer_Parking(t *testing.T) { var mu sync.Mutex var calls int mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { mu.Lock() calls++ n := calls @@ -330,8 +330,8 @@ func TestActorResumer_Parking(t *testing.T) { // Worker pool momentarily saturated. return nil, status.Error(codes.FailedPrecondition, "no worker has room for the actor") } - return &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Name: testActorName}, Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapipb.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}}, + return &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Name: testActorName}, Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapi.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}}, }, nil }, } @@ -357,7 +357,7 @@ func TestActorResumer_Parking(t *testing.T) { var mu sync.Mutex var calls int mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { mu.Lock() calls++ mu.Unlock() @@ -391,7 +391,7 @@ func TestActorResumer_Parking(t *testing.T) { var mu sync.Mutex var calls int mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { mu.Lock() calls++ n := calls @@ -400,8 +400,8 @@ func TestActorResumer_Parking(t *testing.T) { // Control plane momentarily unreachable (e.g. rolling restart). return nil, status.Error(codes.Unavailable, "connection refused") } - return &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Name: testActorName}, Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapipb.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}}, + return &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Name: testActorName}, Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapi.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}}, }, nil }, } @@ -427,7 +427,7 @@ func TestActorResumer_Parking(t *testing.T) { var mu sync.Mutex var calls int mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { mu.Lock() calls++ mu.Unlock() @@ -462,7 +462,7 @@ func TestActorResumer_Parking(t *testing.T) { var ctxErrAtReturn error base := time.Now() mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { mu.Lock() calls++ n := calls @@ -477,8 +477,8 @@ func TestActorResumer_Parking(t *testing.T) { mu.Lock() ctxErrAtReturn = ctx.Err() mu.Unlock() - return &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Name: testActorName}, Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapipb.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}}, + return &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Name: testActorName}, Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapi.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}}, Resumed: true, }, nil }, @@ -519,7 +519,7 @@ func TestActorResumer_Parking(t *testing.T) { const budget = 300 * time.Millisecond var calls atomic.Int32 mock := &resumerMockClient{ - resumeFn: func(context.Context, *ateapipb.ResumeActorRequest, ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(context.Context, *ateapi.ResumeActorRequest, ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { if calls.Add(1) == 1 { return nil, status.Error(codes.ResourceExhausted, "no free workers available") } @@ -554,7 +554,7 @@ func TestActorResumer_Parking(t *testing.T) { var mu sync.Mutex var calls int mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { mu.Lock() calls++ mu.Unlock() @@ -585,7 +585,7 @@ func TestActorResumer_Parking(t *testing.T) { var mu sync.Mutex var calls int mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { mu.Lock() calls++ mu.Unlock() @@ -630,7 +630,7 @@ func testCallerCancelDoesNotAbortFlight(t *testing.T) { started := make(chan struct{}) proceed := make(chan struct{}) mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { mu.Lock() calls++ n := calls @@ -640,8 +640,8 @@ func testCallerCancelDoesNotAbortFlight(t *testing.T) { } // Hold the flight open until the test releases it. <-proceed - return &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Name: testActorName}, Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapipb.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}}, + return &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Name: testActorName}, Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapi.WorkerAssignment{WorkerPodIps: []string{expectedIP}}}}, }, nil }, } @@ -669,7 +669,7 @@ func testCallerCancelDoesNotAbortFlight(t *testing.T) { // Caller 2 arrives after caller 1 left; the flight is still in its first // RPC, so it must join that flight rather than start a new one. type result struct { - actor *ateapipb.Actor + actor *ateapi.Actor err error } resCh := make(chan result, 1) @@ -709,13 +709,13 @@ func TestActorResumer_LotAdmission(t *testing.T) { expectedIP = "10.0.0.99" ) testActorRef := resources.ActorRef{Atespace: testAtespace, Name: testActorName} - runningResp := func() *ateapipb.ResumeActorResponse { - return &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: testActorName}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{WorkerPodIps: []string{expectedIP}}, + runningResp := func() *ateapi.ResumeActorResponse { + return &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: testActorName}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{WorkerPodIps: []string{expectedIP}}, }, }, Resumed: true, @@ -727,9 +727,9 @@ func TestActorResumer_LotAdmission(t *testing.T) { mock := &resumerMockClient{ resumeFn: func( ctx context.Context, - in *ateapipb.ResumeActorRequest, + in *ateapi.ResumeActorRequest, opts ...grpc.CallOption, - ) (*ateapipb.ResumeActorResponse, error) { + ) (*ateapi.ResumeActorResponse, error) { return runningResp(), nil }, } @@ -766,9 +766,9 @@ func TestActorResumer_LotAdmission(t *testing.T) { mock := &resumerMockClient{ resumeFn: func( ctx context.Context, - in *ateapipb.ResumeActorRequest, + in *ateapi.ResumeActorRequest, opts ...grpc.CallOption, - ) (*ateapipb.ResumeActorResponse, error) { + ) (*ateapi.ResumeActorResponse, error) { mu.Lock() calls++ n := calls @@ -820,9 +820,9 @@ func TestActorResumer_LotAdmission(t *testing.T) { mock := &resumerMockClient{ resumeFn: func( ctx context.Context, - in *ateapipb.ResumeActorRequest, + in *ateapi.ResumeActorRequest, opts ...grpc.CallOption, - ) (*ateapipb.ResumeActorResponse, error) { + ) (*ateapi.ResumeActorResponse, error) { mu.Lock() calls++ mu.Unlock() @@ -863,9 +863,9 @@ func TestActorResumer_LotAdmission(t *testing.T) { mock := &resumerMockClient{ resumeFn: func( ctx context.Context, - in *ateapipb.ResumeActorRequest, + in *ateapi.ResumeActorRequest, opts ...grpc.CallOption, - ) (*ateapipb.ResumeActorResponse, error) { + ) (*ateapi.ResumeActorResponse, error) { mu.Lock() calls++ n := calls @@ -881,7 +881,7 @@ func TestActorResumer_LotAdmission(t *testing.T) { // The leader parks and takes the lot's only slot. type result struct { - actor *ateapipb.Actor + actor *ateapi.Actor outcome ResumeOutcome err error } @@ -929,9 +929,9 @@ func TestActorResumer_LotAdmission(t *testing.T) { mock := &resumerMockClient{ resumeFn: func( ctx context.Context, - in *ateapipb.ResumeActorRequest, + in *ateapi.ResumeActorRequest, opts ...grpc.CallOption, - ) (*ateapipb.ResumeActorResponse, error) { + ) (*ateapi.ResumeActorResponse, error) { return nil, status.Error(codes.ResourceExhausted, "no worker has room for the actor") }, } @@ -961,9 +961,9 @@ func TestActorResumer_LotAdmission(t *testing.T) { mock := &resumerMockClient{ resumeFn: func( ctx context.Context, - in *ateapipb.ResumeActorRequest, + in *ateapi.ResumeActorRequest, opts ...grpc.CallOption, - ) (*ateapipb.ResumeActorResponse, error) { + ) (*ateapi.ResumeActorResponse, error) { mu.Lock() calls++ n := calls @@ -1010,9 +1010,9 @@ func TestActorResumer_LotAdmission(t *testing.T) { mock := &resumerMockClient{ resumeFn: func( ctx context.Context, - in *ateapipb.ResumeActorRequest, + in *ateapi.ResumeActorRequest, opts ...grpc.CallOption, - ) (*ateapipb.ResumeActorResponse, error) { + ) (*ateapi.ResumeActorResponse, error) { mu.Lock() calls++ mu.Unlock() @@ -1066,10 +1066,10 @@ func TestActorResumer_FlightKeepsCallerTraceContext(t *testing.T) { var got trace.SpanContext mock := &resumerMockClient{ - resumeFn: func(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { + resumeFn: func(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { got = trace.SpanContextFromContext(ctx) - return &ateapipb.ResumeActorResponse{ - Actor: &ateapipb.Actor{Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapipb.WorkerAssignment{WorkerPodIps: []string{"10.0.0.1"}}}}, + return &ateapi.ResumeActorResponse{ + Actor: &ateapi.Actor{Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING, WorkerAssignment: &ateapi.WorkerAssignment{WorkerPodIps: []string{"10.0.0.1"}}}}, }, nil }, } diff --git a/cmd/atenet/internal/router/router.go b/cmd/atenet/internal/router/router.go index 73b5b24dfd..cd352ec377 100644 --- a/cmd/atenet/internal/router/router.go +++ b/cmd/atenet/internal/router/router.go @@ -35,6 +35,8 @@ import ( "k8s.io/client-go/tools/clientcmd" "sigs.k8s.io/controller-runtime/pkg/client/config" + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/api/credprovider/v1" "go.ate.dev/substrate/cmd/atenet/internal/router/egress" "go.ate.dev/substrate/cmd/atenet/internal/router/extproc" "go.ate.dev/substrate/cmd/atenet/internal/router/ingress" @@ -43,8 +45,6 @@ import ( "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/serverboot" "go.ate.dev/substrate/internal/version" - "go.ate.dev/substrate/pkg/proto/ateapipb" - "go.ate.dev/substrate/pkg/proto/credproviderpb" ) // dataPlaneTraceRatio is the default root sampling fraction for parentless @@ -57,7 +57,7 @@ type RouterServer struct { Cmd *cobra.Command clientset kubernetes.Interface - apiClient ateapipb.ControlClient + apiClient ateapi.ControlClient // extprocSrv is the ext_proc mux. Which handler it carries, ingress or // egress, follows cfg.Mode. extprocSrv *extproc.Server @@ -183,7 +183,7 @@ func (s *RouterServer) Run(ctx context.Context) error { return fmt.Errorf("failed to establish grpc channel to ateapi client: %w", err) } slog.InfoContext(ctx, "Connecting to ateapi", slog.String("address", s.cfg.AteapiAddr)) - s.apiClient = ateapipb.NewControlClient(conn) + s.apiClient = ateapi.NewControlClient(conn) slog.InfoContext(ctx, "Starting substrate router subsystem", slog.String("mode", string(s.cfg.Mode)), @@ -220,7 +220,7 @@ func (s *RouterServer) Run(ctx context.Context) error { // is set: dial the provider over mTLS and hand the client to the handler. // With no address the handler gets no provider, and a request matching // an injection-requiring rule is denied (see egress.applyEffects). - var provider credproviderpb.CredentialProviderClient + var provider credprovider.CredentialProviderClient var providerName string if s.cfg.CredentialProvider.Address != "" { providerName, err = egress.ProviderName(s.cfg.CredentialProvider.Name) @@ -238,7 +238,7 @@ func (s *RouterServer) Run(ctx context.Context) error { return fmt.Errorf("dial credential provider: %w", err) } defer providerConn.Close() - provider = credproviderpb.NewCredentialProviderClient(providerConn) + provider = credprovider.NewCredentialProviderClient(providerConn) slog.InfoContext(ctx, "egress credential injection enabled", slog.String("provider", s.cfg.CredentialProvider.Address), slog.String("provider_name", s.cfg.CredentialProvider.Name)) diff --git a/cmd/ateworker-gvisor/main.go b/cmd/ateworker-gvisor/main.go index edb36400b9..55136406fe 100644 --- a/cmd/ateworker-gvisor/main.go +++ b/cmd/ateworker-gvisor/main.go @@ -34,6 +34,7 @@ import ( "cloud.google.com/go/compute/metadata" "github.com/spf13/pflag" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/ateworker-gvisor/internal/cgroupstats" "go.ate.dev/substrate/internal/actorlock" "go.ate.dev/substrate/internal/actorlog" @@ -58,7 +59,6 @@ import ( "go.ate.dev/substrate/internal/version" "go.ate.dev/substrate/internal/wakeupprobe" "go.ate.dev/substrate/internal/workerstats" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "google.golang.org/grpc" "google.golang.org/grpc/reflection" @@ -289,7 +289,7 @@ func do(ctx context.Context) error { AteletSPIFFEID: tunnelConfig.BrokerIdentity, Actors: *maxActors, PodIPs: register.ParsePodIPs(*podIPs), - SandboxClass: string(atev1alpha1.SandboxClassGvisor), + SandboxClass: string(atev1.SandboxClassGvisor), RuntimesFile: nodepath.WorkerSandboxRuntimesPath(*podUID), } if reporter, err := register.NewCrashReporter(reportConfig); err != nil { @@ -682,6 +682,11 @@ func (s *AteWorkerService) RunWorkload(ctx context.Context, req *ateworkerpb.Run } } }() + // Egress is activated before the sandbox starts, ingress is activated after + // the wakeup probe (see tunnel.Tunnel.ActivateEgress). + if err := s.tunnel.ActivateEgress(attribution, egress); err != nil { + return nil, err + } containersToDelete = append(containersToDelete, ocispec.SandboxID) // Attribute the sandbox's runsc CLI output to the actor. pw, err := s.actorLogger.StartJSONLogPipe(attribution, ocispec.SandboxID) @@ -725,7 +730,7 @@ func (s *AteWorkerService) RunWorkload(ctx context.Context, req *ateworkerpb.Run if err := wakeupprobe.WaitAll(ctx, req.GetSpec().GetContainers(), actornet.ActorVethIP, wakeupprobe.DialFunc(s.sandboxDialer(req.GetActorUid()))); err != nil { return nil, fmt.Errorf("while waiting for container wakeup probe: %w", err) } - if err := s.tunnel.Activate(workerstats.ActorAttributionFromRequest(req), s.sandboxDialer(req.GetActorUid()), egress); err != nil { + if err := s.tunnel.ActivateIngress(attribution, s.sandboxDialer(req.GetActorUid())); err != nil { return nil, err } @@ -1099,6 +1104,11 @@ func (s *AteWorkerService) RestoreWorkload(ctx context.Context, req *ateworkerpb } } }() + err = s.tunnel.ActivateEgress(attribution, egress) + timing.activate = lap(&tLast) + if err != nil { + return nil, err + } checkpointDir := req.GetActorDirs().GetRestoreDir() restoreArgs, err := fsRestoreArgs(checkpointDir, fidelity) if err != nil { @@ -1185,8 +1195,8 @@ func (s *AteWorkerService) RestoreWorkload(ctx context.Context, req *ateworkerpb if err != nil { return nil, fmt.Errorf("while waiting for container wakeup probe: %w", err) } - err = s.tunnel.Activate(attribution, s.sandboxDialer(req.GetActorUid()), egress) - timing.activate = lap(&tLast) + err = s.tunnel.ActivateIngress(attribution, s.sandboxDialer(req.GetActorUid())) + timing.activate += lap(&tLast) if err != nil { return nil, err } diff --git a/cmd/ateworker-gvisor/phaselog.go b/cmd/ateworker-gvisor/phaselog.go index 1413099695..daa6abc6ea 100644 --- a/cmd/ateworker-gvisor/phaselog.go +++ b/cmd/ateworker-gvisor/phaselog.go @@ -57,7 +57,9 @@ const containerCountKey = "ate.actor.container.count" // restoreTiming is the elapsed time of each RestoreWorkload phase. A phase // left at zero never ran. Under VOLUMES and ROOTFS fidelity, sandboxRestore and -// appRestore time the cold start that stands in for the restore. +// appRestore time the cold start that stands in for the restore. activate is +// the total time spent activating the tunnel: egress is activated before the +// containers restore and ingress after the wakeup probe, and both are counted. type restoreTiming struct { prep, egressPrepare, netSetup time.Duration sandboxCreate, sandboxRestore time.Duration diff --git a/cmd/ateworker-gvisor/stats.go b/cmd/ateworker-gvisor/stats.go index d312cdd622..6ddd9bf49d 100644 --- a/cmd/ateworker-gvisor/stats.go +++ b/cmd/ateworker-gvisor/stats.go @@ -24,6 +24,7 @@ import ( "path/filepath" "time" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/ateworker-gvisor/internal/cgroupstats" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" @@ -31,7 +32,6 @@ import ( "go.ate.dev/substrate/internal/ocispec" "go.ate.dev/substrate/internal/proto/ateworkerpb" "go.ate.dev/substrate/internal/resources" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" ) // defaultCgroupRoot is the worker pod's own cgroup scope. The worker runs in a @@ -239,7 +239,7 @@ func pendingSample(active *resources.ActorAttribution) *ateworkerpb.WorkloadStat ActorTemplateAtespace: active.TemplateAtespace, ActorTemplateName: active.TemplateName, - SandboxClass: string(atev1alpha1.SandboxClassGvisor), + SandboxClass: string(atev1.SandboxClassGvisor), ObservedAtUnixNano: time.Now().UnixNano(), } @@ -282,7 +282,7 @@ func (s *AteWorkerService) sampleSandbox(active *resources.ActorAttribution) (*a ActorTemplateAtespace: active.TemplateAtespace, ActorTemplateName: active.TemplateName, - SandboxClass: string(atev1alpha1.SandboxClassGvisor), + SandboxClass: string(atev1.SandboxClassGvisor), Source: ateworkerpb.StatsSource_STATS_SOURCE_CGROUP, MemoryCurrentBytes: sample.MemoryCurrentBytes, diff --git a/cmd/ateworker-microvm/main.go b/cmd/ateworker-microvm/main.go index 4ca28c83a5..2e8cdc3830 100644 --- a/cmd/ateworker-microvm/main.go +++ b/cmd/ateworker-microvm/main.go @@ -38,6 +38,7 @@ import ( "cloud.google.com/go/compute/metadata" "github.com/spf13/pflag" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/actorlock" "go.ate.dev/substrate/internal/actorlog" "go.ate.dev/substrate/internal/apierror" @@ -55,7 +56,6 @@ import ( "go.ate.dev/substrate/internal/serverboot" "go.ate.dev/substrate/internal/version" "go.ate.dev/substrate/internal/workerstats" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "golang.org/x/sys/unix" "google.golang.org/grpc" @@ -288,7 +288,7 @@ func do(ctx context.Context) error { AteletSPIFFEID: tunnelConfig.BrokerIdentity, Actors: *maxActors, PodIPs: register.ParsePodIPs(*podIPs), - SandboxClass: string(atev1alpha1.SandboxClassMicroVM), + SandboxClass: string(atev1.SandboxClassMicroVM), RuntimesFile: nodepath.WorkerSandboxRuntimesPath(*podUID), } if reporter, err := register.NewCrashReporter(reportConfig); err != nil { diff --git a/cmd/ateworker-microvm/restore.go b/cmd/ateworker-microvm/restore.go index b65bb74f63..98a9b0e1c1 100644 --- a/cmd/ateworker-microvm/restore.go +++ b/cmd/ateworker-microvm/restore.go @@ -462,9 +462,18 @@ func (s *AteWorkerService) restoreMemoryFidelity(ctx context.Context, p actorBoo // and notifies the guest before unpausing the vCPUs, so a >=5.18 kernel reseeds its // CRNG on its own with no host round-trip, no per-restore RPC, and no post-Resume // race. At that point this agent-driven reseed can be dropped. + // + // Egress opens only once the reseed succeeds, so nothing leaves the host drawn + // from CRNG state the actor shares with the snapshot's other clones, and a + // failed reseed is still safe to retry (see restoreGuestReadyError). The + // restored workload is past its boot, so it needs egress only from the wakeup + // probe on. Ingress follows the wakeup probe, as in coldBootActor. if err := reseedGuestCRNG(ctx, guestAC); err != nil { return restoreGuestReadyError(ctx, "reseeding guest CRNG", err) } + if err := s.tunnel.ActivateEgress(p.attribution(), egress); err != nil { + return err + } tReseeded := time.Now() // Block until every wakeup-probe-enabled container reports 200. @@ -528,7 +537,7 @@ func (s *AteWorkerService) restoreMemoryFidelity(ctx context.Context, p actorBoo s.startActorLogForwarding(guestAC, attribution, c.id, c.name) } - if err := s.tunnel.Activate(p.attribution(), s.sandboxDialer(p.actorUID), egress); err != nil { + if err := s.tunnel.ActivateIngress(p.attribution(), s.sandboxDialer(p.actorUID)); err != nil { return err } s.setRunningVM(actorUID, ra) @@ -589,8 +598,9 @@ func (s *AteWorkerService) cleanupFailedRestoreRootfs(ctx context.Context, actor // the agent is dialed and the CRNG reseeded (up to about 15s plus // reseedTimeout). Nothing routes inbound traffic to it yet (not even the wakeup // probe), and atunnel's egress proxy closes its outbound TCP connections until -// tunnel.Activate, but a background task in the guest can query the DNS relay -// or write to its filesystems. The retry re-extracts the rootfs upper and +// tunnel.ActivateEgress, which restoreMemoryFidelity calls after the reseed for +// that reason, but a background task in the guest can query the DNS relay or +// write to its filesystems. The retry re-extracts the rootfs upper and // durable-dir volumes from the snapshot, whereas a CSI volume is outside the // snapshot and keeps any writes made during that window while guest memory and // its page cache resume from the snapshot; we accept that narrow window over diff --git a/cmd/ateworker-microvm/run.go b/cmd/ateworker-microvm/run.go index 4b23bbf7f4..926dcbfa83 100644 --- a/cmd/ateworker-microvm/run.go +++ b/cmd/ateworker-microvm/run.go @@ -445,6 +445,12 @@ func (s *AteWorkerService) coldBootActor(ctx context.Context, p actorBootParams) } }() + // Egress before the guest boots, ingress after the wakeup probe (see + // tunnel.Tunnel.ActivateEgress). + if err := s.tunnel.ActivateEgress(p.attribution(), egress); err != nil { + return err + } + kparams := s.kernelParams() // Size the VM to the actor's declared limits (see internal/sizing), which the @@ -608,7 +614,7 @@ func (s *AteWorkerService) coldBootActor(ctx context.Context, p actorBootParams) slog.Duration("since_boot", time.Since(tBooted))) ra := &runningActor{chProc: chProc, vfsdProc: vfsdProc, apiSocket: apiSocket, baseID: actorUID, guestAgent: ac, workloadIDs: workloadIDs(ctrs)} - if err := s.tunnel.Activate(p.attribution(), s.sandboxDialer(p.actorUID), egress); err != nil { + if err := s.tunnel.ActivateIngress(p.attribution(), s.sandboxDialer(p.actorUID)); err != nil { return err } s.setRunningVM(actorUID, ra) diff --git a/cmd/ateworker-microvm/stats.go b/cmd/ateworker-microvm/stats.go index eec4baf9dd..fb059acd5e 100644 --- a/cmd/ateworker-microvm/stats.go +++ b/cmd/ateworker-microvm/stats.go @@ -25,6 +25,7 @@ import ( "sync" "time" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/ateworker-microvm/internal/agentstats" "go.ate.dev/substrate/cmd/ateworker-microvm/internal/third_party/kata/agentpb" "go.ate.dev/substrate/internal/apierror" @@ -32,7 +33,6 @@ import ( "go.ate.dev/substrate/internal/ateworkervalidation" "go.ate.dev/substrate/internal/proto/ateworkerpb" "go.ate.dev/substrate/internal/resources" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" ) // statsCallTimeout bounds one container's guest-agent call. The RPC is polled @@ -310,7 +310,7 @@ func pendingSample(active *resources.ActorAttribution) *ateworkerpb.WorkloadStat ActorTemplateAtespace: active.TemplateAtespace, ActorTemplateName: active.TemplateName, - SandboxClass: string(atev1alpha1.SandboxClassMicroVM), + SandboxClass: string(atev1.SandboxClassMicroVM), ObservedAtUnixNano: time.Now().UnixNano(), } @@ -368,7 +368,7 @@ func (s *AteWorkerService) sampleGuest(ctx context.Context, h *hostedActor) (*at ActorTemplateAtespace: active.TemplateAtespace, ActorTemplateName: active.TemplateName, - SandboxClass: string(atev1alpha1.SandboxClassMicroVM), + SandboxClass: string(atev1.SandboxClassMicroVM), Source: ateworkerpb.StatsSource_STATS_SOURCE_GUEST_AGENT, MemoryCurrentBytes: sample.MemoryCurrentBytes, diff --git a/cmd/benchmarking/isolate/fake-atelet/herder.go b/cmd/benchmarking/isolate/fake-atelet/herder.go index 3a2293589b..425823b025 100644 --- a/cmd/benchmarking/isolate/fake-atelet/herder.go +++ b/cmd/benchmarking/isolate/fake-atelet/herder.go @@ -26,10 +26,10 @@ import ( "strings" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/objectstore" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/protobuf/proto" ) @@ -43,9 +43,9 @@ type objectWriter interface { PutObject(ctx context.Context, bucket, object string, reader io.Reader) error } -// actorCertMinter is the part of ateapipb.WorkerServiceClient the herder uses. +// actorCertMinter is the part of ateapi.WorkerServiceClient the herder uses. type actorCertMinter interface { - MintWorkerActorCertificate(ctx context.Context, in *ateapipb.MintWorkerActorCertificateRequest, opts ...grpc.CallOption) (*ateapipb.MintWorkerActorCertificateResponse, error) + MintWorkerActorCertificate(ctx context.Context, in *ateapi.MintWorkerActorCertificateRequest, opts ...grpc.CallOption) (*ateapi.MintWorkerActorCertificateResponse, error) } // delays is how long each Atelet call takes before it succeeds: the @@ -103,12 +103,12 @@ func (h *herder) mintActorCertificate(ctx context.Context, workerPodUID, atespac if h.minter == nil || gateway == nil { return nil } - if _, err := h.minter.MintWorkerActorCertificate(ctx, &ateapipb.MintWorkerActorCertificateRequest{ - Actor: &ateapipb.ObjectRef{Atespace: atespace, Name: name}, + if _, err := h.minter.MintWorkerActorCertificate(ctx, &ateapi.MintWorkerActorCertificateRequest{ + Actor: &ateapi.ObjectRef{Atespace: atespace, Name: name}, ActorUid: uid, CertificateSigningRequest: h.csr, // Workers are global-scoped and named by their pod UID. - Worker: &ateapipb.ObjectRef{Name: workerPodUID}, + Worker: &ateapi.ObjectRef{Name: workerPodUID}, }); err != nil { return fmt.Errorf("while minting the certificate of actor %s/%s: %w", atespace, name, err) } diff --git a/cmd/benchmarking/isolate/fake-atelet/herder_test.go b/cmd/benchmarking/isolate/fake-atelet/herder_test.go index 740c957891..f2d881b3c8 100644 --- a/cmd/benchmarking/isolate/fake-atelet/herder_test.go +++ b/cmd/benchmarking/isolate/fake-atelet/herder_test.go @@ -28,8 +28,8 @@ import ( "time" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/proto/ateletpb" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" @@ -318,12 +318,12 @@ func TestHerderWarnsOnlyWhenWriteOutlastsANonzeroDelay(t *testing.T) { // recordingMinter records every mint, as ate-api-server's WorkerService. type recordingMinter struct { mu sync.Mutex - reqs []*ateapipb.MintWorkerActorCertificateRequest + reqs []*ateapi.MintWorkerActorCertificateRequest err error delay time.Duration } -func (m *recordingMinter) MintWorkerActorCertificate(_ context.Context, in *ateapipb.MintWorkerActorCertificateRequest, _ ...grpc.CallOption) (*ateapipb.MintWorkerActorCertificateResponse, error) { +func (m *recordingMinter) MintWorkerActorCertificate(_ context.Context, in *ateapi.MintWorkerActorCertificateRequest, _ ...grpc.CallOption) (*ateapi.MintWorkerActorCertificateResponse, error) { if m.delay > 0 { time.Sleep(m.delay) } @@ -333,10 +333,10 @@ func (m *recordingMinter) MintWorkerActorCertificate(_ context.Context, in *atea if m.err != nil { return nil, m.err } - return &ateapipb.MintWorkerActorCertificateResponse{ActorCertificates: [][]byte{[]byte("leaf")}}, nil + return &ateapi.MintWorkerActorCertificateResponse{ActorCertificates: [][]byte{[]byte("leaf")}}, nil } -func (m *recordingMinter) mints() []*ateapipb.MintWorkerActorCertificateRequest { +func (m *recordingMinter) mints() []*ateapi.MintWorkerActorCertificateRequest { m.mu.Lock() defer m.mu.Unlock() return slices.Clone(m.reqs) @@ -386,12 +386,12 @@ func TestHerderMintsActorCertificateOnActivation(t *testing.T) { if len(got) != 1 { t.Fatalf("%s minted %d times, want once", name, len(got)) } - want := &ateapipb.ObjectRef{Atespace: "team-a", Name: "sleep-1"} + want := &ateapi.ObjectRef{Atespace: "team-a", Name: "sleep-1"} if !proto.Equal(got[0].GetActor(), want) || got[0].GetActorUid() != testActorUID { t.Errorf("%s minted for %v/%q, want %v/%q", name, got[0].GetActor(), got[0].GetActorUid(), want, testActorUID) } // The control plane mints only for the worker hosting the actor. - if got, want := got[0].GetWorker(), (&ateapipb.ObjectRef{Name: testWorkerPodUID}); !proto.Equal(got, want) { + if got, want := got[0].GetWorker(), (&ateapi.ObjectRef{Name: testWorkerPodUID}); !proto.Equal(got, want) { t.Errorf("%s minted as worker %v, want %v", name, got, want) } // ate-api-server parses the CSR and checks its signature. diff --git a/cmd/benchmarking/isolate/fake-atelet/main.go b/cmd/benchmarking/isolate/fake-atelet/main.go index 7199834ab6..449d9d8724 100644 --- a/cmd/benchmarking/isolate/fake-atelet/main.go +++ b/cmd/benchmarking/isolate/fake-atelet/main.go @@ -40,6 +40,7 @@ import ( "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/spf13/pflag" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/benchmarking/isolate/internal/fakeworker" "go.ate.dev/substrate/internal/ateapiauth" "go.ate.dev/substrate/internal/atelet" @@ -50,7 +51,6 @@ import ( "go.ate.dev/substrate/internal/serverboot" "go.ate.dev/substrate/internal/version" "go.ate.dev/substrate/pkg/objectstorage" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) @@ -132,7 +132,7 @@ func main() { if err != nil { serverboot.Fatal(ctx, "Failed to listen", err) } - workers := ateapipb.NewWorkerServiceClient(ateapiConn) + workers := ateapi.NewWorkerServiceClient(ateapiConn) epochs := newWorkerEpochs() h := &herder{delays: callDelays, storage: storage, epochs: epochs} if *mintActorCertificate { @@ -155,7 +155,7 @@ func main() { // Its own server and listener, so each port admits only its own caller: // ate-api-server on the herder's, fake-workersync on the relay's. relaySrv := grpc.NewServer(grpc.Creds(credentials.NewTLS(relayTLS))) - ateapipb.RegisterWorkerServiceServer(relaySrv, &relay{client: workers, epochs: epochs}) + ateapi.RegisterWorkerServiceServer(relaySrv, &relay{client: workers, epochs: epochs}) health := &http.Server{Addr: *healthListenAddr, Handler: healthHandler(), ReadHeaderTimeout: 10 * time.Second} slog.WarnContext(ctx, "Serving the fake atelet: actor lifecycle calls succeed without running any workload", diff --git a/cmd/benchmarking/isolate/fake-atelet/relay.go b/cmd/benchmarking/isolate/fake-atelet/relay.go index b15ee2d785..f8dbfd938a 100644 --- a/cmd/benchmarking/isolate/fake-atelet/relay.go +++ b/cmd/benchmarking/isolate/fake-atelet/relay.go @@ -19,16 +19,16 @@ import ( "crypto/tls" "log/slog" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/benchmarking/isolate/internal/fakeworker" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" ) -// capacityClient is the part of ateapipb.WorkerServiceClient the relay uses. +// capacityClient is the part of ateapi.WorkerServiceClient the relay uses. type capacityClient interface { - AcquireWorkerEpoch(ctx context.Context, in *ateapipb.AcquireWorkerEpochRequest, opts ...grpc.CallOption) (*ateapipb.AcquireWorkerEpochResponse, error) - RegisterWorker(ctx context.Context, in *ateapipb.RegisterWorkerRequest, opts ...grpc.CallOption) (*ateapipb.RegisterWorkerResponse, error) - SetWorkerSandboxRuntimes(ctx context.Context, in *ateapipb.SetWorkerSandboxRuntimesRequest, opts ...grpc.CallOption) (*ateapipb.SetWorkerSandboxRuntimesResponse, error) + AcquireWorkerEpoch(ctx context.Context, in *ateapi.AcquireWorkerEpochRequest, opts ...grpc.CallOption) (*ateapi.AcquireWorkerEpochResponse, error) + RegisterWorker(ctx context.Context, in *ateapi.RegisterWorkerRequest, opts ...grpc.CallOption) (*ateapi.RegisterWorkerResponse, error) + SetWorkerSandboxRuntimes(ctx context.Context, in *ateapi.SetWorkerSandboxRuntimesRequest, opts ...grpc.CallOption) (*ateapi.SetWorkerSandboxRuntimesResponse, error) } // relay forwards fake-workersync's capacity reports to ate-api-server under @@ -41,14 +41,14 @@ type capacityClient interface { // It serves WorkerService so the request and ate-api-server's status pass // through unchanged; every other WorkerService call is Unimplemented. type relay struct { - ateapipb.UnimplementedWorkerServiceServer + ateapi.UnimplementedWorkerServiceServer client capacityClient // epochs records the epoch of each registration ate-api-server accepts. epochs *workerEpochs } -func (r *relay) AcquireWorkerEpoch(ctx context.Context, in *ateapipb.AcquireWorkerEpochRequest) (*ateapipb.AcquireWorkerEpochResponse, error) { +func (r *relay) AcquireWorkerEpoch(ctx context.Context, in *ateapi.AcquireWorkerEpochRequest) (*ateapi.AcquireWorkerEpochResponse, error) { resp, err := r.client.AcquireWorkerEpoch(ctx, in) if err != nil { slog.WarnContext(ctx, "Epoch acquire rejected", @@ -58,7 +58,7 @@ func (r *relay) AcquireWorkerEpoch(ctx context.Context, in *ateapipb.AcquireWork return resp, nil } -func (r *relay) SetWorkerSandboxRuntimes(ctx context.Context, in *ateapipb.SetWorkerSandboxRuntimesRequest) (*ateapipb.SetWorkerSandboxRuntimesResponse, error) { +func (r *relay) SetWorkerSandboxRuntimes(ctx context.Context, in *ateapi.SetWorkerSandboxRuntimesRequest) (*ateapi.SetWorkerSandboxRuntimesResponse, error) { resp, err := r.client.SetWorkerSandboxRuntimes(ctx, in) if err != nil { slog.WarnContext(ctx, "Sandbox runtimes report rejected", @@ -68,7 +68,7 @@ func (r *relay) SetWorkerSandboxRuntimes(ctx context.Context, in *ateapipb.SetWo return resp, nil } -func (r *relay) RegisterWorker(ctx context.Context, in *ateapipb.RegisterWorkerRequest) (*ateapipb.RegisterWorkerResponse, error) { +func (r *relay) RegisterWorker(ctx context.Context, in *ateapi.RegisterWorkerRequest) (*ateapi.RegisterWorkerResponse, error) { resp, err := r.client.RegisterWorker(ctx, in) if err != nil { slog.WarnContext(ctx, "Capacity report rejected", diff --git a/cmd/benchmarking/isolate/fake-atelet/relay_test.go b/cmd/benchmarking/isolate/fake-atelet/relay_test.go index b9c0850303..ae02e8df83 100644 --- a/cmd/benchmarking/isolate/fake-atelet/relay_test.go +++ b/cmd/benchmarking/isolate/fake-atelet/relay_test.go @@ -21,9 +21,9 @@ import ( "strings" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/benchmarking/isolate/internal/fakeworker/fakeworkertest" "go.ate.dev/substrate/internal/credbundle" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -34,45 +34,45 @@ import ( // recordingWorkerService records the last request of each kind and answers // with err. type recordingWorkerService struct { - got *ateapipb.RegisterWorkerRequest - acquireGot *ateapipb.AcquireWorkerEpochRequest - runtimesGot *ateapipb.SetWorkerSandboxRuntimesRequest + got *ateapi.RegisterWorkerRequest + acquireGot *ateapi.AcquireWorkerEpochRequest + runtimesGot *ateapi.SetWorkerSandboxRuntimesRequest err error } -func (f *recordingWorkerService) AcquireWorkerEpoch(_ context.Context, in *ateapipb.AcquireWorkerEpochRequest, _ ...grpc.CallOption) (*ateapipb.AcquireWorkerEpochResponse, error) { +func (f *recordingWorkerService) AcquireWorkerEpoch(_ context.Context, in *ateapi.AcquireWorkerEpochRequest, _ ...grpc.CallOption) (*ateapi.AcquireWorkerEpochResponse, error) { f.acquireGot = in if f.err != nil { return nil, f.err } - return &ateapipb.AcquireWorkerEpochResponse{Epoch: 4}, nil + return &ateapi.AcquireWorkerEpochResponse{Epoch: 4}, nil } -func (f *recordingWorkerService) RegisterWorker(_ context.Context, in *ateapipb.RegisterWorkerRequest, _ ...grpc.CallOption) (*ateapipb.RegisterWorkerResponse, error) { +func (f *recordingWorkerService) RegisterWorker(_ context.Context, in *ateapi.RegisterWorkerRequest, _ ...grpc.CallOption) (*ateapi.RegisterWorkerResponse, error) { f.got = in if f.err != nil { return nil, f.err } - return &ateapipb.RegisterWorkerResponse{}, nil + return &ateapi.RegisterWorkerResponse{}, nil } -func (f *recordingWorkerService) SetWorkerSandboxRuntimes(_ context.Context, in *ateapipb.SetWorkerSandboxRuntimesRequest, _ ...grpc.CallOption) (*ateapipb.SetWorkerSandboxRuntimesResponse, error) { +func (f *recordingWorkerService) SetWorkerSandboxRuntimes(_ context.Context, in *ateapi.SetWorkerSandboxRuntimesRequest, _ ...grpc.CallOption) (*ateapi.SetWorkerSandboxRuntimesResponse, error) { f.runtimesGot = in if f.err != nil { return nil, f.err } - return &ateapipb.SetWorkerSandboxRuntimesResponse{}, nil + return &ateapi.SetWorkerSandboxRuntimesResponse{}, nil } -func runtimesReport() *ateapipb.SetWorkerSandboxRuntimesRequest { - return &ateapipb.SetWorkerSandboxRuntimesRequest{ - Worker: &ateapipb.ObjectRef{Name: "fake-r1-c52b9bd3-0"}, +func runtimesReport() *ateapi.SetWorkerSandboxRuntimesRequest { + return &ateapi.SetWorkerSandboxRuntimesRequest{ + Worker: &ateapi.ObjectRef{Name: "fake-r1-c52b9bd3-0"}, Epoch: 4, - SandboxClasses: []*ateapipb.WorkerSandboxClass{{ + SandboxClasses: []*ateapi.WorkerSandboxClass{{ SandboxClass: "gvisor", - DefaultRuntime: &ateapipb.WorkerSandboxRuntime{Version: &ateapipb.VersionedSandboxCompat{ + DefaultRuntime: &ateapi.WorkerSandboxRuntime{Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{{Key: "architecture", Value: "amd64"}}, + Attributes: []*ateapi.AttributeEntry{{Key: "architecture", Value: "amd64"}}, }}, }}, } @@ -80,7 +80,7 @@ func runtimesReport() *ateapipb.SetWorkerSandboxRuntimesRequest { func TestRelayForwardsTheAcquireUnchanged(t *testing.T) { svc := &recordingWorkerService{} - in := &ateapipb.AcquireWorkerEpochRequest{Worker: &ateapipb.ObjectRef{Name: "fake-r1-c52b9bd3-0"}} + in := &ateapi.AcquireWorkerEpochRequest{Worker: &ateapi.ObjectRef{Name: "fake-r1-c52b9bd3-0"}} resp, err := (&relay{client: svc}).AcquireWorkerEpoch(context.Background(), in) if err != nil { t.Fatalf("AcquireWorkerEpoch: %v", err) @@ -103,10 +103,10 @@ func TestRelayForwardsTheRuntimesUnchanged(t *testing.T) { } } -func report() *ateapipb.RegisterWorkerRequest { - return &ateapipb.RegisterWorkerRequest{ - Worker: &ateapipb.ObjectRef{Name: "fake-r1-c52b9bd3-0"}, - Capacity: &ateapipb.WorkerResources{ +func report() *ateapi.RegisterWorkerRequest { + return &ateapi.RegisterWorkerRequest{ + Worker: &ateapi.ObjectRef{Name: "fake-r1-c52b9bd3-0"}, + Capacity: &ateapi.WorkerResources{ Actors: 1000, CpuMillicores: 64000, MemoryBytes: 256 << 30, }, @@ -152,7 +152,7 @@ func TestRelayRecordsTheRegisteredEpoch(t *testing.T) { func TestRelayPassesThroughAteAPIServersStatus(t *testing.T) { calls := map[string]func(*relay) error{ "AcquireWorkerEpoch": func(r *relay) error { - _, err := r.AcquireWorkerEpoch(context.Background(), &ateapipb.AcquireWorkerEpochRequest{}) + _, err := r.AcquireWorkerEpoch(context.Background(), &ateapi.AcquireWorkerEpochRequest{}) return err }, "RegisterWorker": func(r *relay) error { @@ -182,7 +182,7 @@ func TestRelayPassesThroughAteAPIServersStatus(t *testing.T) { // nothing but capacity reports: a minted actor certificate, say, would hand // fake-workersync an identity it does not hold. func TestRelayServesOnlyCapacityReports(t *testing.T) { - _, err := (&relay{client: &recordingWorkerService{}}).MintWorkerActorCertificate(context.Background(), &ateapipb.MintWorkerActorCertificateRequest{}) + _, err := (&relay{client: &recordingWorkerService{}}).MintWorkerActorCertificate(context.Background(), &ateapi.MintWorkerActorCertificateRequest{}) if got := status.Code(err); got != codes.Unimplemented { t.Errorf("MintWorkerActorCertificate code = %v, want Unimplemented", got) } @@ -202,7 +202,7 @@ func TestRelayTLSAdmitsOnlyTheAllowedID(t *testing.T) { t.Fatal(err) } srv := grpc.NewServer(grpc.Creds(credentials.NewTLS(serverCfg))) - ateapipb.RegisterWorkerServiceServer(srv, &relay{client: &recordingWorkerService{}}) + ateapi.RegisterWorkerServiceServer(srv, &relay{client: &recordingWorkerService{}}) go func() { _ = srv.Serve(lis) }() defer srv.Stop() @@ -215,7 +215,7 @@ func TestRelayTLSAdmitsOnlyTheAllowedID(t *testing.T) { t.Fatal(err) } defer conn.Close() - _, err = ateapipb.NewWorkerServiceClient(conn).RegisterWorker(context.Background(), report()) + _, err = ateapi.NewWorkerServiceClient(conn).RegisterWorker(context.Background(), report()) return err } if err := call(ca.Issue(t, allowed)); err != nil { @@ -244,7 +244,7 @@ func TestRelayTLSFollowsATrustBundleRotation(t *testing.T) { t.Fatal(err) } srv := grpc.NewServer(grpc.Creds(credentials.NewTLS(serverCfg))) - ateapipb.RegisterWorkerServiceServer(srv, &relay{client: &recordingWorkerService{}}) + ateapi.RegisterWorkerServiceServer(srv, &relay{client: &recordingWorkerService{}}) go func() { _ = srv.Serve(lis) }() defer srv.Stop() @@ -258,7 +258,7 @@ func TestRelayTLSFollowsATrustBundleRotation(t *testing.T) { t.Fatal(err) } defer conn.Close() - if _, err := ateapipb.NewWorkerServiceClient(conn).RegisterWorker(context.Background(), report()); err != nil { + if _, err := ateapi.NewWorkerServiceClient(conn).RegisterWorker(context.Background(), report()); err != nil { t.Errorf("a certificate from the rotated-in CA was refused: %v", err) } } diff --git a/cmd/benchmarking/isolate/fake-workersync/controller.go b/cmd/benchmarking/isolate/fake-workersync/controller.go index 7e81e2ecc4..596ec60e60 100644 --- a/cmd/benchmarking/isolate/fake-workersync/controller.go +++ b/cmd/benchmarking/isolate/fake-workersync/controller.go @@ -28,10 +28,10 @@ import ( "time" "github.com/google/uuid" + "go.ate.dev/substrate/api/ateapi/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/benchmarking/isolate/internal/fakeworker" "go.ate.dev/substrate/internal/hardware" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" - "go.ate.dev/substrate/pkg/proto/ateapipb" "golang.org/x/sync/errgroup" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -42,16 +42,16 @@ import ( "k8s.io/apimachinery/pkg/labels" ) -// workerClient is the part of ateapipb.ControlClient the controller uses. +// workerClient is the part of ateapi.ControlClient the controller uses. type workerClient interface { - CreateWorker(ctx context.Context, in *ateapipb.CreateWorkerRequest, opts ...grpc.CallOption) (*ateapipb.Worker, error) - DeleteWorker(ctx context.Context, in *ateapipb.DeleteWorkerRequest, opts ...grpc.CallOption) (*ateapipb.Worker, error) - DrainWorker(ctx context.Context, in *ateapipb.DrainWorkerRequest, opts ...grpc.CallOption) (*ateapipb.DrainWorkerResponse, error) - MarkWorkerAvailable(ctx context.Context, in *ateapipb.MarkWorkerAvailableRequest, opts ...grpc.CallOption) (*ateapipb.MarkWorkerAvailableResponse, error) - GetWorker(ctx context.Context, in *ateapipb.GetWorkerRequest, opts ...grpc.CallOption) (*ateapipb.Worker, error) - UpdateWorker(ctx context.Context, in *ateapipb.UpdateWorkerRequest, opts ...grpc.CallOption) (*ateapipb.Worker, error) - ListWorkers(ctx context.Context, in *ateapipb.ListWorkersRequest, opts ...grpc.CallOption) (*ateapipb.ListWorkersResponse, error) - ListWorkerActorAssignments(ctx context.Context, in *ateapipb.ListWorkerActorAssignmentsRequest, opts ...grpc.CallOption) (*ateapipb.ListWorkerActorAssignmentsResponse, error) + CreateWorker(ctx context.Context, in *ateapi.CreateWorkerRequest, opts ...grpc.CallOption) (*ateapi.Worker, error) + DeleteWorker(ctx context.Context, in *ateapi.DeleteWorkerRequest, opts ...grpc.CallOption) (*ateapi.Worker, error) + DrainWorker(ctx context.Context, in *ateapi.DrainWorkerRequest, opts ...grpc.CallOption) (*ateapi.DrainWorkerResponse, error) + MarkWorkerAvailable(ctx context.Context, in *ateapi.MarkWorkerAvailableRequest, opts ...grpc.CallOption) (*ateapi.MarkWorkerAvailableResponse, error) + GetWorker(ctx context.Context, in *ateapi.GetWorkerRequest, opts ...grpc.CallOption) (*ateapi.Worker, error) + UpdateWorker(ctx context.Context, in *ateapi.UpdateWorkerRequest, opts ...grpc.CallOption) (*ateapi.Worker, error) + ListWorkers(ctx context.Context, in *ateapi.ListWorkersRequest, opts ...grpc.CallOption) (*ateapi.ListWorkersResponse, error) + ListWorkerActorAssignments(ctx context.Context, in *ateapi.ListWorkerActorAssignmentsRequest, opts ...grpc.CallOption) (*ateapi.ListWorkerActorAssignmentsResponse, error) } // workerReport is what a fake worker process registers and reports. @@ -62,8 +62,8 @@ type workerReport struct { // epoch, which would make ate-api-server crash every Actor on the Worker. Epoch int64 IPs []string - Capacity *ateapipb.WorkerResources - SandboxClasses []*ateapipb.WorkerSandboxClass + Capacity *ateapi.WorkerResources + SandboxClasses []*ateapi.WorkerSandboxClass } // capacityRelay registers a fake worker process through the fake-atelet relay @@ -83,13 +83,13 @@ type node struct { // cluster is what the controller reads from and writes to Kubernetes. type cluster interface { // Pools returns every WorkerPool. - Pools() ([]*atev1alpha1.WorkerPool, error) + Pools() ([]*atev1.WorkerPool, error) // Nodes returns the nodes that run a fake-atelet pod, sorted by name. Nodes(ctx context.Context) ([]node, error) // Relays returns the fake-atelet relay address on each node that has one. Relays(ctx context.Context) (map[string]string, error) // UpdateStatus writes a WorkerPool's status. - UpdateStatus(ctx context.Context, wp *atev1alpha1.WorkerPool) error + UpdateStatus(ctx context.Context, wp *atev1.WorkerPool) error } // fakeWorker is a fake Worker the controller has registered. @@ -116,7 +116,7 @@ type fakeWorker struct { tmpl *template // capacity is fixed when the Worker is made, as worker reads its limits // once at startup; reported is whether ate-api-server has accepted it. - capacity *ateapipb.WorkerResources + capacity *ateapi.WorkerResources reported bool draining bool // drainedAt is when the controller drained the Worker, or adopted it @@ -198,7 +198,7 @@ func (c *controller) adopt(ctx context.Context) error { prefix := fakeworker.Prefix(c.run) var token string for { - page, err := c.client.ListWorkers(ctx, &ateapipb.ListWorkersRequest{Options: &ateapipb.ListOptions{PageSize: 1000, PageToken: token}}) + page, err := c.client.ListWorkers(ctx, &ateapi.ListWorkersRequest{Options: &ateapi.ListOptions{PageSize: 1000, PageToken: token}}) if err != nil { return fmt.Errorf("while listing Workers: %w", err) } @@ -226,8 +226,8 @@ func (c *controller) adopt(ctx context.Context) error { reported: len(w.GetStatus().GetSandboxClasses()) > 0, // One never marked available goes back through create, which // marks it. - created: w.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE, - draining: w.GetStatus().GetState() == ateapipb.WorkerState_WORKER_STATE_DRAINING, + created: w.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_UNAVAILABLE, + draining: w.GetStatus().GetState() == ateapi.WorkerState_WORKER_STATE_DRAINING, } if c.workers[name].draining { // When it was drained is not recorded, so its grace restarts. @@ -244,7 +244,7 @@ func (c *controller) adopt(ctx context.Context) error { // desiredWorker is a fake Worker some WorkerPool wants. type desiredWorker struct { - pool *atev1alpha1.WorkerPool + pool *atev1.WorkerPool index int } @@ -429,7 +429,7 @@ func (c *controller) ensure(ctx context.Context, pod string, d desiredWorker, w if addr == "" { return fmt.Errorf("no fake-atelet on node %s yet for Worker %s", w.node, name) } - current, err := c.client.GetWorker(ctx, &ateapipb.GetWorkerRequest{Worker: &ateapipb.ObjectRef{Name: name}}) + current, err := c.client.GetWorker(ctx, &ateapi.GetWorkerRequest{Worker: &ateapi.ObjectRef{Name: name}}) if err != nil { return fmt.Errorf("while reading Worker %s: %w", name, err) } @@ -445,9 +445,9 @@ func (c *controller) ensure(ctx context.Context, pod string, d desiredWorker, w Epoch: epoch, IPs: ips, Capacity: fixed, - SandboxClasses: []*ateapipb.WorkerSandboxClass{{ + SandboxClasses: []*ateapi.WorkerSandboxClass{{ SandboxClass: string(d.pool.Spec.DefaultSandboxClass()), - DefaultRuntime: &ateapipb.WorkerSandboxRuntime{Version: hostCompat()}, + DefaultRuntime: &ateapi.WorkerSandboxRuntime{Version: hostCompat()}, }}, }); err != nil { return fmt.Errorf("while reporting capacity for Worker %s: %w", name, err) @@ -458,11 +458,11 @@ func (c *controller) ensure(ctx context.Context, pod string, d desiredWorker, w return nil } -func hostCompat() *ateapipb.VersionedSandboxCompat { +func hostCompat() *ateapi.VersionedSandboxCompat { in := hardware.ProbeHost() - out := &ateapipb.VersionedSandboxCompat{SchemaVersion: in.GetSchemaVersion()} + out := &ateapi.VersionedSandboxCompat{SchemaVersion: in.GetSchemaVersion()} for _, a := range in.GetAttributes() { - out.Attributes = append(out.Attributes, &ateapipb.AttributeEntry{Key: a.GetKey(), Value: a.GetValue()}) + out.Attributes = append(out.Attributes, &ateapi.AttributeEntry{Key: a.GetKey(), Value: a.GetValue()}) } return out } @@ -470,10 +470,10 @@ func hostCompat() *ateapipb.VersionedSandboxCompat { // create registers the Worker with the fields the worker syncer would copy // from the pool and its pod, then marks it available as the syncer does once // the pod is Ready. -func (c *controller) create(ctx context.Context, w *fakeWorker, wp *atev1alpha1.WorkerPool) error { +func (c *controller) create(ctx context.Context, w *fakeWorker, wp *atev1.WorkerPool) error { name := w.name - _, err := c.client.CreateWorker(ctx, &ateapipb.CreateWorkerRequest{Worker: &ateapipb.Worker{ - Metadata: &ateapipb.ResourceMetadata{Name: name}, + _, err := c.client.CreateWorker(ctx, &ateapi.CreateWorkerRequest{Worker: &ateapi.Worker{ + Metadata: &ateapi.ResourceMetadata{Name: name}, WorkerNamespace: wp.Namespace, WorkerPool: wp.Name, WorkerPod: w.pod, @@ -484,7 +484,7 @@ func (c *controller) create(ctx context.Context, w *fakeWorker, wp *atev1alpha1. if err != nil && status.Code(err) != codes.AlreadyExists { return fmt.Errorf("while creating Worker %s: %w", name, err) } - if _, err := c.client.MarkWorkerAvailable(ctx, &ateapipb.MarkWorkerAvailableRequest{Worker: &ateapipb.ObjectRef{Name: name}}); err != nil { + if _, err := c.client.MarkWorkerAvailable(ctx, &ateapi.MarkWorkerAvailableRequest{Worker: &ateapi.ObjectRef{Name: name}}); err != nil { return fmt.Errorf("while marking Worker %s available: %w", name, err) } return nil @@ -496,13 +496,13 @@ func (c *controller) create(ctx context.Context, w *fakeWorker, wp *atev1alpha1. // the Worker is read first; a conflicting write fails the call and the next // pass retries it. func (c *controller) updateLabels(ctx context.Context, name string, w *fakeWorker, want map[string]string) error { - got, err := c.client.GetWorker(ctx, &ateapipb.GetWorkerRequest{Worker: &ateapipb.ObjectRef{Name: name}}) + got, err := c.client.GetWorker(ctx, &ateapi.GetWorkerRequest{Worker: &ateapi.ObjectRef{Name: name}}) if err != nil { return fmt.Errorf("while reading Worker %s: %w", name, err) } if !maps.Equal(got.GetLabels(), want) { got.Labels = maps.Clone(want) - if _, err := c.client.UpdateWorker(ctx, &ateapipb.UpdateWorkerRequest{Worker: got}); err != nil { + if _, err := c.client.UpdateWorker(ctx, &ateapi.UpdateWorkerRequest{Worker: got}); err != nil { return fmt.Errorf("while updating Worker %s labels: %w", name, err) } } @@ -523,9 +523,9 @@ func (c *controller) retire(ctx context.Context, name string) error { c.mu.Lock() w := c.workers[name] c.mu.Unlock() - ref := &ateapipb.ObjectRef{Name: name} + ref := &ateapi.ObjectRef{Name: name} if !w.draining { - if _, err := c.client.DrainWorker(ctx, &ateapipb.DrainWorkerRequest{Worker: ref}); err != nil { + if _, err := c.client.DrainWorker(ctx, &ateapi.DrainWorkerRequest{Worker: ref}); err != nil { if status.Code(err) == codes.NotFound { c.forget(name) return nil @@ -537,7 +537,7 @@ func (c *controller) retire(ctx context.Context, name string) error { w.drainedAt = c.now() c.mu.Unlock() } - assigned, err := c.client.ListWorkerActorAssignments(ctx, &ateapipb.ListWorkerActorAssignmentsRequest{Worker: ref, Options: &ateapipb.ListOptions{PageSize: 1}}) + assigned, err := c.client.ListWorkerActorAssignments(ctx, &ateapi.ListWorkerActorAssignmentsRequest{Worker: ref, Options: &ateapi.ListOptions{PageSize: 1}}) if err != nil { if status.Code(err) == codes.NotFound { c.forget(name) @@ -548,7 +548,7 @@ func (c *controller) retire(ctx context.Context, name string) error { if len(assigned.GetActorAssignments()) > 0 && c.now().Sub(w.drainedAt) < c.drainGrace { return nil } - if _, err := c.client.DeleteWorker(ctx, &ateapipb.DeleteWorkerRequest{Worker: ref}); err != nil && status.Code(err) != codes.NotFound { + if _, err := c.client.DeleteWorker(ctx, &ateapi.DeleteWorkerRequest{Worker: ref}); err != nil && status.Code(err) != codes.NotFound { return fmt.Errorf("while deleting Worker %s: %w", name, err) } c.forget(name) @@ -564,8 +564,8 @@ func (c *controller) forget(name string) { // syncStatus writes the pool's status as the WorkerPool controller does from // its Deployment: a replica is a registered Worker, ready once its capacity // is reported, and the selector is the one worker pods would carry. -func (c *controller) syncStatus(ctx context.Context, wp *atev1alpha1.WorkerPool, onFakeAteletNode func(*fakeWorker) bool, allocatable map[string]corev1.ResourceList) error { - want := atev1alpha1.WorkerPoolStatus{ +func (c *controller) syncStatus(ctx context.Context, wp *atev1.WorkerPool, onFakeAteletNode func(*fakeWorker) bool, allocatable map[string]corev1.ResourceList) error { + want := atev1.WorkerPoolStatus{ Selector: labels.SelectorFromSet(labels.Set{fakeworker.WorkerPoolLabel: wp.Name}).String(), } c.mu.Lock() @@ -604,7 +604,7 @@ func (c *controller) deleteAll(ctx context.Context) error { errs := make([]error, len(names)) for i, name := range names { g.Go(func() error { - _, err := c.client.DeleteWorker(ctx, &ateapipb.DeleteWorkerRequest{Worker: &ateapipb.ObjectRef{Name: name}}) + _, err := c.client.DeleteWorker(ctx, &ateapi.DeleteWorkerRequest{Worker: &ateapi.ObjectRef{Name: name}}) if err != nil && status.Code(err) != codes.NotFound { errs[i] = fmt.Errorf("while deleting Worker %s: %w", name, err) return nil @@ -632,7 +632,7 @@ type template struct { // templateOf reads wp's template; it fails only on a bad max-actors // annotation. -func templateOf(wp *atev1alpha1.WorkerPool) (template, error) { +func templateOf(wp *atev1.WorkerPool) (template, error) { actors, err := maxActors(wp) if err != nil { return template{}, err @@ -650,7 +650,7 @@ func templateOf(wp *atev1alpha1.WorkerPool) (template, error) { // cpu and memory from its limits, or, with no limit set, the node's // allocatable, which is what the downward API projects into worker for an // unset limit. -func (t template) capacity(allocatable corev1.ResourceList) *ateapipb.WorkerResources { +func (t template) capacity(allocatable corev1.ResourceList) *ateapi.WorkerResources { cpu, memory := t.cpuMilli, t.memoryBytes if cpu == 0 { cpu = allocatable.Cpu().MilliValue() @@ -658,7 +658,7 @@ func (t template) capacity(allocatable corev1.ResourceList) *ateapipb.WorkerReso if memory == 0 { memory = allocatable.Memory().Value() } - return &ateapipb.WorkerResources{Actors: int32(t.actors), CpuMillicores: cpu, MemoryBytes: memory} + return &ateapi.WorkerResources{Actors: int32(t.actors), CpuMillicores: cpu, MemoryBytes: memory} } // fits reports whether w was made from wp's current template, so a real pool @@ -667,7 +667,7 @@ func (t template) capacity(allocatable corev1.ResourceList) *ateapipb.WorkerReso // its node now; one whose node's allocatable changed while fake-workersync was // down is replaced too. A held pool's Workers fit, since they are left as they // are. -func fits(w *fakeWorker, wp *atev1alpha1.WorkerPool, allocatable map[string]corev1.ResourceList) bool { +func fits(w *fakeWorker, wp *atev1.WorkerPool, allocatable map[string]corev1.ResourceList) bool { t, err := templateOf(wp) if err != nil { return true @@ -684,7 +684,7 @@ func fits(w *fakeWorker, wp *atev1alpha1.WorkerPool, allocatable map[string]core // maxActors is the pool's actor capacity per Worker: worker's default, unless // the pool's annotation overrides it. -func maxActors(wp *atev1alpha1.WorkerPool) (int, error) { +func maxActors(wp *atev1.WorkerPool) (int, error) { v, ok := wp.Annotations[fakeworker.MaxActorsAnnotation] if !ok { return fakeworker.DefaultMaxActors, nil diff --git a/cmd/benchmarking/isolate/fake-workersync/controller_test.go b/cmd/benchmarking/isolate/fake-workersync/controller_test.go index e0008fe6fa..03c7177cdf 100644 --- a/cmd/benchmarking/isolate/fake-workersync/controller_test.go +++ b/cmd/benchmarking/isolate/fake-workersync/controller_test.go @@ -25,10 +25,10 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/benchmarking/isolate/internal/fakeworker" "go.ate.dev/substrate/internal/hardware" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -46,7 +46,7 @@ const ( // fakeControl is an in-memory Worker registry. type fakeControl struct { mu sync.Mutex - workers map[string]*ateapipb.Worker + workers map[string]*ateapi.Worker assignments map[string]int // actors assigned, by Worker name creates int updates int @@ -65,10 +65,10 @@ type fakeControl struct { } func newFakeControl() *fakeControl { - return &fakeControl{workers: map[string]*ateapipb.Worker{}, assignments: map[string]int{}} + return &fakeControl{workers: map[string]*ateapi.Worker{}, assignments: map[string]int{}} } -func (f *fakeControl) CreateWorker(_ context.Context, in *ateapipb.CreateWorkerRequest, _ ...grpc.CallOption) (*ateapipb.Worker, error) { +func (f *fakeControl) CreateWorker(_ context.Context, in *ateapi.CreateWorkerRequest, _ ...grpc.CallOption) (*ateapi.Worker, error) { f.mu.Lock() defer f.mu.Unlock() f.creates++ @@ -79,7 +79,7 @@ func (f *fakeControl) CreateWorker(_ context.Context, in *ateapipb.CreateWorkerR w := proto.CloneOf(in.GetWorker()) // Like ate-api-server: a Worker takes no Actors until it is marked // available. - w.Status = &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE} + w.Status = &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_UNAVAILABLE} f.workers[name] = w if f.lostReply != nil { return nil, f.lostReply @@ -87,7 +87,7 @@ func (f *fakeControl) CreateWorker(_ context.Context, in *ateapipb.CreateWorkerR return w, nil } -func (f *fakeControl) MarkWorkerAvailable(_ context.Context, in *ateapipb.MarkWorkerAvailableRequest, _ ...grpc.CallOption) (*ateapipb.MarkWorkerAvailableResponse, error) { +func (f *fakeControl) MarkWorkerAvailable(_ context.Context, in *ateapi.MarkWorkerAvailableRequest, _ ...grpc.CallOption) (*ateapi.MarkWorkerAvailableResponse, error) { f.mu.Lock() defer f.mu.Unlock() if f.markErr != nil { @@ -97,23 +97,23 @@ func (f *fakeControl) MarkWorkerAvailable(_ context.Context, in *ateapipb.MarkWo if !ok { return nil, status.Error(codes.NotFound, "no such Worker") } - if w.Status.State == ateapipb.WorkerState_WORKER_STATE_DRAINING { + if w.Status.State == ateapi.WorkerState_WORKER_STATE_DRAINING { return nil, status.Error(codes.FailedPrecondition, "Worker is draining") } - w.Status.State = ateapipb.WorkerState_WORKER_STATE_ACTIVE - return &ateapipb.MarkWorkerAvailableResponse{Worker: proto.CloneOf(w)}, nil + w.Status.State = ateapi.WorkerState_WORKER_STATE_ACTIVE + return &ateapi.MarkWorkerAvailableResponse{Worker: proto.CloneOf(w)}, nil } // state returns the state of the Worker registered for pod, as worker picks // it. -func (f *fakeControl) state(pod string) ateapipb.WorkerState { +func (f *fakeControl) state(pod string) ateapi.WorkerState { w := f.worker(pod) f.mu.Lock() defer f.mu.Unlock() return w.GetStatus().GetState() } -func (f *fakeControl) DeleteWorker(_ context.Context, in *ateapipb.DeleteWorkerRequest, _ ...grpc.CallOption) (*ateapipb.Worker, error) { +func (f *fakeControl) DeleteWorker(_ context.Context, in *ateapi.DeleteWorkerRequest, _ ...grpc.CallOption) (*ateapi.Worker, error) { f.mu.Lock() defer f.mu.Unlock() name := in.GetWorker().GetName() @@ -127,7 +127,7 @@ func (f *fakeControl) DeleteWorker(_ context.Context, in *ateapipb.DeleteWorkerR return w, nil } -func (f *fakeControl) DrainWorker(_ context.Context, in *ateapipb.DrainWorkerRequest, _ ...grpc.CallOption) (*ateapipb.DrainWorkerResponse, error) { +func (f *fakeControl) DrainWorker(_ context.Context, in *ateapi.DrainWorkerRequest, _ ...grpc.CallOption) (*ateapi.DrainWorkerResponse, error) { f.mu.Lock() defer f.mu.Unlock() if f.drainErr != nil { @@ -137,11 +137,11 @@ func (f *fakeControl) DrainWorker(_ context.Context, in *ateapipb.DrainWorkerReq if !ok { return nil, status.Error(codes.NotFound, "no such Worker") } - w.Status.State = ateapipb.WorkerState_WORKER_STATE_DRAINING - return &ateapipb.DrainWorkerResponse{Worker: w}, nil + w.Status.State = ateapi.WorkerState_WORKER_STATE_DRAINING + return &ateapi.DrainWorkerResponse{Worker: w}, nil } -func (f *fakeControl) GetWorker(_ context.Context, in *ateapipb.GetWorkerRequest, _ ...grpc.CallOption) (*ateapipb.Worker, error) { +func (f *fakeControl) GetWorker(_ context.Context, in *ateapi.GetWorkerRequest, _ ...grpc.CallOption) (*ateapi.Worker, error) { f.mu.Lock() defer f.mu.Unlock() w, ok := f.workers[in.GetWorker().GetName()] @@ -153,7 +153,7 @@ func (f *fakeControl) GetWorker(_ context.Context, in *ateapipb.GetWorkerRequest // UpdateWorker allows only the labels to change, as ate-api-server's // immutable-field validation does for the fields the controller sets. -func (f *fakeControl) UpdateWorker(_ context.Context, in *ateapipb.UpdateWorkerRequest, _ ...grpc.CallOption) (*ateapipb.Worker, error) { +func (f *fakeControl) UpdateWorker(_ context.Context, in *ateapi.UpdateWorkerRequest, _ ...grpc.CallOption) (*ateapi.Worker, error) { f.mu.Lock() defer f.mu.Unlock() f.updates++ @@ -172,7 +172,7 @@ func (f *fakeControl) UpdateWorker(_ context.Context, in *ateapipb.UpdateWorkerR return w, nil } -func (f *fakeControl) ListWorkers(_ context.Context, _ *ateapipb.ListWorkersRequest, _ ...grpc.CallOption) (*ateapipb.ListWorkersResponse, error) { +func (f *fakeControl) ListWorkers(_ context.Context, _ *ateapi.ListWorkersRequest, _ ...grpc.CallOption) (*ateapi.ListWorkersResponse, error) { f.mu.Lock() defer f.mu.Unlock() if f.listFailures > 0 { @@ -182,19 +182,19 @@ func (f *fakeControl) ListWorkers(_ context.Context, _ *ateapipb.ListWorkersRequ } return nil, status.Error(codes.Unavailable, "no ready endpoints") } - return &ateapipb.ListWorkersResponse{Workers: slices.Collect(maps.Values(f.workers))}, nil + return &ateapi.ListWorkersResponse{Workers: slices.Collect(maps.Values(f.workers))}, nil } -func (f *fakeControl) ListWorkerActorAssignments(_ context.Context, in *ateapipb.ListWorkerActorAssignmentsRequest, _ ...grpc.CallOption) (*ateapipb.ListWorkerActorAssignmentsResponse, error) { +func (f *fakeControl) ListWorkerActorAssignments(_ context.Context, in *ateapi.ListWorkerActorAssignmentsRequest, _ ...grpc.CallOption) (*ateapi.ListWorkerActorAssignmentsResponse, error) { f.mu.Lock() defer f.mu.Unlock() name := in.GetWorker().GetName() if _, ok := f.workers[name]; !ok { return nil, status.Error(codes.NotFound, "no such Worker") } - resp := &ateapipb.ListWorkerActorAssignmentsResponse{} + resp := &ateapi.ListWorkerActorAssignmentsResponse{} for range f.assignments[name] { - resp.ActorAssignments = append(resp.ActorAssignments, &ateapipb.ActorAssignment{}) + resp.ActorAssignments = append(resp.ActorAssignments, &ateapi.ActorAssignment{}) } return resp, nil } @@ -214,15 +214,15 @@ func (f *fakeControl) names() []string { // worker returns the Worker registered for pod: the one not draining, if // there is one. -func (f *fakeControl) worker(pod string) *ateapipb.Worker { +func (f *fakeControl) worker(pod string) *ateapi.Worker { f.mu.Lock() defer f.mu.Unlock() - var found *ateapipb.Worker + var found *ateapi.Worker for _, w := range f.workers { if w.GetWorkerPod() != pod { continue } - if found == nil || w.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_DRAINING { + if found == nil || w.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_DRAINING { found = w } } @@ -230,18 +230,18 @@ func (f *fakeControl) worker(pod string) *ateapipb.Worker { } // all returns every registered Worker. -func (f *fakeControl) all() []*ateapipb.Worker { +func (f *fakeControl) all() []*ateapi.Worker { f.mu.Lock() defer f.mu.Unlock() return slices.Collect(maps.Values(f.workers)) } // draining returns the draining Worker registered for pod, if any. -func (f *fakeControl) draining(pod string) *ateapipb.Worker { +func (f *fakeControl) draining(pod string) *ateapi.Worker { f.mu.Lock() defer f.mu.Unlock() for _, w := range f.workers { - if w.GetWorkerPod() == pod && w.GetStatus().GetState() == ateapipb.WorkerState_WORKER_STATE_DRAINING { + if w.GetWorkerPod() == pod && w.GetStatus().GetState() == ateapi.WorkerState_WORKER_STATE_DRAINING { return w } } @@ -261,12 +261,12 @@ func (f *fakeControl) uid(pod string) string { type fakeRelay struct { control *fakeControl mu sync.Mutex - reported map[string]*ateapipb.WorkerResources // by Worker name - classes map[string][]*ateapipb.WorkerSandboxClass // sandbox classes, by Worker name - via map[string]string // relay address, by Worker name - ips map[string][]string // by Worker name - epochs map[string]int64 // registered epoch, by Worker name - acquired map[string]int // epochs acquired, by Worker name + reported map[string]*ateapi.WorkerResources // by Worker name + classes map[string][]*ateapi.WorkerSandboxClass // sandbox classes, by Worker name + via map[string]string // relay address, by Worker name + ips map[string][]string // by Worker name + epochs map[string]int64 // registered epoch, by Worker name + acquired map[string]int // epochs acquired, by Worker name reject map[string]codes.Code calls int live map[string]string // as last pruned to @@ -274,8 +274,8 @@ type fakeRelay struct { func newFakeRelay() *fakeRelay { return &fakeRelay{ - reported: map[string]*ateapipb.WorkerResources{}, - classes: map[string][]*ateapipb.WorkerSandboxClass{}, + reported: map[string]*ateapi.WorkerResources{}, + classes: map[string][]*ateapi.WorkerSandboxClass{}, via: map[string]string{}, ips: map[string][]string{}, epochs: map[string]int64{}, @@ -322,14 +322,14 @@ func (f *fakeRelay) Prune(live map[string]string) { // fakeCluster is the controller's Kubernetes, in memory. type fakeCluster struct { mu sync.Mutex - pools []*atev1alpha1.WorkerPool + pools []*atev1.WorkerPool nodes []node relays map[string]string - statuses map[string]atev1alpha1.WorkerPoolStatus // by pool name + statuses map[string]atev1.WorkerPoolStatus // by pool name updates int } -func (f *fakeCluster) Pools() ([]*atev1alpha1.WorkerPool, error) { +func (f *fakeCluster) Pools() ([]*atev1.WorkerPool, error) { f.mu.Lock() defer f.mu.Unlock() return slices.Clone(f.pools), nil @@ -343,12 +343,12 @@ func (f *fakeCluster) Relays(context.Context) (map[string]string, error) { return maps.Clone(f.relays), nil } -func (f *fakeCluster) UpdateStatus(_ context.Context, wp *atev1alpha1.WorkerPool) error { +func (f *fakeCluster) UpdateStatus(_ context.Context, wp *atev1.WorkerPool) error { f.mu.Lock() defer f.mu.Unlock() f.updates++ if f.statuses == nil { - f.statuses = map[string]atev1alpha1.WorkerPoolStatus{} + f.statuses = map[string]atev1.WorkerPoolStatus{} } f.statuses[wp.Name] = wp.Status // Like the API server: the next List returns the written status. @@ -361,7 +361,7 @@ func (f *fakeCluster) UpdateStatus(_ context.Context, wp *atev1alpha1.WorkerPool } // editPool replaces the named pool with a copy edit has changed. -func (f *fakeCluster) editPool(name string, edit func(*atev1alpha1.WorkerPool)) { +func (f *fakeCluster) editPool(name string, edit func(*atev1.WorkerPool)) { f.mu.Lock() defer f.mu.Unlock() for i, p := range f.pools { @@ -385,13 +385,13 @@ func (f *fakeCluster) setReplicas(pool string, n int32) { } } -func pool(name string, replicas int32, limits corev1.ResourceList) *atev1alpha1.WorkerPool { - wp := &atev1alpha1.WorkerPool{ +func pool(name string, replicas int32, limits corev1.ResourceList) *atev1.WorkerPool { + wp := &atev1.WorkerPool{ ObjectMeta: metav1.ObjectMeta{Namespace: "benchmark-workloads", Name: name, Labels: map[string]string{"workload": name}}, - Spec: atev1alpha1.WorkerPoolSpec{Replicas: replicas, SandboxClasses: []atev1alpha1.WorkerPoolSandboxClass{{Name: atev1alpha1.SandboxClassGvisor}}}, + Spec: atev1.WorkerPoolSpec{Replicas: replicas, SandboxClasses: []atev1.WorkerPoolSandboxClass{{Name: atev1.SandboxClassGvisor}}}, } if limits != nil { - wp.Spec.Template = &atev1alpha1.WorkerPoolPodTemplate{Resources: &corev1.ResourceRequirements{Limits: limits}} + wp.Spec.Template = &atev1.WorkerPoolPodTemplate{Resources: &corev1.ResourceRequirements{Limits: limits}} } return wp } @@ -403,7 +403,7 @@ func testNodes() []node { return []node{{name: "node-a", allocatable: alloc("86", "160Gi")}, {name: "node-b", allocatable: alloc("44", "80Gi")}} } -func newTestController(pools ...*atev1alpha1.WorkerPool) (*controller, *fakeControl, *fakeRelay, *fakeCluster) { +func newTestController(pools ...*atev1.WorkerPool) (*controller, *fakeControl, *fakeRelay, *fakeCluster) { ctl, rel := newFakeControl(), newFakeRelay() rel.control = ctl cl := &fakeCluster{pools: pools, nodes: testNodes(), relays: map[string]string{"node-a": "10.0.0.1:8086", "node-b": "10.0.0.2:8086"}} @@ -435,9 +435,9 @@ func poolNames(name string, n int) []string { return out } -func wantCapacity(actors int32, cpu, mem string) *ateapipb.WorkerResources { +func wantCapacity(actors int32, cpu, mem string) *ateapi.WorkerResources { c, m := resource.MustParse(cpu), resource.MustParse(mem) - return &ateapipb.WorkerResources{Actors: actors, CpuMillicores: c.MilliValue(), MemoryBytes: m.Value()} + return &ateapi.WorkerResources{Actors: actors, CpuMillicores: c.MilliValue(), MemoryBytes: m.Value()} } func TestReconcileHonorsReplicasAndLimits(t *testing.T) { @@ -479,11 +479,11 @@ func TestReconcileHonorsReplicasAndLimits(t *testing.T) { if got, want := rel.reported[ctl.uid(name)], wantCapacity(1000, "1500m", "4Gi"); !proto.Equal(got, want) { t.Errorf("reported %v, want %v from the pool's limits", got, want) } - wantClass := &ateapipb.WorkerSandboxClass{SandboxClass: "gvisor", DefaultRuntime: &ateapipb.WorkerSandboxRuntime{Version: hostCompat()}} + wantClass := &ateapi.WorkerSandboxClass{SandboxClass: "gvisor", DefaultRuntime: &ateapi.WorkerSandboxRuntime{Version: hostCompat()}} if got := rel.classes[ctl.uid(name)]; len(got) != 1 || !proto.Equal(got[0], wantClass) { t.Errorf("sandbox classes %v, want one, %v: the pool's class on this host, which ate-api-server requires", got, wantClass) } - if got, want := cl.statuses["bench"], (atev1alpha1.WorkerPoolStatus{Replicas: 3, ReadyReplicas: 3, Selector: "ate.dev/worker-pool=bench"}); !reflect.DeepEqual(got, want) { + if got, want := cl.statuses["bench"], (atev1.WorkerPoolStatus{Replicas: 3, ReadyReplicas: 3, Selector: "ate.dev/worker-pool=bench"}); !reflect.DeepEqual(got, want) { t.Errorf("status = %+v, want %+v", got, want) } } @@ -680,7 +680,7 @@ func TestPoolLimitsChangeReplacesWorkers(t *testing.T) { ctl.assignments[old] = 1 reports := rel.calls - cl.editPool("bench", func(wp *atev1alpha1.WorkerPool) { + cl.editPool("bench", func(wp *atev1.WorkerPool) { wp.Spec.Template.Resources.Limits = corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("4"), corev1.ResourceMemory: resource.MustParse("8Gi")} }) if err := reconcile(t, c); err != nil { @@ -715,7 +715,7 @@ func TestMaxActorsAnnotationChangeReplacesWorkers(t *testing.T) { } pod := fakeworker.Name(testRun, "benchmark-workloads", "bench", 0) old := ctl.uid(pod) - cl.editPool("bench", func(wp *atev1alpha1.WorkerPool) { + cl.editPool("bench", func(wp *atev1.WorkerPool) { wp.Annotations = map[string]string{fakeworker.MaxActorsAnnotation: "5"} }) if err := reconcile(t, c); err != nil { @@ -771,7 +771,7 @@ func TestScaleDownDrainsThenDeletes(t *testing.T) { if slices.Contains(ctl.names(), idle) { t.Errorf("idle Worker %s not deleted", idle) } - if w := ctl.worker(busy); w == nil || w.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_DRAINING { + if w := ctl.worker(busy); w == nil || w.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_DRAINING { t.Fatalf("busy Worker %s = %v, want kept and draining", busy, w) } if got := cl.statuses["bench"]; got.Replicas != 2 || got.ReadyReplicas != 2 { @@ -840,7 +840,7 @@ func TestScaleDownThenUpReplacesTheDrainingWorker(t *testing.T) { if err := reconcile(t, c); err != nil { t.Fatalf("scale-up reconcile: %v", err) } - if w := ctl.worker(busy); w.GetMetadata().GetName() == old || w.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_ACTIVE { + if w := ctl.worker(busy); w.GetMetadata().GetName() == old || w.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_ACTIVE { t.Errorf("Worker for %s = %s/%v, want a new active one", busy, w.GetMetadata().GetName(), w.GetStatus().GetState()) } if got := cl.statuses["bench"]; got.Replicas != 2 || got.ReadyReplicas != 2 { @@ -904,8 +904,8 @@ func TestReconcileMarksWorkersAvailable(t *testing.T) { t.Fatalf("reconcile: %v", err) } for _, name := range poolNames("bench", 2) { - if got := ctl.state(name); got != ateapipb.WorkerState_WORKER_STATE_ACTIVE { - t.Errorf("Worker %s state = %v, want %v", name, got, ateapipb.WorkerState_WORKER_STATE_ACTIVE) + if got := ctl.state(name); got != ateapi.WorkerState_WORKER_STATE_ACTIVE { + t.Errorf("Worker %s state = %v, want %v", name, got, ateapi.WorkerState_WORKER_STATE_ACTIVE) } } } @@ -919,8 +919,8 @@ func TestUnmarkedWorkerIsMarkedByTheNextPass(t *testing.T) { t.Fatal("reconcile succeeded with every mark failing") } name := poolNames("bench", 1)[0] - if got := ctl.state(name); got != ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE { - t.Fatalf("Worker %s state = %v after a failed mark, want %v", name, got, ateapipb.WorkerState_WORKER_STATE_UNAVAILABLE) + if got := ctl.state(name); got != ateapi.WorkerState_WORKER_STATE_UNAVAILABLE { + t.Fatalf("Worker %s state = %v after a failed mark, want %v", name, got, ateapi.WorkerState_WORKER_STATE_UNAVAILABLE) } ctl.markErr = nil @@ -931,8 +931,8 @@ func TestUnmarkedWorkerIsMarkedByTheNextPass(t *testing.T) { if err := reconcile(t, restarted); err != nil { t.Fatalf("reconcile after restart: %v", err) } - if got := ctl.state(name); got != ateapipb.WorkerState_WORKER_STATE_ACTIVE { - t.Errorf("Worker %s state = %v after restart, want %v", name, got, ateapipb.WorkerState_WORKER_STATE_ACTIVE) + if got := ctl.state(name); got != ateapi.WorkerState_WORKER_STATE_ACTIVE { + t.Errorf("Worker %s state = %v after restart, want %v", name, got, ateapi.WorkerState_WORKER_STATE_ACTIVE) } if got, want := ctl.names(), poolNames("bench", 1); !slices.Equal(got, want) { t.Errorf("registered %v, want %v: the adopted Worker, not a replacement", got, want) @@ -947,7 +947,7 @@ func TestPoolLabelChangeUpdatesWorkers(t *testing.T) { t.Fatalf("reconcile: %v", err) } relabel := func(v string) { - cl.editPool("bench", func(wp *atev1alpha1.WorkerPool) { wp.Labels = map[string]string{"workload": v} }) + cl.editPool("bench", func(wp *atev1.WorkerPool) { wp.Labels = map[string]string{"workload": v} }) } relabel("v2") @@ -994,15 +994,15 @@ func TestPoolSandboxClassChangeReplacesWorkers(t *testing.T) { oldBusy := ctl.uid(busy) ctl.assignments[oldBusy] = 1 - cl.editPool("bench", func(wp *atev1alpha1.WorkerPool) { - wp.Spec.SandboxClasses = []atev1alpha1.WorkerPoolSandboxClass{{Name: atev1alpha1.SandboxClassMicroVM}} + cl.editPool("bench", func(wp *atev1.WorkerPool) { + wp.Spec.SandboxClasses = []atev1.WorkerPoolSandboxClass{{Name: atev1.SandboxClassMicroVM}} }) if err := reconcile(t, c); err != nil { t.Fatalf("reconcile after the class change: %v", err) } for _, pod := range []string{idle, busy} { w := ctl.worker(pod) - if hardware.SandboxClass(w.GetStatus()) != "microvm" || w.GetStatus().GetState() != ateapipb.WorkerState_WORKER_STATE_ACTIVE { + if hardware.SandboxClass(w.GetStatus()) != "microvm" || w.GetStatus().GetState() != ateapi.WorkerState_WORKER_STATE_ACTIVE { t.Errorf("Worker for %s = %q/%v, want microvm and active", pod, hardware.SandboxClass(w.GetStatus()), w.GetStatus().GetState()) } if w.GetWorkerPodUid() != w.GetMetadata().GetName() { @@ -1035,14 +1035,14 @@ func TestFailedDrainOfAReplacedWorkerIsNoReplica(t *testing.T) { pod := fakeworker.Name(testRun, "benchmark-workloads", "bench", 0) old := ctl.worker(pod) ctl.drainErr = status.Error(codes.Unavailable, "connection reset") - cl.editPool("bench", func(wp *atev1alpha1.WorkerPool) { - wp.Spec.SandboxClasses = []atev1alpha1.WorkerPoolSandboxClass{{Name: atev1alpha1.SandboxClassMicroVM}} + cl.editPool("bench", func(wp *atev1.WorkerPool) { + wp.Spec.SandboxClasses = []atev1.WorkerPoolSandboxClass{{Name: atev1.SandboxClassMicroVM}} wp.Labels = map[string]string{"workload": "v2"} }) if err := reconcile(t, c); err == nil { t.Error("reconcile succeeded with a failed drain") } - var replacement *ateapipb.Worker + var replacement *ateapi.Worker for _, w := range ctl.all() { if hardware.SandboxClass(w.GetStatus()) == "microvm" { replacement = w @@ -1087,8 +1087,8 @@ func TestAdoptAfterRestart(t *testing.T) { if err := reconcile(t, c); err != nil { t.Fatalf("reconcile: %v", err) } - real := &ateapipb.Worker{Metadata: &ateapipb.ResourceMetadata{Name: "0c4f6c2e-real-pod-uid"}, WorkerNamespace: "benchmark-workloads", WorkerPool: "bench", WorkerPod: "bench-7d9f8c-x2x4k", Status: &ateapipb.WorkerStatus{}} - otherRun := &ateapipb.Worker{Metadata: &ateapipb.ResourceMetadata{Name: "9a1e0d3b-other-run"}, WorkerNamespace: "benchmark-workloads", WorkerPool: "bench", WorkerPod: fakeworker.Name("r2", "benchmark-workloads", "bench", 0), Status: &ateapipb.WorkerStatus{}} + real := &ateapi.Worker{Metadata: &ateapi.ResourceMetadata{Name: "0c4f6c2e-real-pod-uid"}, WorkerNamespace: "benchmark-workloads", WorkerPool: "bench", WorkerPod: "bench-7d9f8c-x2x4k", Status: &ateapi.WorkerStatus{}} + otherRun := &ateapi.Worker{Metadata: &ateapi.ResourceMetadata{Name: "9a1e0d3b-other-run"}, WorkerNamespace: "benchmark-workloads", WorkerPool: "bench", WorkerPod: fakeworker.Name("r2", "benchmark-workloads", "bench", 0), Status: &ateapi.WorkerStatus{}} ctl.workers[real.Metadata.Name] = real ctl.workers[otherRun.Metadata.Name] = otherRun @@ -1174,7 +1174,7 @@ func TestAdoptReplacesWorkersOfAPoolEditedWhileDown(t *testing.T) { } pod := fakeworker.Name(testRun, "benchmark-workloads", "bench", 0) old := ctl.uid(pod) - cl.editPool("bench", func(wp *atev1alpha1.WorkerPool) { + cl.editPool("bench", func(wp *atev1.WorkerPool) { wp.Spec.Template.Resources.Limits = corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("4"), corev1.ResourceMemory: resource.MustParse("8Gi")} }) @@ -1232,7 +1232,7 @@ func TestReportReusesTheRegisteredEpoch(t *testing.T) { tests := []struct { name string ip string - capacity *ateapipb.WorkerResources + capacity *ateapi.WorkerResources wantAcquired int wantEpoch int64 }{ @@ -1284,7 +1284,7 @@ func TestDeleteAll(t *testing.T) { } func TestCapacityFormatsLikeWorker(t *testing.T) { - capacity := func(wp *atev1alpha1.WorkerPool) *ateapipb.WorkerResources { + capacity := func(wp *atev1.WorkerPool) *ateapi.WorkerResources { t.Helper() tmpl, err := templateOf(wp) if err != nil { diff --git a/cmd/benchmarking/isolate/fake-workersync/main.go b/cmd/benchmarking/isolate/fake-workersync/main.go index 3601144610..659fa15cd8 100644 --- a/cmd/benchmarking/isolate/fake-workersync/main.go +++ b/cmd/benchmarking/isolate/fake-workersync/main.go @@ -45,16 +45,16 @@ import ( "time" "github.com/spf13/pflag" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/cmd/benchmarking/isolate/internal/fakeworker" "go.ate.dev/substrate/internal/benchmarking/boomer/boomerutil" "go.ate.dev/substrate/internal/installdefaults" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/serverboot" "go.ate.dev/substrate/internal/version" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" "go.ate.dev/substrate/pkg/client/clientset/versioned" ateinformers "go.ate.dev/substrate/pkg/client/informers/externalversions" - atelisters "go.ate.dev/substrate/pkg/client/listers/api/v1alpha1" + atelisters "go.ate.dev/substrate/pkg/client/listers/ate/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -134,7 +134,7 @@ func main() { defer relay.Close() factory := ateinformers.NewSharedInformerFactory(ac, 0) - poolInformer := factory.Api().V1alpha1().WorkerPools() + poolInformer := factory.Ate().V1().WorkerPools() changed := make(chan struct{}, 1) notify := func(any) { select { @@ -243,7 +243,7 @@ type kubeCluster struct { seen map[string]time.Time } -func (k *kubeCluster) Pools() ([]*atev1alpha1.WorkerPool, error) { +func (k *kubeCluster) Pools() ([]*atev1.WorkerPool, error) { return k.pools.List(labels.Everything()) } @@ -318,7 +318,7 @@ func (k *kubeCluster) Relays(ctx context.Context) (map[string]string, error) { return out, nil } -func (k *kubeCluster) UpdateStatus(ctx context.Context, wp *atev1alpha1.WorkerPool) error { - _, err := k.ac.ApiV1alpha1().WorkerPools(wp.Namespace).UpdateStatus(ctx, wp, metav1.UpdateOptions{}) +func (k *kubeCluster) UpdateStatus(ctx context.Context, wp *atev1.WorkerPool) error { + _, err := k.ac.AteV1().WorkerPools(wp.Namespace).UpdateStatus(ctx, wp, metav1.UpdateOptions{}) return err } diff --git a/cmd/benchmarking/isolate/fake-workersync/relayclient.go b/cmd/benchmarking/isolate/fake-workersync/relayclient.go index e666edc55e..bc2ac7f8eb 100644 --- a/cmd/benchmarking/isolate/fake-workersync/relayclient.go +++ b/cmd/benchmarking/isolate/fake-workersync/relayclient.go @@ -23,9 +23,9 @@ import ( "sync" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/benchmarking/isolate/internal/fakeworker" "go.ate.dev/substrate/internal/credbundle" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) @@ -95,17 +95,17 @@ func (g *grpcRelay) Report(ctx context.Context, addr string, report workerReport } ctx, cancel := context.WithTimeout(ctx, reportTimeout) defer cancel() - client := ateapipb.NewWorkerServiceClient(conn) - ref := &ateapipb.ObjectRef{Name: report.Name} + client := ateapi.NewWorkerServiceClient(conn) + ref := &ateapi.ObjectRef{Name: report.Name} epoch := report.Epoch if epoch == 0 { - resp, err := client.AcquireWorkerEpoch(ctx, &ateapipb.AcquireWorkerEpochRequest{Worker: ref}) + resp, err := client.AcquireWorkerEpoch(ctx, &ateapi.AcquireWorkerEpochRequest{Worker: ref}) if err != nil { return err } epoch = resp.GetEpoch() } - if _, err := client.RegisterWorker(ctx, &ateapipb.RegisterWorkerRequest{ + if _, err := client.RegisterWorker(ctx, &ateapi.RegisterWorkerRequest{ Worker: ref, Epoch: epoch, Ips: report.IPs, @@ -113,7 +113,7 @@ func (g *grpcRelay) Report(ctx context.Context, addr string, report workerReport }); err != nil { return err } - _, err = client.SetWorkerSandboxRuntimes(ctx, &ateapipb.SetWorkerSandboxRuntimesRequest{ + _, err = client.SetWorkerSandboxRuntimes(ctx, &ateapi.SetWorkerSandboxRuntimesRequest{ Worker: ref, Epoch: epoch, SandboxClasses: report.SandboxClasses, diff --git a/cmd/benchmarking/isolate/fake-workersync/relayclient_test.go b/cmd/benchmarking/isolate/fake-workersync/relayclient_test.go index 961ec0f599..9bb3105453 100644 --- a/cmd/benchmarking/isolate/fake-workersync/relayclient_test.go +++ b/cmd/benchmarking/isolate/fake-workersync/relayclient_test.go @@ -26,10 +26,10 @@ import ( "sync" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/benchmarking/isolate/internal/fakeworker" "go.ate.dev/substrate/cmd/benchmarking/isolate/internal/fakeworker/fakeworkertest" "go.ate.dev/substrate/internal/credbundle" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -48,55 +48,55 @@ const stubEpoch = 9 // stubRelay is a stand-in fake-atelet relay: it records each request and // answers with err. type stubRelay struct { - ateapipb.UnimplementedWorkerServiceServer + ateapi.UnimplementedWorkerServiceServer mu sync.Mutex - acquireGot []*ateapipb.AcquireWorkerEpochRequest - got []*ateapipb.RegisterWorkerRequest - runtimesGot []*ateapipb.SetWorkerSandboxRuntimesRequest + acquireGot []*ateapi.AcquireWorkerEpochRequest + got []*ateapi.RegisterWorkerRequest + runtimesGot []*ateapi.SetWorkerSandboxRuntimesRequest err error } -func (s *stubRelay) AcquireWorkerEpoch(_ context.Context, in *ateapipb.AcquireWorkerEpochRequest) (*ateapipb.AcquireWorkerEpochResponse, error) { +func (s *stubRelay) AcquireWorkerEpoch(_ context.Context, in *ateapi.AcquireWorkerEpochRequest) (*ateapi.AcquireWorkerEpochResponse, error) { s.mu.Lock() defer s.mu.Unlock() s.acquireGot = append(s.acquireGot, in) if s.err != nil { return nil, s.err } - return &ateapipb.AcquireWorkerEpochResponse{Epoch: stubEpoch}, nil + return &ateapi.AcquireWorkerEpochResponse{Epoch: stubEpoch}, nil } -func (s *stubRelay) RegisterWorker(_ context.Context, in *ateapipb.RegisterWorkerRequest) (*ateapipb.RegisterWorkerResponse, error) { +func (s *stubRelay) RegisterWorker(_ context.Context, in *ateapi.RegisterWorkerRequest) (*ateapi.RegisterWorkerResponse, error) { s.mu.Lock() defer s.mu.Unlock() s.got = append(s.got, in) if s.err != nil { return nil, s.err } - return &ateapipb.RegisterWorkerResponse{}, nil + return &ateapi.RegisterWorkerResponse{}, nil } -func (s *stubRelay) SetWorkerSandboxRuntimes(_ context.Context, in *ateapipb.SetWorkerSandboxRuntimesRequest) (*ateapipb.SetWorkerSandboxRuntimesResponse, error) { +func (s *stubRelay) SetWorkerSandboxRuntimes(_ context.Context, in *ateapi.SetWorkerSandboxRuntimesRequest) (*ateapi.SetWorkerSandboxRuntimesResponse, error) { s.mu.Lock() defer s.mu.Unlock() s.runtimesGot = append(s.runtimesGot, in) if s.err != nil { return nil, s.err } - return &ateapipb.SetWorkerSandboxRuntimesResponse{}, nil + return &ateapi.SetWorkerSandboxRuntimesResponse{}, nil } // relayServer serves svc with a certificate for serverID from ca, requiring // fake-workersync's certificate from ca, and returns its address. -func relayServer(t *testing.T, ca *fakeworkertest.CA, serverID string, svc ateapipb.WorkerServiceServer) string { +func relayServer(t *testing.T, ca *fakeworkertest.CA, serverID string, svc ateapi.WorkerServiceServer) string { t.Helper() return relayServerTrusting(t, ca, ca, serverID, svc) } // relayServerTrusting is relayServer with its certificate from ca and // fake-workersync's required to chain to clientCA. -func relayServerTrusting(t *testing.T, ca, clientCA *fakeworkertest.CA, serverID string, svc ateapipb.WorkerServiceServer) string { +func relayServerTrusting(t *testing.T, ca, clientCA *fakeworkertest.CA, serverID string, svc ateapi.WorkerServiceServer) string { t.Helper() pem, err := os.ReadFile(clientCA.TrustBundle) if err != nil { @@ -116,7 +116,7 @@ func relayServerTrusting(t *testing.T, ca, clientCA *fakeworkertest.CA, serverID return fakeworker.VerifyPeerID(cs, testWorkerSyncID) }, }))) - ateapipb.RegisterWorkerServiceServer(srv, svc) + ateapi.RegisterWorkerServiceServer(srv, svc) go func() { _ = srv.Serve(lis) }() t.Cleanup(srv.Stop) return lis.Addr().String() @@ -132,12 +132,12 @@ func newTestRelay(t *testing.T, ca *fakeworkertest.CA) *grpcRelay { return relay } -func testClasses() []*ateapipb.WorkerSandboxClass { - return []*ateapipb.WorkerSandboxClass{{ +func testClasses() []*ateapi.WorkerSandboxClass { + return []*ateapi.WorkerSandboxClass{{ SandboxClass: "gvisor", - DefaultRuntime: &ateapipb.WorkerSandboxRuntime{Version: &ateapipb.VersionedSandboxCompat{ + DefaultRuntime: &ateapi.WorkerSandboxRuntime{Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: "v1", - Attributes: []*ateapipb.AttributeEntry{{Key: "architecture", Value: "amd64"}}, + Attributes: []*ateapi.AttributeEntry{{Key: "architecture", Value: "amd64"}}, }}, }} } @@ -146,7 +146,7 @@ func capacityReport() workerReport { return workerReport{ Name: "fake-r1-c52b9bd3-0", IPs: []string{"10.0.0.7"}, - Capacity: &ateapipb.WorkerResources{Actors: 1000}, + Capacity: &ateapi.WorkerResources{Actors: 1000}, SandboxClasses: testClasses(), } } @@ -163,15 +163,15 @@ func TestRelayClientSendsTheReport(t *testing.T) { t.Fatalf("Report: %v", err) } } - ref := &ateapipb.ObjectRef{Name: "fake-r1-c52b9bd3-0"} - wantAcquire := &ateapipb.AcquireWorkerEpochRequest{Worker: ref} - wantRegister := &ateapipb.RegisterWorkerRequest{ + ref := &ateapi.ObjectRef{Name: "fake-r1-c52b9bd3-0"} + wantAcquire := &ateapi.AcquireWorkerEpochRequest{Worker: ref} + wantRegister := &ateapi.RegisterWorkerRequest{ Worker: ref, Epoch: stubEpoch, Ips: []string{"10.0.0.7"}, - Capacity: &ateapipb.WorkerResources{Actors: 1000}, + Capacity: &ateapi.WorkerResources{Actors: 1000}, } - wantRuntimes := &ateapipb.SetWorkerSandboxRuntimesRequest{Worker: ref, Epoch: stubEpoch, SandboxClasses: testClasses()} + wantRuntimes := &ateapi.SetWorkerSandboxRuntimesRequest{Worker: ref, Epoch: stubEpoch, SandboxClasses: testClasses()} if len(svc.acquireGot) != 2 || !proto.Equal(svc.acquireGot[0], wantAcquire) { t.Errorf("relay received acquires %v, want %v twice", svc.acquireGot, wantAcquire) } diff --git a/cmd/credential-provider/kubernetes-secrets/kubeprovider.go b/cmd/credential-provider/kubernetes-secrets/kubeprovider.go index 054c0ca75e..1941c3e341 100644 --- a/cmd/credential-provider/kubernetes-secrets/kubeprovider.go +++ b/cmd/credential-provider/kubernetes-secrets/kubeprovider.go @@ -33,8 +33,8 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "go.ate.dev/substrate/api/credprovider/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/credproviderpb" ) // ProviderName is the ate-secret:// URI host this backend serves. @@ -112,10 +112,10 @@ func ParseURI(raw string) (SecretRef, error) { return ref, nil } -// Server implements credproviderpb.CredentialProviderServer over the Kubernetes +// Server implements credprovider.CredentialProviderServer over the Kubernetes // API. type Server struct { - credproviderpb.UnimplementedCredentialProviderServer + credprovider.UnimplementedCredentialProviderServer client kubernetes.Interface // nsAuth restricts which namespaces an atespace may resolve secrets from. @@ -131,7 +131,7 @@ func NewServer(client kubernetes.Interface, nsAuth *NamespaceAuthorizer) *Server func (s *Server) Grants() map[string][]string { return s.nsAuth.Grants() } // FetchSecret resolves one ate-secret:// URI to its Secret value. -func (s *Server) FetchSecret(ctx context.Context, req *credproviderpb.FetchSecretRequest) (*credproviderpb.FetchSecretResponse, error) { +func (s *Server) FetchSecret(ctx context.Context, req *credprovider.FetchSecretRequest) (*credprovider.FetchSecretResponse, error) { ref, err := ParseURI(req.GetUri()) if err != nil { return nil, status.Error(codes.InvalidArgument, err.Error()) @@ -179,7 +179,7 @@ func (s *Server) FetchSecret(ctx context.Context, req *credproviderpb.FetchSecre if err != nil { return nil, status.Errorf(codes.NotFound, "secret %s/%s: %v", ref.Namespace, ref.Name, err) } - return &credproviderpb.FetchSecretResponse{OpaqueBytes: value}, nil + return &credprovider.FetchSecretResponse{OpaqueBytes: value}, nil } // authorize checks the actor identity and its namespace grant before reading diff --git a/cmd/credential-provider/kubernetes-secrets/kubeprovider_test.go b/cmd/credential-provider/kubernetes-secrets/kubeprovider_test.go index 6199be449e..bb9518d8b9 100644 --- a/cmd/credential-provider/kubernetes-secrets/kubeprovider_test.go +++ b/cmd/credential-provider/kubernetes-secrets/kubeprovider_test.go @@ -34,7 +34,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "go.ate.dev/substrate/pkg/proto/credproviderpb" + "go.ate.dev/substrate/api/credprovider/v1" ) func TestParseURI(t *testing.T) { @@ -188,7 +188,7 @@ func TestFetchSecretAuthorization(t *testing.T) { t.Run(tc.name, func(t *testing.T) { client := fake.NewSimpleClientset(secret) srv := NewServer(client, authz) - resp, err := srv.FetchSecret(context.Background(), &credproviderpb.FetchSecretRequest{Uri: tc.uri, ActorSpiffeId: tc.actorSpiffeID}) + resp, err := srv.FetchSecret(context.Background(), &credprovider.FetchSecretRequest{Uri: tc.uri, ActorSpiffeId: tc.actorSpiffeID}) if tc.wantCode != codes.OK { if len(client.Actions()) != 0 { t.Fatal("denied request reached Kubernetes") @@ -210,7 +210,7 @@ func TestFetchSecretAuthorization(t *testing.T) { // A missing authorizer must fail closed. t.Run("nil authorizer denies", func(t *testing.T) { srv := NewServer(fake.NewSimpleClientset(secret), nil) - if _, err := srv.FetchSecret(context.Background(), &credproviderpb.FetchSecretRequest{ + if _, err := srv.FetchSecret(context.Background(), &credprovider.FetchSecretRequest{ Uri: "ate-secret://k8s.io/default/ns1/example-api/token", ActorSpiffeId: teamAURI, }); status.Code(err) != codes.PermissionDenied { @@ -275,7 +275,7 @@ func TestFetchSecret(t *testing.T) { t.Run(tc.name, func(t *testing.T) { client := fake.NewSimpleClientset(secret, multiKey) srv := NewServer(client, &NamespaceAuthorizer{allowed: map[string]map[string][]grant{"team-a": {"ns1": {{}}}}}) - resp, err := srv.FetchSecret(context.Background(), &credproviderpb.FetchSecretRequest{Uri: tc.uri, ActorSpiffeId: "spiffe://substrate-actor.local/actor/team-a/my-actor"}) + resp, err := srv.FetchSecret(context.Background(), &credprovider.FetchSecretRequest{Uri: tc.uri, ActorSpiffeId: "spiffe://substrate-actor.local/actor/team-a/my-actor"}) if tc.wantCode != codes.OK { if status.Code(err) != tc.wantCode { t.Fatalf("FetchSecret(%q) code = %v, want %v (err=%v)", tc.uri, status.Code(err), tc.wantCode, err) @@ -337,7 +337,7 @@ func TestFetchSecretKubernetesErrors(t *testing.T) { client := fake.NewSimpleClientset() client.PrependReactor("get", "secrets", func(k8stesting.Action) (bool, runtime.Object, error) { return true, nil, tc.err }) srv := NewServer(client, &NamespaceAuthorizer{allowed: map[string]map[string][]grant{"team-a": {"ns1": {{}}}}}) - _, err := srv.FetchSecret(t.Context(), &credproviderpb.FetchSecretRequest{ + _, err := srv.FetchSecret(t.Context(), &credprovider.FetchSecretRequest{ Uri: "ate-secret://k8s.io/default/ns1/api/token", ActorSpiffeId: "spiffe://substrate-actor.local/actor/team-a/a", }) if status.Code(err) != tc.code { @@ -354,7 +354,7 @@ func TestFetchSecretObservesRotation(t *testing.T) { secret := &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "api", Namespace: "ns1"}, Data: map[string][]byte{"token": []byte("first")}} client := fake.NewSimpleClientset(secret) srv := NewServer(client, &NamespaceAuthorizer{allowed: map[string]map[string][]grant{"team-a": {"ns1": {{}}}}}) - req := &credproviderpb.FetchSecretRequest{Uri: "ate-secret://k8s.io/default/ns1/api/token", ActorSpiffeId: "spiffe://substrate-actor.local/actor/team-a/a"} + req := &credprovider.FetchSecretRequest{Uri: "ate-secret://k8s.io/default/ns1/api/token", ActorSpiffeId: "spiffe://substrate-actor.local/actor/team-a/a"} first, err := srv.FetchSecret(t.Context(), req) if err != nil || string(first.GetOpaqueBytes()) != "first" { t.Fatalf("first fetch: %v, %v", first, err) @@ -418,7 +418,7 @@ func TestFetchSecretSecretNarrowing(t *testing.T) { t.Fatalf("newNamespaceAuthorizer: %v", err) } srv := NewServer(fake.NewSimpleClientset(model, caPool), authz) - resp, err := srv.FetchSecret(context.Background(), &credproviderpb.FetchSecretRequest{ + resp, err := srv.FetchSecret(context.Background(), &credprovider.FetchSecretRequest{ Uri: "ate-secret://k8s.io/default/ns1/" + tc.secret + "/token", ActorSpiffeId: actorURI, }) @@ -643,7 +643,7 @@ func TestFetchSecretLabelGrantHidesExistence(t *testing.T) { }), authz) ask := func(name string) (codes.Code, string) { - _, err := srv.FetchSecret(context.Background(), &credproviderpb.FetchSecretRequest{ + _, err := srv.FetchSecret(context.Background(), &credprovider.FetchSecretRequest{ Uri: "ate-secret://k8s.io/default/ns1/" + name + "/token", ActorSpiffeId: "spiffe://substrate-actor.local/actor/team-a/my-actor", }) @@ -675,7 +675,7 @@ func TestFetchSecretMissingSecretIsPermissionDeniedWhenEnforced(t *testing.T) { t.Fatalf("newNamespaceAuthorizer: %v", err) } srv := NewServer(fake.NewSimpleClientset(), authz) - if _, err := srv.FetchSecret(context.Background(), &credproviderpb.FetchSecretRequest{ + if _, err := srv.FetchSecret(context.Background(), &credprovider.FetchSecretRequest{ Uri: "ate-secret://k8s.io/default/ns1/no-such-secret/token", ActorSpiffeId: "spiffe://substrate-actor.local/actor/team-a/my-actor", }); status.Code(err) != codes.PermissionDenied { diff --git a/cmd/credential-provider/kubernetes-secrets/main.go b/cmd/credential-provider/kubernetes-secrets/main.go index 2dcc57b858..793d587579 100644 --- a/cmd/credential-provider/kubernetes-secrets/main.go +++ b/cmd/credential-provider/kubernetes-secrets/main.go @@ -41,12 +41,12 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" + "go.ate.dev/substrate/api/credprovider/v1" "go.ate.dev/substrate/internal/credbundle" "go.ate.dev/substrate/internal/installdefaults" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/serverboot" "go.ate.dev/substrate/internal/version" - "go.ate.dev/substrate/pkg/proto/credproviderpb" ) const serviceName = "credprovider" @@ -55,7 +55,7 @@ var ( listenAddr = pflag.String("listen-address", ":50051", "gRPC listen address") metricsAddr = pflag.String("metrics-address", ":9090", "Prometheus /metrics HTTP listen address") healthAddr = pflag.String("health-address", ":9091", "/readyz and /healthz HTTP listen address") - statusAddr = pflag.String("status-address", ":4040", "/statusz HTTP listen address; empty disables the page") + statusAddr = pflag.String("status-address", "127.0.0.1:4040", "/statusz HTTP listen address; defaults to loopback for port-forward access; empty disables the page") serverBundle = pflag.String("server-cred-bundle", "", "credential bundle (PEM key+chain) presented for serving TLS (required)") clientCAFile = pflag.String("client-ca-file", "", "CA bundle that caller (injector) client certificates must chain to (required)") // The injector is the only caller allowed to fetch secrets. Its identity @@ -125,7 +125,7 @@ func run(ctx context.Context) error { ) reflection.Register(srv) provider := NewServer(client, nsAuth) - credproviderpb.RegisterCredentialProviderServer(srv, provider) + credprovider.RegisterCredentialProviderServer(srv, provider) lis, err := (&net.ListenConfig{}).Listen(ctx, "tcp", *listenAddr) if err != nil { diff --git a/cmd/credential-provider/kubernetes-secrets/main_test.go b/cmd/credential-provider/kubernetes-secrets/main_test.go index a1cf7ed8d7..0a95b2e8a8 100644 --- a/cmd/credential-provider/kubernetes-secrets/main_test.go +++ b/cmd/credential-provider/kubernetes-secrets/main_test.go @@ -31,9 +31,9 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/credprovider/v1" "go.ate.dev/substrate/internal/installdefaults" "go.ate.dev/substrate/internal/localca" - "go.ate.dev/substrate/pkg/proto/credproviderpb" "google.golang.org/grpc" "google.golang.org/grpc/credentials" corev1 "k8s.io/api/core/v1" @@ -337,7 +337,7 @@ func TestProviderMTLS(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "api", Namespace: "ns1"}, Data: map[string][]byte{"token": []byte("credential")}, }) srv := grpc.NewServer(grpc.Creds(creds)) - credproviderpb.RegisterCredentialProviderServer(srv, NewServer(client, &NamespaceAuthorizer{allowed: map[string]map[string][]grant{"team-a": {"ns1": {{}}}}})) + credprovider.RegisterCredentialProviderServer(srv, NewServer(client, &NamespaceAuthorizer{allowed: map[string]map[string][]grant{"team-a": {"ns1": {{}}}}})) lis, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) @@ -367,7 +367,7 @@ func TestProviderMTLS(t *testing.T) { ctx, cancel := context.WithTimeout(t.Context(), 5*time.Second) defer cancel() before := len(client.Actions()) - resp, err := credproviderpb.NewCredentialProviderClient(conn).FetchSecret(ctx, &credproviderpb.FetchSecretRequest{ + resp, err := credprovider.NewCredentialProviderClient(conn).FetchSecret(ctx, &credprovider.FetchSecretRequest{ Uri: "ate-secret://k8s.io/default/ns1/api/token", ActorSpiffeId: "spiffe://substrate-actor.local/actor/team-a/a", }) if tc.allowed { diff --git a/cmd/credential-provider/kubernetes-secrets/statusz_test.go b/cmd/credential-provider/kubernetes-secrets/statusz_test.go index 184ec08e01..69fa9f49de 100644 --- a/cmd/credential-provider/kubernetes-secrets/statusz_test.go +++ b/cmd/credential-provider/kubernetes-secrets/statusz_test.go @@ -27,7 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - "go.ate.dev/substrate/pkg/proto/credproviderpb" + "go.ate.dev/substrate/api/credprovider/v1" ) func TestGrants(t *testing.T) { @@ -71,7 +71,7 @@ func statuszServer(t *testing.T) (*Server, string) { } srv := NewServer(fake.NewSimpleClientset(secret), authz) - if _, err := srv.FetchSecret(context.Background(), &credproviderpb.FetchSecretRequest{ + if _, err := srv.FetchSecret(context.Background(), &credprovider.FetchSecretRequest{ Uri: "ate-secret://k8s.io/default/ns1/example-api/token", ActorSpiffeId: "spiffe://substrate-actor.local/actor/team-a/my-actor", }); err != nil { diff --git a/cmd/kubectl-ate/README.md b/cmd/kubectl-ate/README.md index 1f6ba2c12d..21c27a77e4 100644 --- a/cmd/kubectl-ate/README.md +++ b/cmd/kubectl-ate/README.md @@ -164,7 +164,7 @@ one (or create a new template and repoint suspended actors to it with `kubectl ate update actor --template`). ```bash -# Create a template from a manifest (protojson-shaped ateapipb.ActorTemplate, +# Create a template from a manifest (protojson-shaped ateapi.ActorTemplate, # a single YAML/JSON document; use -f - for stdin). The metadata's atespace # must already exist. kubectl ate create actor-template -f template.yaml diff --git a/cmd/kubectl-ate/internal/cmd/access_policy.go b/cmd/kubectl-ate/internal/cmd/access_policy.go index 092fd8fd56..714aa693e1 100644 --- a/cmd/kubectl-ate/internal/cmd/access_policy.go +++ b/cmd/kubectl-ate/internal/cmd/access_policy.go @@ -26,9 +26,9 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/encoding/protojson" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/kubectl-ate/internal/printer" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) var accessPolicyFlags struct { @@ -103,8 +103,8 @@ func (s accessPolicyScope) String() string { return fmt.Sprintf("atespace %q", s.atespace) } -func (s accessPolicyScope) ref() *ateapipb.ObjectRef { - return &ateapipb.ObjectRef{Name: s.atespace} +func (s accessPolicyScope) ref() *ateapi.ObjectRef { + return &ateapi.ObjectRef{Name: s.atespace} } // scopeFromFlags requires exactly one of --atespace and --global. @@ -121,12 +121,12 @@ func scopeFromFlags(atespace string, global bool) (accessPolicyScope, error) { // accessPolicyFromManifest parses a single protojson-shaped YAML or JSON // document into an AccessPolicy. Parsing is strict: unknown fields are an // error. -func accessPolicyFromManifest(data []byte) (*ateapipb.AccessPolicy, error) { +func accessPolicyFromManifest(data []byte) (*ateapi.AccessPolicy, error) { jsonData, err := manifestToJSON(data) if err != nil { return nil, err } - policy := &ateapipb.AccessPolicy{} + policy := &ateapi.AccessPolicy{} if err := protojson.Unmarshal(jsonData, policy); err != nil { return nil, fmt.Errorf("invalid AccessPolicy: %w", err) } @@ -137,7 +137,7 @@ func accessPolicyFromManifest(data []byte) (*ateapipb.AccessPolicy, error) { // filename is "-", parses it, and checks its metadata. An access policy's // metadata.atespace is always empty, whatever its scope, and its name is // always "default"; omitted metadata is filled in. -func loadAccessPolicyManifest(in io.Reader, filename string) (*ateapipb.AccessPolicy, error) { +func loadAccessPolicyManifest(in io.Reader, filename string) (*ateapi.AccessPolicy, error) { data, err := readFileOrStdin(in, filename) if err != nil { return nil, err @@ -147,7 +147,7 @@ func loadAccessPolicyManifest(in io.Reader, filename string) (*ateapipb.AccessPo return nil, fmt.Errorf("failed to parse access policy manifest %q: %w", filename, err) } if policy.Metadata == nil { - policy.Metadata = &ateapipb.ResourceMetadata{} + policy.Metadata = &ateapi.ResourceMetadata{} } if policy.Metadata.Name == "" { policy.Metadata.Name = resources.SingletonName @@ -164,7 +164,7 @@ func loadAccessPolicyManifest(in io.Reader, filename string) (*ateapipb.AccessPo // atespaceGetter abstracts the atespace read that tells a missing atespace // from a missing access policy. type atespaceGetter interface { - GetAtespace(ctx context.Context, req *ateapipb.GetAtespaceRequest, opts ...grpc.CallOption) (*ateapipb.Atespace, error) + GetAtespace(ctx context.Context, req *ateapi.GetAtespaceRequest, opts ...grpc.CallOption) (*ateapi.Atespace, error) } // requireScope settles a NotFound from an access policy RPC. For an atespace @@ -175,7 +175,7 @@ func requireScope(ctx context.Context, getter atespaceGetter, scope accessPolicy if scope.global() { return nil } - if _, err := getter.GetAtespace(ctx, &ateapipb.GetAtespaceRequest{Atespace: scope.ref()}); err != nil { + if _, err := getter.GetAtespace(ctx, &ateapi.GetAtespaceRequest{Atespace: scope.ref()}); err != nil { if status.Code(err) == codes.NotFound { return fmt.Errorf("atespace %q not found", scope.atespace) } @@ -187,13 +187,13 @@ func requireScope(ctx context.Context, getter atespaceGetter, scope accessPolicy // accessPolicyClient is the subset of the Control API the access policy // commands call. type accessPolicyClient interface { - GetGlobalAccessPolicy(ctx context.Context, req *ateapipb.GetGlobalAccessPolicyRequest, opts ...grpc.CallOption) (*ateapipb.AccessPolicy, error) - CreateGlobalAccessPolicy(ctx context.Context, req *ateapipb.CreateGlobalAccessPolicyRequest, opts ...grpc.CallOption) (*ateapipb.AccessPolicy, error) - UpdateGlobalAccessPolicy(ctx context.Context, req *ateapipb.UpdateGlobalAccessPolicyRequest, opts ...grpc.CallOption) (*ateapipb.AccessPolicy, error) - GetAtespaceAccessPolicy(ctx context.Context, req *ateapipb.GetAtespaceAccessPolicyRequest, opts ...grpc.CallOption) (*ateapipb.AccessPolicy, error) - CreateAtespaceAccessPolicy(ctx context.Context, req *ateapipb.CreateAtespaceAccessPolicyRequest, opts ...grpc.CallOption) (*ateapipb.AccessPolicy, error) - UpdateAtespaceAccessPolicy(ctx context.Context, req *ateapipb.UpdateAtespaceAccessPolicyRequest, opts ...grpc.CallOption) (*ateapipb.AccessPolicy, error) - DeleteAtespaceAccessPolicy(ctx context.Context, req *ateapipb.DeleteAtespaceAccessPolicyRequest, opts ...grpc.CallOption) (*ateapipb.AccessPolicy, error) + GetGlobalAccessPolicy(ctx context.Context, req *ateapi.GetGlobalAccessPolicyRequest, opts ...grpc.CallOption) (*ateapi.AccessPolicy, error) + CreateGlobalAccessPolicy(ctx context.Context, req *ateapi.CreateGlobalAccessPolicyRequest, opts ...grpc.CallOption) (*ateapi.AccessPolicy, error) + UpdateGlobalAccessPolicy(ctx context.Context, req *ateapi.UpdateGlobalAccessPolicyRequest, opts ...grpc.CallOption) (*ateapi.AccessPolicy, error) + GetAtespaceAccessPolicy(ctx context.Context, req *ateapi.GetAtespaceAccessPolicyRequest, opts ...grpc.CallOption) (*ateapi.AccessPolicy, error) + CreateAtespaceAccessPolicy(ctx context.Context, req *ateapi.CreateAtespaceAccessPolicyRequest, opts ...grpc.CallOption) (*ateapi.AccessPolicy, error) + UpdateAtespaceAccessPolicy(ctx context.Context, req *ateapi.UpdateAtespaceAccessPolicyRequest, opts ...grpc.CallOption) (*ateapi.AccessPolicy, error) + DeleteAtespaceAccessPolicy(ctx context.Context, req *ateapi.DeleteAtespaceAccessPolicyRequest, opts ...grpc.CallOption) (*ateapi.AccessPolicy, error) atespaceGetter } @@ -207,12 +207,12 @@ type accessPolicyRunner struct { } func (r *accessPolicyRunner) get(ctx context.Context) error { - var policy *ateapipb.AccessPolicy + var policy *ateapi.AccessPolicy var err error if r.scope.global() { - policy, err = r.client.GetGlobalAccessPolicy(ctx, &ateapipb.GetGlobalAccessPolicyRequest{Name: resources.SingletonName}) + policy, err = r.client.GetGlobalAccessPolicy(ctx, &ateapi.GetGlobalAccessPolicyRequest{Name: resources.SingletonName}) } else { - policy, err = r.client.GetAtespaceAccessPolicy(ctx, &ateapipb.GetAtespaceAccessPolicyRequest{Atespace: r.scope.ref(), Name: resources.SingletonName}) + policy, err = r.client.GetAtespaceAccessPolicy(ctx, &ateapi.GetAtespaceAccessPolicyRequest{Atespace: r.scope.ref(), Name: resources.SingletonName}) } if status.Code(err) == codes.NotFound { if err := requireScope(ctx, r.client, r.scope); err != nil { @@ -228,13 +228,13 @@ func (r *accessPolicyRunner) get(ctx context.Context) error { return printer.PrintAccessPolicyTo(r.stdout, r.scope.atespace, policy, r.outputFmt) } -func (r *accessPolicyRunner) create(ctx context.Context, policy *ateapipb.AccessPolicy) error { - var created *ateapipb.AccessPolicy +func (r *accessPolicyRunner) create(ctx context.Context, policy *ateapi.AccessPolicy) error { + var created *ateapi.AccessPolicy var err error if r.scope.global() { - created, err = r.client.CreateGlobalAccessPolicy(ctx, &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: policy}) + created, err = r.client.CreateGlobalAccessPolicy(ctx, &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: policy}) } else { - created, err = r.client.CreateAtespaceAccessPolicy(ctx, &ateapipb.CreateAtespaceAccessPolicyRequest{Atespace: r.scope.ref(), AccessPolicy: policy}) + created, err = r.client.CreateAtespaceAccessPolicy(ctx, &ateapi.CreateAtespaceAccessPolicyRequest{Atespace: r.scope.ref(), AccessPolicy: policy}) } if status.Code(err) == codes.AlreadyExists { return fmt.Errorf(`%s already has an access policy; change it with "kubectl ate update access-policy": %w`, r.scope, err) @@ -245,13 +245,13 @@ func (r *accessPolicyRunner) create(ctx context.Context, policy *ateapipb.Access return printer.PrintAccessPolicyTo(r.stdout, r.scope.atespace, created, r.outputFmt) } -func (r *accessPolicyRunner) update(ctx context.Context, policy *ateapipb.AccessPolicy) error { - var updated *ateapipb.AccessPolicy +func (r *accessPolicyRunner) update(ctx context.Context, policy *ateapi.AccessPolicy) error { + var updated *ateapi.AccessPolicy var err error if r.scope.global() { - updated, err = r.client.UpdateGlobalAccessPolicy(ctx, &ateapipb.UpdateGlobalAccessPolicyRequest{AccessPolicy: policy}) + updated, err = r.client.UpdateGlobalAccessPolicy(ctx, &ateapi.UpdateGlobalAccessPolicyRequest{AccessPolicy: policy}) } else { - updated, err = r.client.UpdateAtespaceAccessPolicy(ctx, &ateapipb.UpdateAtespaceAccessPolicyRequest{Atespace: r.scope.ref(), AccessPolicy: policy}) + updated, err = r.client.UpdateAtespaceAccessPolicy(ctx, &ateapi.UpdateAtespaceAccessPolicyRequest{Atespace: r.scope.ref(), AccessPolicy: policy}) } if status.Code(err) == codes.NotFound { if err := requireScope(ctx, r.client, r.scope); err != nil { @@ -268,8 +268,8 @@ func (r *accessPolicyRunner) update(ctx context.Context, policy *ateapipb.Access return printer.PrintAccessPolicyTo(r.stdout, r.scope.atespace, updated, r.outputFmt) } -func (r *accessPolicyRunner) delete(ctx context.Context, options *ateapipb.DeleteOptions) error { - _, err := r.client.DeleteAtespaceAccessPolicy(ctx, &ateapipb.DeleteAtespaceAccessPolicyRequest{Atespace: r.scope.ref(), Name: resources.SingletonName, Options: options}) +func (r *accessPolicyRunner) delete(ctx context.Context, options *ateapi.DeleteOptions) error { + _, err := r.client.DeleteAtespaceAccessPolicy(ctx, &ateapi.DeleteAtespaceAccessPolicyRequest{Atespace: r.scope.ref(), Name: resources.SingletonName, Options: options}) if status.Code(err) == codes.NotFound { if err := requireScope(ctx, r.client, r.scope); err != nil { return err diff --git a/cmd/kubectl-ate/internal/cmd/access_policy_test.go b/cmd/kubectl-ate/internal/cmd/access_policy_test.go index 9288cac71c..f4815f5e54 100644 --- a/cmd/kubectl-ate/internal/cmd/access_policy_test.go +++ b/cmd/kubectl-ate/internal/cmd/access_policy_test.go @@ -26,8 +26,8 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/testing/protocmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) func TestScopeFromFlags(t *testing.T) { @@ -66,29 +66,29 @@ func TestScopeFromFlags(t *testing.T) { func TestLoadAccessPolicyManifest(t *testing.T) { t.Parallel() - ownerAlice := []*ateapipb.Binding{{Role: "owner", Members: []string{"user:alice"}}} + ownerAlice := []*ateapi.Binding{{Role: "owner", Members: []string{"user:alice"}}} tests := []struct { name string manifest string - want *ateapipb.AccessPolicy + want *ateapi.AccessPolicy wantErr string }{ { name: "metadata omitted is filled in", manifest: "bindings:\n- role: owner\n members: [\"user:alice\"]\n", - want: &ateapipb.AccessPolicy{Metadata: &ateapipb.ResourceMetadata{Name: "default"}, Bindings: ownerAlice}, + want: &ateapi.AccessPolicy{Metadata: &ateapi.ResourceMetadata{Name: "default"}, Bindings: ownerAlice}, }, { name: "preconditions preserved", manifest: `metadata: {name: default, uid: u-1, version: "3"} bindings: [{role: owner, members: ["user:alice"]}] `, - want: &ateapipb.AccessPolicy{Metadata: &ateapipb.ResourceMetadata{Name: "default", Uid: "u-1", Version: 3}, Bindings: ownerAlice}, + want: &ateapi.AccessPolicy{Metadata: &ateapi.ResourceMetadata{Name: "default", Uid: "u-1", Version: 3}, Bindings: ownerAlice}, }, { name: "no bindings", manifest: "metadata: {name: default}\n", - want: &ateapipb.AccessPolicy{Metadata: &ateapipb.ResourceMetadata{Name: "default"}}, + want: &ateapi.AccessPolicy{Metadata: &ateapi.ResourceMetadata{Name: "default"}}, }, {name: "wrong name", manifest: "metadata: {name: other}\n", wantErr: `must be "default"`}, {name: "atespace set", manifest: "metadata: {atespace: team-a}\n", wantErr: "metadata.atespace must be empty"}, @@ -117,7 +117,7 @@ bindings: [{role: owner, members: ["user:alice"]}] // fakeAccessPolicyClient records the last RPC and answers with policy or err. type fakeAccessPolicyClient struct { - policy *ateapipb.AccessPolicy + policy *ateapi.AccessPolicy err error atespaceErr error @@ -125,53 +125,53 @@ type fakeAccessPolicyClient struct { req any } -func (f *fakeAccessPolicyClient) answer(method string, req any) (*ateapipb.AccessPolicy, error) { +func (f *fakeAccessPolicyClient) answer(method string, req any) (*ateapi.AccessPolicy, error) { f.method, f.req = method, req return f.policy, f.err } -func (f *fakeAccessPolicyClient) GetGlobalAccessPolicy(_ context.Context, req *ateapipb.GetGlobalAccessPolicyRequest, _ ...grpc.CallOption) (*ateapipb.AccessPolicy, error) { +func (f *fakeAccessPolicyClient) GetGlobalAccessPolicy(_ context.Context, req *ateapi.GetGlobalAccessPolicyRequest, _ ...grpc.CallOption) (*ateapi.AccessPolicy, error) { return f.answer("GetGlobalAccessPolicy", req) } -func (f *fakeAccessPolicyClient) CreateGlobalAccessPolicy(_ context.Context, req *ateapipb.CreateGlobalAccessPolicyRequest, _ ...grpc.CallOption) (*ateapipb.AccessPolicy, error) { +func (f *fakeAccessPolicyClient) CreateGlobalAccessPolicy(_ context.Context, req *ateapi.CreateGlobalAccessPolicyRequest, _ ...grpc.CallOption) (*ateapi.AccessPolicy, error) { return f.answer("CreateGlobalAccessPolicy", req) } -func (f *fakeAccessPolicyClient) UpdateGlobalAccessPolicy(_ context.Context, req *ateapipb.UpdateGlobalAccessPolicyRequest, _ ...grpc.CallOption) (*ateapipb.AccessPolicy, error) { +func (f *fakeAccessPolicyClient) UpdateGlobalAccessPolicy(_ context.Context, req *ateapi.UpdateGlobalAccessPolicyRequest, _ ...grpc.CallOption) (*ateapi.AccessPolicy, error) { return f.answer("UpdateGlobalAccessPolicy", req) } -func (f *fakeAccessPolicyClient) GetAtespaceAccessPolicy(_ context.Context, req *ateapipb.GetAtespaceAccessPolicyRequest, _ ...grpc.CallOption) (*ateapipb.AccessPolicy, error) { +func (f *fakeAccessPolicyClient) GetAtespaceAccessPolicy(_ context.Context, req *ateapi.GetAtespaceAccessPolicyRequest, _ ...grpc.CallOption) (*ateapi.AccessPolicy, error) { return f.answer("GetAtespaceAccessPolicy", req) } -func (f *fakeAccessPolicyClient) CreateAtespaceAccessPolicy(_ context.Context, req *ateapipb.CreateAtespaceAccessPolicyRequest, _ ...grpc.CallOption) (*ateapipb.AccessPolicy, error) { +func (f *fakeAccessPolicyClient) CreateAtespaceAccessPolicy(_ context.Context, req *ateapi.CreateAtespaceAccessPolicyRequest, _ ...grpc.CallOption) (*ateapi.AccessPolicy, error) { return f.answer("CreateAtespaceAccessPolicy", req) } -func (f *fakeAccessPolicyClient) UpdateAtespaceAccessPolicy(_ context.Context, req *ateapipb.UpdateAtespaceAccessPolicyRequest, _ ...grpc.CallOption) (*ateapipb.AccessPolicy, error) { +func (f *fakeAccessPolicyClient) UpdateAtespaceAccessPolicy(_ context.Context, req *ateapi.UpdateAtespaceAccessPolicyRequest, _ ...grpc.CallOption) (*ateapi.AccessPolicy, error) { return f.answer("UpdateAtespaceAccessPolicy", req) } -func (f *fakeAccessPolicyClient) DeleteAtespaceAccessPolicy(_ context.Context, req *ateapipb.DeleteAtespaceAccessPolicyRequest, _ ...grpc.CallOption) (*ateapipb.AccessPolicy, error) { +func (f *fakeAccessPolicyClient) DeleteAtespaceAccessPolicy(_ context.Context, req *ateapi.DeleteAtespaceAccessPolicyRequest, _ ...grpc.CallOption) (*ateapi.AccessPolicy, error) { return f.answer("DeleteAtespaceAccessPolicy", req) } -func (f *fakeAccessPolicyClient) GetAtespace(_ context.Context, req *ateapipb.GetAtespaceRequest, _ ...grpc.CallOption) (*ateapipb.Atespace, error) { +func (f *fakeAccessPolicyClient) GetAtespace(_ context.Context, req *ateapi.GetAtespaceRequest, _ ...grpc.CallOption) (*ateapi.Atespace, error) { if f.atespaceErr != nil { return nil, f.atespaceErr } - return &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: req.GetAtespace().GetName()}}, nil + return &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: req.GetAtespace().GetName()}}, nil } func TestAccessPolicyRunner(t *testing.T) { t.Parallel() - stored := &ateapipb.AccessPolicy{ - Metadata: &ateapipb.ResourceMetadata{Name: "default", Uid: "u-1", Version: 2}, - Bindings: []*ateapipb.Binding{{Role: "owner", Members: []string{"user:alice"}}}, + stored := &ateapi.AccessPolicy{ + Metadata: &ateapi.ResourceMetadata{Name: "default", Uid: "u-1", Version: 2}, + Bindings: []*ateapi.Binding{{Role: "owner", Members: []string{"user:alice"}}}, } - edit := &ateapipb.AccessPolicy{Metadata: &ateapipb.ResourceMetadata{Name: "default", Uid: "u-1", Version: 2}} + edit := &ateapi.AccessPolicy{Metadata: &ateapi.ResourceMetadata{Name: "default", Uid: "u-1", Version: 2}} teamA := accessPolicyScope{atespace: "team-a"} global := accessPolicyScope{} notFound := status.Error(codes.NotFound, "not found") @@ -194,7 +194,7 @@ func TestAccessPolicyRunner(t *testing.T) { client: &fakeAccessPolicyClient{policy: stored}, run: func(ctx context.Context, r *accessPolicyRunner) error { return r.get(ctx) }, wantMethod: "GetAtespaceAccessPolicy", - wantReq: &ateapipb.GetAtespaceAccessPolicyRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}, Name: resources.SingletonName}, + wantReq: &ateapi.GetAtespaceAccessPolicyRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}, Name: resources.SingletonName}, wantStdout: "team-a owner user:alice", }, { @@ -203,7 +203,7 @@ func TestAccessPolicyRunner(t *testing.T) { client: &fakeAccessPolicyClient{policy: stored}, run: func(ctx context.Context, r *accessPolicyRunner) error { return r.get(ctx) }, wantMethod: "GetGlobalAccessPolicy", - wantReq: &ateapipb.GetGlobalAccessPolicyRequest{Name: resources.SingletonName}, + wantReq: &ateapi.GetGlobalAccessPolicyRequest{Name: resources.SingletonName}, wantStdout: " owner user:alice", }, { @@ -236,7 +236,7 @@ func TestAccessPolicyRunner(t *testing.T) { client: &fakeAccessPolicyClient{policy: stored}, run: func(ctx context.Context, r *accessPolicyRunner) error { return r.create(ctx, edit) }, wantMethod: "CreateAtespaceAccessPolicy", - wantReq: &ateapipb.CreateAtespaceAccessPolicyRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}, AccessPolicy: edit}, + wantReq: &ateapi.CreateAtespaceAccessPolicyRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}, AccessPolicy: edit}, wantStdout: "team-a owner user:alice", }, { @@ -245,7 +245,7 @@ func TestAccessPolicyRunner(t *testing.T) { client: &fakeAccessPolicyClient{policy: stored}, run: func(ctx context.Context, r *accessPolicyRunner) error { return r.create(ctx, edit) }, wantMethod: "CreateGlobalAccessPolicy", - wantReq: &ateapipb.CreateGlobalAccessPolicyRequest{AccessPolicy: edit}, + wantReq: &ateapi.CreateGlobalAccessPolicyRequest{AccessPolicy: edit}, }, { name: "create existing", @@ -261,7 +261,7 @@ func TestAccessPolicyRunner(t *testing.T) { client: &fakeAccessPolicyClient{policy: stored}, run: func(ctx context.Context, r *accessPolicyRunner) error { return r.update(ctx, edit) }, wantMethod: "UpdateGlobalAccessPolicy", - wantReq: &ateapipb.UpdateGlobalAccessPolicyRequest{AccessPolicy: edit}, + wantReq: &ateapi.UpdateGlobalAccessPolicyRequest{AccessPolicy: edit}, }, { name: "update stale", @@ -284,10 +284,10 @@ func TestAccessPolicyRunner(t *testing.T) { scope: teamA, client: &fakeAccessPolicyClient{policy: stored}, run: func(ctx context.Context, r *accessPolicyRunner) error { - return r.delete(ctx, &ateapipb.DeleteOptions{Version: 2}) + return r.delete(ctx, &ateapi.DeleteOptions{Version: 2}) }, wantMethod: "DeleteAtespaceAccessPolicy", - wantReq: &ateapipb.DeleteAtespaceAccessPolicyRequest{Atespace: &ateapipb.ObjectRef{Name: "team-a"}, Name: resources.SingletonName, Options: &ateapipb.DeleteOptions{Version: 2}}, + wantReq: &ateapi.DeleteAtespaceAccessPolicyRequest{Atespace: &ateapi.ObjectRef{Name: "team-a"}, Name: resources.SingletonName, Options: &ateapi.DeleteOptions{Version: 2}}, wantStdout: `access policy for atespace "team-a" deleted`, }, { diff --git a/cmd/kubectl-ate/internal/cmd/actor.go b/cmd/kubectl-ate/internal/cmd/actor.go index c1fcd70d42..070d3aed2d 100644 --- a/cmd/kubectl-ate/internal/cmd/actor.go +++ b/cmd/kubectl-ate/internal/cmd/actor.go @@ -28,11 +28,11 @@ import ( "time" "github.com/spf13/cobra" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/kubectl-ate/internal/printer" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/ocispec" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -81,10 +81,10 @@ var getActorsCmd = &cobra.Command{ defer apiClient.Close() if len(args) > 0 { - actors := make([]*ateapipb.Actor, 0, len(args)) + actors := make([]*ateapi.Actor, 0, len(args)) for _, actorName := range args { actorRef := resources.ActorRef{Atespace: getActorAtespaceFlag, Name: actorName} - resp, err := apiClient.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actorRef.ToObjectRef()}) + resp, err := apiClient.GetActor(ctx, &ateapi.GetActorRequest{Actor: actorRef.ToObjectRef()}) if err != nil { return fmt.Errorf("failed to get actor %q: %w", actorName, err) } @@ -96,11 +96,11 @@ var getActorsCmd = &cobra.Command{ return printer.PrintActorsTo(cmd.OutOrStdout(), actors, outputFmt) } - var allActors []*ateapipb.Actor + var allActors []*ateapi.Actor pageToken := "" for { - resp, err := apiClient.ListActors(ctx, &ateapipb.ListActorsRequest{ - Options: &ateapipb.ListOptions{PageSize: 1000, PageToken: pageToken}, + resp, err := apiClient.ListActors(ctx, &ateapi.ListActorsRequest{ + Options: &ateapi.ListOptions{PageSize: 1000, PageToken: pageToken}, Atespace: getActorAtespaceFlag, }) if err != nil { @@ -155,7 +155,7 @@ var updateActorCmd = &cobra.Command{ return usageErrorf("at least one of --template or --worker-selector is required") } - var templateRef *ateapipb.ObjectRef + var templateRef *ateapi.ObjectRef if templateSet { ref, err := parseAtespacedName(updateActorTemplateFlag, updateActorAtespaceFlag) if err != nil { @@ -164,7 +164,7 @@ var updateActorCmd = &cobra.Command{ templateRef = ref } - var selector *ateapipb.Selector + var selector *ateapi.Selector if workerSelectorSet { s, err := parseWorkerSelector(updateActorWorkerSelectorFlag) if err != nil { @@ -181,7 +181,7 @@ var updateActorCmd = &cobra.Command{ defer apiClient.Close() actorRef := resources.ActorRef{Atespace: updateActorAtespaceFlag, Name: args[0]} - resp, err := updateActor(ctx, apiClient, actorRef.ToObjectRef(), func(actor *ateapipb.Actor) { + resp, err := updateActor(ctx, apiClient, actorRef.ToObjectRef(), func(actor *ateapi.Actor) { if templateSet { actor.ActorTemplate = templateRef } @@ -210,7 +210,7 @@ var deleteActorCmd = &cobra.Command{ defer c.Close() actorRef := resources.ActorRef{Atespace: deleteActorAtespaceFlag, Name: args[0]} - _, err = c.ControlClient.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ + _, err = c.ControlClient.DeleteActor(ctx, &ateapi.DeleteActorRequest{ Actor: actorRef.ToObjectRef(), }) if err != nil { @@ -235,7 +235,7 @@ var resumeActorCmd = &cobra.Command{ defer apiClient.Close() actorRef := resources.ActorRef{Atespace: resumeActorAtespaceFlag, Name: args[0]} - resp, err := apiClient.ResumeActor(ctx, &ateapipb.ResumeActorRequest{ + resp, err := apiClient.ResumeActor(ctx, &ateapi.ResumeActorRequest{ Actor: actorRef.ToObjectRef(), }) if err != nil { @@ -286,32 +286,32 @@ const ( ) // parseSuspendMode maps the --mode flag value to a durability mode. -func parseSuspendMode(mode string) (ateapipb.DurabilityMode, error) { +func parseSuspendMode(mode string) (ateapi.DurabilityMode, error) { switch mode { case suspendModeAsync: - return ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, nil + return ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, nil case suspendModeSync: - return ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS, nil + return ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS, nil default: - return ateapipb.DurabilityMode_DURABILITY_MODE_UNSPECIFIED, fmt.Errorf("invalid --mode %q: must be one of %s, %s", mode, suspendModeAsync, suspendModeSync) + return ateapi.DurabilityMode_DURABILITY_MODE_UNSPECIFIED, fmt.Errorf("invalid --mode %q: must be one of %s, %s", mode, suspendModeAsync, suspendModeSync) } } // buildSuspendActorRequest builds the SuspendActor request for an actor. -func buildSuspendActorRequest(actorRef resources.ActorRef, mode ateapipb.DurabilityMode) *ateapipb.SuspendActorRequest { - return &ateapipb.SuspendActorRequest{ +func buildSuspendActorRequest(actorRef resources.ActorRef, mode ateapi.DurabilityMode) *ateapi.SuspendActorRequest { + return &ateapi.SuspendActorRequest{ Actor: actorRef.ToObjectRef(), - Options: &ateapipb.SuspendOptions{Mode: mode}, + Options: &ateapi.SuspendOptions{Mode: mode}, } } -func buildCreateActorRequest(actorName, atespace, template, tag string) (*ateapipb.CreateActorRequest, error) { +func buildCreateActorRequest(actorName, atespace, template, tag string) (*ateapi.CreateActorRequest, error) { templateRef, err := parseAtespacedName(template, atespace) if err != nil { return nil, err } - actor := &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ + actor := &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: atespace, Name: actorName, }, @@ -325,22 +325,22 @@ func buildCreateActorRequest(actorName, atespace, template, tag string) (*ateapi } actor.SourceTag = ref } - return &ateapipb.CreateActorRequest{Actor: actor}, nil + return &ateapi.CreateActorRequest{Actor: actor}, nil } type actorUpdater interface { - GetActor(ctx context.Context, in *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) - UpdateActor(ctx context.Context, in *ateapipb.UpdateActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) + GetActor(ctx context.Context, in *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) + UpdateActor(ctx context.Context, in *ateapi.UpdateActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) } -func updateActor(ctx context.Context, client actorUpdater, ref *ateapipb.ObjectRef, mutate func(*ateapipb.Actor)) (*ateapipb.Actor, error) { - actor, err := client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: ref}) +func updateActor(ctx context.Context, client actorUpdater, ref *ateapi.ObjectRef, mutate func(*ateapi.Actor)) (*ateapi.Actor, error) { + actor, err := client.GetActor(ctx, &ateapi.GetActorRequest{Actor: ref}) if err != nil { return nil, fmt.Errorf("failed to get actor %q: %w", ref.GetName(), err) } mutate(actor) - resp, err := client.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: actor}) + resp, err := client.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: actor}) if err != nil { return nil, fmt.Errorf("failed to update actor: %w", err) } @@ -350,7 +350,7 @@ func updateActor(ctx context.Context, client actorUpdater, ref *ateapipb.ObjectR // parseWorkerSelector parses a comma-separated key=value label selector into a // Selector proto. An empty string returns nil, which clears the actor's // worker_selector on update. -func parseWorkerSelector(raw string) (*ateapipb.Selector, error) { +func parseWorkerSelector(raw string) (*ateapi.Selector, error) { if raw == "" { return nil, nil } @@ -374,12 +374,12 @@ func parseWorkerSelector(raw string) (*ateapipb.Selector, error) { if len(matchLabels) > maxWorkerSelectorLabels { return nil, fmt.Errorf("invalid worker selector %q: at most %d labels are allowed, got %d", raw, maxWorkerSelectorLabels, len(matchLabels)) } - return &ateapipb.Selector{MatchLabels: matchLabels}, nil + return &ateapi.Selector{MatchLabels: matchLabels}, nil } // AteAPIClient abstracts the gRPC client calls. type AteAPIClient interface { - GetActor(ctx context.Context, in *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) + GetActor(ctx context.Context, in *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) Close() } @@ -433,7 +433,7 @@ func (r *LogsActorRunner) Run(ctx context.Context) error { } func (r *LogsActorRunner) runOneShot(ctx context.Context) error { - actor, err := r.apiClient.GetActor(ctx, &ateapipb.GetActorRequest{Actor: r.actorRef.ToObjectRef()}) + actor, err := r.apiClient.GetActor(ctx, &ateapi.GetActorRequest{Actor: r.actorRef.ToObjectRef()}) if err != nil { return fmt.Errorf("failed to get actor: %w", err) } @@ -441,7 +441,7 @@ func (r *LogsActorRunner) runOneShot(ctx context.Context) error { podName := actor.GetStatus().GetWorkerAssignment().GetWorkerPod() namespace := actor.GetStatus().GetWorkerAssignment().GetWorkerNamespace() - if podName == "" || namespace == "" || actor.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if podName == "" || namespace == "" || actor.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING { return fmt.Errorf("actor %s is not currently running on any worker pod", r.actorRef) } @@ -474,7 +474,7 @@ func (r *LogsActorRunner) runFollow(ctx context.Context) error { // lastWorkerPod, the resume cursor for a reconnect to it. var lastSeenTime time.Time var waitingLogged bool - var lastWaitingState ateapipb.ActorState + var lastWaitingState ateapi.ActorState for { select { @@ -483,7 +483,7 @@ func (r *LogsActorRunner) runFollow(ctx context.Context) error { default: } - actor, err := r.apiClient.GetActor(ctx, &ateapipb.GetActorRequest{Actor: r.actorRef.ToObjectRef()}) + actor, err := r.apiClient.GetActor(ctx, &ateapi.GetActorRequest{Actor: r.actorRef.ToObjectRef()}) if err != nil { if status.Code(err) == codes.NotFound { return fmt.Errorf("actor %s not found: %w", r.actorRef, err) @@ -501,7 +501,7 @@ func (r *LogsActorRunner) runFollow(ctx context.Context) error { namespace := actor.GetStatus().GetWorkerAssignment().GetWorkerNamespace() state := actor.GetStatus().GetState() - if podName == "" || namespace == "" || state != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if podName == "" || namespace == "" || state != ateapi.ActorState_ACTOR_STATE_RUNNING { if !waitingLogged || state != lastWaitingState { vlogf(r.stderr, vBasic, "Actor %s is not running (state=%s); waiting for worker assignment...", r.actorRef, state) waitingLogged = true @@ -614,7 +614,7 @@ func (r *LogsActorRunner) startMigrationMonitor( case <-ctx.Done(): return case <-ticker.C: - resp, err := r.apiClient.GetActor(ctx, &ateapipb.GetActorRequest{Actor: r.actorRef.ToObjectRef()}) + resp, err := r.apiClient.GetActor(ctx, &ateapi.GetActorRequest{Actor: r.actorRef.ToObjectRef()}) if err != nil { if ctx.Err() == nil { vlogf(r.stderr, vBasic, "Migration monitor failed to get actor %s: %v", r.actorRef, err) @@ -622,7 +622,7 @@ func (r *LogsActorRunner) startMigrationMonitor( continue } act := resp - if act.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_RUNNING || act.GetStatus().GetWorkerAssignment().GetWorkerPod() != currentPod { + if act.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_RUNNING || act.GetStatus().GetWorkerAssignment().GetWorkerPod() != currentPod { // Actor suspended or migrated! Cancel stream context to reconnect. vlogf(r.stderr, vBasic, "Actor %s left pod %s (state=%s, pod=%s); closing current log stream", r.actorRef, currentPod, act.GetStatus().GetState(), act.GetStatus().GetWorkerAssignment().GetWorkerPod()) diff --git a/cmd/kubectl-ate/internal/cmd/actor_test.go b/cmd/kubectl-ate/internal/cmd/actor_test.go index f7b72b79a1..a4c049d827 100644 --- a/cmd/kubectl-ate/internal/cmd/actor_test.go +++ b/cmd/kubectl-ate/internal/cmd/actor_test.go @@ -25,8 +25,8 @@ import ( "time" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -49,43 +49,43 @@ func TestBuildCreateActorRequest(t *testing.T) { name string templateRef string tag string - want *ateapipb.Actor + want *ateapi.Actor wantErr bool }{ { name: "bare template name defaults to the actor's atespace", templateRef: "counter", - want: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "demo", Name: "my-counter"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "demo", Name: "counter"}, + want: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "demo", Name: "my-counter"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "demo", Name: "counter"}, }, }, { name: "bare tag name defaults to the actor's atespace", templateRef: "counter", tag: "before-upgrade", - want: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "demo", Name: "my-counter"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "demo", Name: "counter"}, - SourceTag: &ateapipb.ObjectRef{Atespace: "demo", Name: "before-upgrade"}, + want: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "demo", Name: "my-counter"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "demo", Name: "counter"}, + SourceTag: &ateapi.ObjectRef{Atespace: "demo", Name: "before-upgrade"}, }, }, { name: "qualified tag in a different atespace", templateRef: "counter", tag: "other-atespace/before-upgrade", - want: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "demo", Name: "my-counter"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "demo", Name: "counter"}, - SourceTag: &ateapipb.ObjectRef{Atespace: "other-atespace", Name: "before-upgrade"}, + want: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "demo", Name: "my-counter"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "demo", Name: "counter"}, + SourceTag: &ateapi.ObjectRef{Atespace: "other-atespace", Name: "before-upgrade"}, }, }, { name: "qualified template in a different atespace", templateRef: "shared-templates/counter", - want: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "demo", Name: "my-counter"}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "shared-templates", Name: "counter"}, + want: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "demo", Name: "my-counter"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "shared-templates", Name: "counter"}, }, }, {name: "malformed template ref", templateRef: "a/b/c", wantErr: true}, @@ -101,7 +101,7 @@ func TestBuildCreateActorRequest(t *testing.T) { if test.wantErr { return } - want := &ateapipb.CreateActorRequest{Actor: test.want} + want := &ateapi.CreateActorRequest{Actor: test.want} if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" { t.Errorf("request mismatch (-want +got):\n%s", diff) } @@ -112,18 +112,18 @@ func TestBuildCreateActorRequest(t *testing.T) { func TestBuildSuspendActorRequest(t *testing.T) { tests := []struct { name string - mode ateapipb.DurabilityMode + mode ateapi.DurabilityMode }{ - {name: "async", mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, - {name: "sync", mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + {name: "async", mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + {name: "sync", mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { got := buildSuspendActorRequest(resources.ActorRef{Atespace: "demo", Name: "my-counter"}, test.mode) - want := &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: "demo", Name: "my-counter"}, - Options: &ateapipb.SuspendOptions{Mode: test.mode}, + want := &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: "demo", Name: "my-counter"}, + Options: &ateapi.SuspendOptions{Mode: test.mode}, } if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" { t.Errorf("request mismatch (-want +got):\n%s", diff) @@ -136,11 +136,11 @@ func TestParseSuspendMode(t *testing.T) { tests := []struct { name string mode string - want ateapipb.DurabilityMode + want ateapi.DurabilityMode wantErr string }{ - {name: "async", mode: "async", want: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, - {name: "sync", mode: "sync", want: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + {name: "async", mode: "async", want: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + {name: "sync", mode: "sync", want: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, {name: "empty", mode: "", wantErr: `invalid --mode "": must be one of async, sync`}, {name: "unknown", mode: "durable", wantErr: `invalid --mode "durable": must be one of async, sync`}, } @@ -178,7 +178,7 @@ func TestParseWorkerSelector(t *testing.T) { tests := []struct { name string raw string - want *ateapipb.Selector + want *ateapi.Selector wantErr string }{ { @@ -189,12 +189,12 @@ func TestParseWorkerSelector(t *testing.T) { { name: "single label", raw: "tier=paid", - want: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}}, + want: &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}}, }, { name: "multiple labels with prefixed key and empty value", raw: "ate.dev/pool=fast,tier=paid,empty=", - want: &ateapipb.Selector{MatchLabels: map[string]string{ + want: &ateapi.Selector{MatchLabels: map[string]string{ "ate.dev/pool": "fast", "tier": "paid", "empty": "", @@ -203,7 +203,7 @@ func TestParseWorkerSelector(t *testing.T) { { name: "exactly 10 labels is allowed", raw: "k1=v1,k2=v2,k3=v3,k4=v4,k5=v5,k6=v6,k7=v7,k8=v8,k9=v9,k10=v10", - want: &ateapipb.Selector{MatchLabels: map[string]string{ + want: &ateapi.Selector{MatchLabels: map[string]string{ "k1": "v1", "k2": "v2", "k3": "v3", "k4": "v4", "k5": "v5", "k6": "v6", "k7": "v7", "k8": "v8", "k9": "v9", "k10": "v10", }}, @@ -260,91 +260,91 @@ func TestParseWorkerSelector(t *testing.T) { } type fakeActorUpdater struct { - actor *ateapipb.Actor + actor *ateapi.Actor getErr error updateErr error getCalls int - updateReq *ateapipb.UpdateActorRequest + updateReq *ateapi.UpdateActorRequest } -func (f *fakeActorUpdater) GetActor(_ context.Context, _ *ateapipb.GetActorRequest, _ ...grpc.CallOption) (*ateapipb.Actor, error) { +func (f *fakeActorUpdater) GetActor(_ context.Context, _ *ateapi.GetActorRequest, _ ...grpc.CallOption) (*ateapi.Actor, error) { f.getCalls++ if f.getErr != nil { return nil, f.getErr } - return proto.Clone(f.actor).(*ateapipb.Actor), nil + return proto.Clone(f.actor).(*ateapi.Actor), nil } -func (f *fakeActorUpdater) UpdateActor(_ context.Context, in *ateapipb.UpdateActorRequest, _ ...grpc.CallOption) (*ateapipb.Actor, error) { +func (f *fakeActorUpdater) UpdateActor(_ context.Context, in *ateapi.UpdateActorRequest, _ ...grpc.CallOption) (*ateapi.Actor, error) { f.updateReq = in if f.updateErr != nil { return nil, f.updateErr } - updated := proto.Clone(in.GetActor()).(*ateapipb.Actor) + updated := proto.Clone(in.GetActor()).(*ateapi.Actor) updated.Metadata.Version++ return updated, nil } func TestUpdateActor(t *testing.T) { - baseActor := func() *ateapipb.Actor { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{ + baseActor := func() *ateapi.Actor { + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "demo", Name: "my-counter", Uid: "8ba9b6ee-2e1a-4c0f-9f4e-2f0a0f1c3d55", Version: 3, }, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "demo", Name: "counter-v1"}, - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "free"}}, - SourceTag: &ateapipb.ObjectRef{Atespace: "demo", Name: "seed-tag"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "demo", Name: "counter-v1"}, + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "free"}}, + SourceTag: &ateapi.ObjectRef{Atespace: "demo", Name: "seed-tag"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, } } tests := []struct { name string - mutate func(*ateapipb.Actor) - wantTemplate *ateapipb.ObjectRef - wantSelector *ateapipb.Selector + mutate func(*ateapi.Actor) + wantTemplate *ateapi.ObjectRef + wantSelector *ateapi.Selector }{ { name: "repoint template keeps worker selector", - mutate: func(a *ateapipb.Actor) { - a.ActorTemplate = &ateapipb.ObjectRef{Atespace: "shared", Name: "counter-v2"} + mutate: func(a *ateapi.Actor) { + a.ActorTemplate = &ateapi.ObjectRef{Atespace: "shared", Name: "counter-v2"} }, - wantTemplate: &ateapipb.ObjectRef{Atespace: "shared", Name: "counter-v2"}, - wantSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "free"}}, + wantTemplate: &ateapi.ObjectRef{Atespace: "shared", Name: "counter-v2"}, + wantSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "free"}}, }, { name: "update worker selector keeps template", - mutate: func(a *ateapipb.Actor) { - a.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid", "env": "prod"}} + mutate: func(a *ateapi.Actor) { + a.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid", "env": "prod"}} }, - wantTemplate: &ateapipb.ObjectRef{Atespace: "demo", Name: "counter-v1"}, - wantSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid", "env": "prod"}}, + wantTemplate: &ateapi.ObjectRef{Atespace: "demo", Name: "counter-v1"}, + wantSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid", "env": "prod"}}, }, { name: "nil worker selector clears existing selector", - mutate: func(a *ateapipb.Actor) { a.WorkerSelector = nil }, - wantTemplate: &ateapipb.ObjectRef{Atespace: "demo", Name: "counter-v1"}, + mutate: func(a *ateapi.Actor) { a.WorkerSelector = nil }, + wantTemplate: &ateapi.ObjectRef{Atespace: "demo", Name: "counter-v1"}, wantSelector: nil, }, { name: "update both template and worker selector", - mutate: func(a *ateapipb.Actor) { - a.ActorTemplate = &ateapipb.ObjectRef{Atespace: "demo", Name: "counter-v2"} - a.WorkerSelector = &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}} + mutate: func(a *ateapi.Actor) { + a.ActorTemplate = &ateapi.ObjectRef{Atespace: "demo", Name: "counter-v2"} + a.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}} }, - wantTemplate: &ateapipb.ObjectRef{Atespace: "demo", Name: "counter-v2"}, - wantSelector: &ateapipb.Selector{MatchLabels: map[string]string{"tier": "paid"}}, + wantTemplate: &ateapi.ObjectRef{Atespace: "demo", Name: "counter-v2"}, + wantSelector: &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}}, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { client := &fakeActorUpdater{actor: baseActor()} - ref := &ateapipb.ObjectRef{Atespace: "demo", Name: "my-counter"} + ref := &ateapi.ObjectRef{Atespace: "demo", Name: "my-counter"} got, err := updateActor(context.Background(), client, ref, tc.mutate) if err != nil { @@ -366,8 +366,8 @@ func TestUpdateActor(t *testing.T) { t.Run("GetActor error is propagated", func(t *testing.T) { client := &fakeActorUpdater{getErr: status.Error(codes.NotFound, "not found")} - ref := &ateapipb.ObjectRef{Atespace: "demo", Name: "my-counter"} - _, err := updateActor(context.Background(), client, ref, func(*ateapipb.Actor) {}) + ref := &ateapi.ObjectRef{Atespace: "demo", Name: "my-counter"} + _, err := updateActor(context.Background(), client, ref, func(*ateapi.Actor) {}) if status.Code(err) != codes.NotFound { t.Fatalf("updateActor() error = %v, want NotFound", err) } @@ -381,8 +381,8 @@ func TestUpdateActor(t *testing.T) { actor: baseActor(), updateErr: status.Error(codes.FailedPrecondition, "actor must be SUSPENDED"), } - ref := &ateapipb.ObjectRef{Atespace: "demo", Name: "my-counter"} - _, err := updateActor(context.Background(), client, ref, func(*ateapipb.Actor) {}) + ref := &ateapi.ObjectRef{Atespace: "demo", Name: "my-counter"} + _, err := updateActor(context.Background(), client, ref, func(*ateapi.Actor) {}) if status.Code(err) != codes.FailedPrecondition { t.Fatalf("updateActor() error = %v, want FailedPrecondition", err) } @@ -687,11 +687,11 @@ func TestNewLogLineFilter(t *testing.T) { } type mockAteAPIClient struct { - GetActorFunc func(ctx context.Context, in *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) + GetActorFunc func(ctx context.Context, in *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) CloseCalls int } -func (m *mockAteAPIClient) GetActor(ctx context.Context, in *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { +func (m *mockAteAPIClient) GetActor(ctx context.Context, in *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { if m.GetActorFunc != nil { return m.GetActorFunc(ctx, in, opts...) } @@ -719,15 +719,15 @@ func TestLogsActorRunner_Run_OneShotSuccess(t *testing.T) { namespace := "ns-abc" mockAPI := &mockAteAPIClient{ - GetActorFunc: func(ctx context.Context, in *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { + GetActorFunc: func(ctx context.Context, in *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { if in.GetActor().GetName() != actorName { return nil, fmt.Errorf("unexpected actor name: %s", in.GetActor().GetName()) } - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorName}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{ + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorName}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{ WorkerPod: podName, WorkerNamespace: namespace, }, @@ -841,12 +841,12 @@ func TestLogsActorRunner_Run_OneShot_SourceFilter(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { mockAPI := &mockAteAPIClient{ - GetActorFunc: func(ctx context.Context, in *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorName}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{ + GetActorFunc: func(ctx context.Context, in *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorName}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{ WorkerPod: "pod-xyz", WorkerNamespace: "ns-abc", }, @@ -903,10 +903,10 @@ func TestLogsActorRunner_Run_OneShot_ActorNotRunning(t *testing.T) { actorName := "act-123" mockAPI := &mockAteAPIClient{ - GetActorFunc: func(ctx context.Context, in *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorName}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, // not running + GetActorFunc: func(ctx context.Context, in *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorName}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, // not running }, nil }, } @@ -952,25 +952,25 @@ func TestLogsActorRunner_Run_Follow_SuspendedToRunning(t *testing.T) { var getActorMu sync.Mutex mockAPI := &mockAteAPIClient{ - GetActorFunc: func(ctx context.Context, in *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { + GetActorFunc: func(ctx context.Context, in *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { getActorMu.Lock() defer getActorMu.Unlock() getActorCalls++ if getActorCalls == 1 { // First call: suspended - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorName}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorName}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }, nil } // Subsequent calls: running - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorName}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{ + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorName}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{ WorkerPod: podName, WorkerNamespace: namespace, }, @@ -1048,7 +1048,7 @@ func TestLogsActorRunner_Run_Follow_NotFoundActor(t *testing.T) { actorName := "act-notfound" mockAPI := &mockAteAPIClient{ - GetActorFunc: func(ctx context.Context, in *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { + GetActorFunc: func(ctx context.Context, in *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { return nil, status.Error(codes.NotFound, "actor not found") }, } @@ -1093,18 +1093,18 @@ func TestLogsActorRunner_Run_Follow_ActorMigration(t *testing.T) { lineRead := make(chan struct{}) mockAPI := &mockAteAPIClient{ - GetActorFunc: func(ctx context.Context, in *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { + GetActorFunc: func(ctx context.Context, in *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { getActorMu.Lock() defer getActorMu.Unlock() getActorCalls++ if getActorCalls == 1 { // 1. Initial call for stream 1: pod-1 - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorName}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{ + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorName}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{ WorkerPod: "pod-1", WorkerNamespace: "ns", }, @@ -1120,11 +1120,11 @@ func TestLogsActorRunner_Run_Follow_ActorMigration(t *testing.T) { return nil, ctx.Err() } - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorName}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{ + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorName}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{ WorkerPod: "pod-2", WorkerNamespace: "ns", }, @@ -1212,18 +1212,18 @@ func TestLogsActorRunner_Run_Follow_ActorSuspendedMidStream(t *testing.T) { lineRead := make(chan struct{}) mockAPI := &mockAteAPIClient{ - GetActorFunc: func(ctx context.Context, in *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { + GetActorFunc: func(ctx context.Context, in *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { getActorMu.Lock() defer getActorMu.Unlock() getActorCalls++ // 1. Initial call: running on pod-1 if getActorCalls == 1 { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorName}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{ + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorName}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{ WorkerPod: "pod-1", WorkerNamespace: "ns", }, @@ -1239,26 +1239,26 @@ func TestLogsActorRunner_Run_Follow_ActorSuspendedMidStream(t *testing.T) { case <-ctx.Done(): return nil, ctx.Err() } - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorName}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorName}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }, nil } // 3. Loop reconnection call: suspended (still suspended, so it will wait) if getActorCalls == 3 { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorName}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorName}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }, nil } // 4. Subsequent loop reconnection call: running again on pod-1 - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorName}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{ + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorName}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{ WorkerPod: "pod-1", WorkerNamespace: "ns", }, @@ -1336,12 +1336,12 @@ func TestLogsActorRunner_Run_Follow_CursorIsKubeletTimestampOfLastLineRead(t *te actorName := "act-123" mockAPI := &mockAteAPIClient{ - GetActorFunc: func(ctx context.Context, in *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: actorName}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{ + GetActorFunc: func(ctx context.Context, in *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: actorName}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{ WorkerPod: "pod-xyz", WorkerNamespace: "ns-abc", }, diff --git a/cmd/kubectl-ate/internal/cmd/actortemplate.go b/cmd/kubectl-ate/internal/cmd/actortemplate.go index 8a73095942..7794ab63fa 100644 --- a/cmd/kubectl-ate/internal/cmd/actortemplate.go +++ b/cmd/kubectl-ate/internal/cmd/actortemplate.go @@ -20,8 +20,8 @@ import ( "os" "github.com/spf13/cobra" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/kubectl-ate/internal/printer" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/encoding/protojson" "sigs.k8s.io/yaml" ) @@ -52,10 +52,10 @@ var getActorTemplatesCmd = &cobra.Command{ defer apiClient.Close() if len(args) > 0 { - templates := make([]*ateapipb.ActorTemplate, 0, len(args)) + templates := make([]*ateapi.ActorTemplate, 0, len(args)) for _, name := range args { - resp, err := apiClient.GetActorTemplate(ctx, &ateapipb.GetActorTemplateRequest{ - ActorTemplate: &ateapipb.ObjectRef{Atespace: getActorTemplateAtespaceFlag, Name: name}, + resp, err := apiClient.GetActorTemplate(ctx, &ateapi.GetActorTemplateRequest{ + ActorTemplate: &ateapi.ObjectRef{Atespace: getActorTemplateAtespaceFlag, Name: name}, }) if err != nil { return fmt.Errorf("failed to get actor template %q: %w", name, err) @@ -68,11 +68,11 @@ var getActorTemplatesCmd = &cobra.Command{ return printer.PrintActorTemplatesTo(cmd.OutOrStdout(), templates, outputFmt) } - var allTemplates []*ateapipb.ActorTemplate + var allTemplates []*ateapi.ActorTemplate pageToken := "" for { - resp, err := apiClient.ListActorTemplates(ctx, &ateapipb.ListActorTemplatesRequest{ - Options: &ateapipb.ListOptions{PageSize: 100, PageToken: pageToken}, + resp, err := apiClient.ListActorTemplates(ctx, &ateapi.ListActorTemplatesRequest{ + Options: &ateapi.ListOptions{PageSize: 100, PageToken: pageToken}, Atespace: getActorTemplateAtespaceFlag, }) if err != nil { @@ -95,7 +95,7 @@ var createActorTemplateCmd = &cobra.Command{ Short: "Create an actor template from a manifest", Long: `Create an actor template from a manifest file. -The manifest is a single YAML (or JSON) document holding one ateapipb.ActorTemplate +The manifest is a single YAML (or JSON) document holding one ateapi.ActorTemplate message in its protojson form, exactly as printed by "kubectl ate get actor-template -a -o yaml". The template's atespace and name come from the manifest's metadata. @@ -120,7 +120,7 @@ Actor templates are immutable: there is no update; delete and recreate to change } defer apiClient.Close() - resp, err := apiClient.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ActorTemplate: template}) + resp, err := apiClient.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ActorTemplate: template}) if err != nil { return fmt.Errorf("failed to create actor template: %w", err) } @@ -143,8 +143,8 @@ The server also deletes the template's golden actor and golden snapshot.`, } defer c.Close() - _, err = c.DeleteActorTemplate(ctx, &ateapipb.DeleteActorTemplateRequest{ - ActorTemplate: &ateapipb.ObjectRef{Atespace: deleteActorTemplateAtespaceFlag, Name: args[0]}, + _, err = c.DeleteActorTemplate(ctx, &ateapi.DeleteActorTemplateRequest{ + ActorTemplate: &ateapi.ObjectRef{Atespace: deleteActorTemplateAtespaceFlag, Name: args[0]}, }) if err != nil { return fmt.Errorf("failed to delete actor template: %w", err) @@ -158,7 +158,7 @@ The server also deletes the template's golden actor and golden snapshot.`, // actorTemplateFromManifest parses a single protojson-shaped YAML or JSON // document into an ActorTemplate. Parsing is strict: unknown fields are an // error, so typos don't silently drop configuration. -func actorTemplateFromManifest(data []byte) (*ateapipb.ActorTemplate, error) { +func actorTemplateFromManifest(data []byte) (*ateapi.ActorTemplate, error) { jsonData, err := yaml.YAMLToJSON(data) if err != nil { return nil, fmt.Errorf("invalid YAML: %w", err) @@ -166,7 +166,7 @@ func actorTemplateFromManifest(data []byte) (*ateapipb.ActorTemplate, error) { if string(jsonData) == "null" { return nil, fmt.Errorf("manifest is empty") } - template := &ateapipb.ActorTemplate{} + template := &ateapi.ActorTemplate{} if err := protojson.Unmarshal(jsonData, template); err != nil { return nil, err } diff --git a/cmd/kubectl-ate/internal/cmd/actortemplate_test.go b/cmd/kubectl-ate/internal/cmd/actortemplate_test.go index 0374fdb129..5ce5d737fa 100644 --- a/cmd/kubectl-ate/internal/cmd/actortemplate_test.go +++ b/cmd/kubectl-ate/internal/cmd/actortemplate_test.go @@ -21,7 +21,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/protobuf/testing/protocmp" ) @@ -68,26 +68,26 @@ func TestActorTemplateFromManifest(t *testing.T) { t.Fatalf("actorTemplateFromManifest: %v", err) } - want := &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "ate-demo-counter", Name: "counter"}, - WorkerSelector: &ateapipb.Selector{MatchLabels: map[string]string{"workload": "counter"}}, - Containers: []*ateapipb.Container{{ + want := &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: "ate-demo-counter", Name: "counter"}, + WorkerSelector: &ateapi.Selector{MatchLabels: map[string]string{"workload": "counter"}}, + Containers: []*ateapi.Container{{ Name: "counter", Image: "ko://go.ate.dev/substrate/demos/counter", Command: []string{"/ko-app/counter", "--extra-port=9090"}, - WakeupProbe: &ateapipb.WakeupProbe{ - HttpGet: &ateapipb.HttpGetAction{Path: "/readyz", Port: 80}, + WakeupProbe: &ateapi.WakeupProbe{ + HttpGet: &ateapi.HttpGetAction{Path: "/readyz", Port: 80}, }, - VolumeMounts: []*ateapipb.VolumeMount{{Name: "data", MountPath: "/home/counter"}}, + VolumeMounts: []*ateapi.VolumeMount{{Name: "data", MountPath: "/home/counter"}}, }}, - Resources: &ateapipb.ResourceRequirements{Limits: &ateapipb.Resources{CpuMillicores: 1000, MemoryBytes: 512 << 20}}, - SnapshotConfig: &ateapipb.SnapshotConfig{ - PreferredFidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + Resources: &ateapi.ResourceRequirements{Limits: &ateapi.Resources{CpuMillicores: 1000, MemoryBytes: 512 << 20}}, + SnapshotConfig: &ateapi.SnapshotConfig{ + PreferredFidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, StorageLocation: "gs://ate-snapshots/ate-demo-counter/", }, - Volumes: []*ateapipb.Volume{{ + Volumes: []*ateapi.Volume{{ Name: "data", - DurableDir: &ateapipb.DurableDirVolumeSource{}, + DurableDir: &ateapi.DurableDirVolumeSource{}, }}, } if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" { @@ -121,7 +121,7 @@ func TestActorTemplateFromManifest_Errors(t *testing.T) { {name: "unknown field", manifest: "metadata: {atespace: a, name: n}\nsandboxClass: gvisor\n"}, {name: "bad enum", manifest: "snapshotConfig: {preferredFidelity: memory}\n"}, {name: "resources limits list", manifest: "resources: {limits: [{name: cpu, quantity: \"1\"}]}\n"}, - {name: "crd shape", manifest: "apiVersion: ate.dev/v1alpha1\nkind: ActorTemplate\nmetadata: {name: counter}\n"}, + {name: "crd shape", manifest: "apiVersion: ate.dev/v1\nkind: ActorTemplate\nmetadata: {name: counter}\n"}, {name: "not yaml", manifest: "\t{"}, } for _, test := range tests { diff --git a/cmd/kubectl-ate/internal/cmd/atespace.go b/cmd/kubectl-ate/internal/cmd/atespace.go index 48d673b08d..8f6bbe36b1 100644 --- a/cmd/kubectl-ate/internal/cmd/atespace.go +++ b/cmd/kubectl-ate/internal/cmd/atespace.go @@ -18,8 +18,8 @@ import ( "fmt" "github.com/spf13/cobra" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/kubectl-ate/internal/printer" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) var getAtespacesCmd = &cobra.Command{ @@ -36,9 +36,9 @@ var getAtespacesCmd = &cobra.Command{ defer apiClient.Close() if len(args) > 0 { - atespaces := make([]*ateapipb.Atespace, 0, len(args)) + atespaces := make([]*ateapi.Atespace, 0, len(args)) for _, atespaceName := range args { - resp, err := apiClient.GetAtespace(ctx, &ateapipb.GetAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: atespaceName}}) + resp, err := apiClient.GetAtespace(ctx, &ateapi.GetAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: atespaceName}}) if err != nil { return fmt.Errorf("failed to get atespace %q: %w", atespaceName, err) } @@ -50,11 +50,11 @@ var getAtespacesCmd = &cobra.Command{ return printer.PrintAtespacesTo(cmd.OutOrStdout(), atespaces, outputFmt) } - var allAtespaces []*ateapipb.Atespace + var allAtespaces []*ateapi.Atespace pageToken := "" for { - resp, err := apiClient.ListAtespaces(ctx, &ateapipb.ListAtespacesRequest{ - Options: &ateapipb.ListOptions{PageSize: 1000, PageToken: pageToken}, + resp, err := apiClient.ListAtespaces(ctx, &ateapi.ListAtespacesRequest{ + Options: &ateapi.ListOptions{PageSize: 1000, PageToken: pageToken}, }) if err != nil { return fmt.Errorf("failed to list atespaces: %w", err) @@ -82,9 +82,9 @@ var createAtespaceCmd = &cobra.Command{ } defer apiClient.Close() - resp, err := apiClient.CreateAtespace(ctx, &ateapipb.CreateAtespaceRequest{ - Atespace: &ateapipb.Atespace{ - Metadata: &ateapipb.ResourceMetadata{ + resp, err := apiClient.CreateAtespace(ctx, &ateapi.CreateAtespaceRequest{ + Atespace: &ateapi.Atespace{ + Metadata: &ateapi.ResourceMetadata{ Name: args[0], }, }, @@ -110,7 +110,7 @@ var deleteAtespaceCmd = &cobra.Command{ defer apiClient.Close() name := args[0] - if _, err := apiClient.DeleteAtespace(ctx, &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: name}}); err != nil { + if _, err := apiClient.DeleteAtespace(ctx, &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: name}}); err != nil { return fmt.Errorf("failed to delete atespace: %w", err) } diff --git a/cmd/kubectl-ate/internal/cmd/egress_policy.go b/cmd/kubectl-ate/internal/cmd/egress_policy.go index bc2c45ac46..a81785427e 100644 --- a/cmd/kubectl-ate/internal/cmd/egress_policy.go +++ b/cmd/kubectl-ate/internal/cmd/egress_policy.go @@ -22,9 +22,9 @@ import ( "io" "github.com/spf13/cobra" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/kubectl-ate/internal/printer" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -84,12 +84,12 @@ var deleteEgressPolicyCmd = &cobra.Command{ // egressPolicyFromManifest parses a single protojson-shaped YAML or JSON // document into an EgressPolicy. Parsing is strict: unknown fields are an // error. -func egressPolicyFromManifest(data []byte) (*ateapipb.EgressPolicy, error) { +func egressPolicyFromManifest(data []byte) (*ateapi.EgressPolicy, error) { jsonData, err := manifestToJSON(data) if err != nil { return nil, err } - policy := &ateapipb.EgressPolicy{} + policy := &ateapi.EgressPolicy{} if err := protojson.Unmarshal(jsonData, policy); err != nil { return nil, fmt.Errorf("invalid EgressPolicy: %w", err) } @@ -125,9 +125,9 @@ func manifestToJSON(data []byte) ([]byte, error) { // overrideEgressPolicyMetadata defaults each of metadata.atespace and // metadata.name the manifest leaves empty, then checks that both match the // command line: the atespace flag and the fixed policy name. -func overrideEgressPolicyMetadata(policy *ateapipb.EgressPolicy, atespace string) error { +func overrideEgressPolicyMetadata(policy *ateapi.EgressPolicy, atespace string) error { if policy.Metadata == nil { - policy.Metadata = &ateapipb.ResourceMetadata{} + policy.Metadata = &ateapi.ResourceMetadata{} } if policy.Metadata.Atespace == "" { policy.Metadata.Atespace = atespace @@ -146,7 +146,7 @@ func overrideEgressPolicyMetadata(policy *ateapipb.EgressPolicy, atespace string // loadEgressPolicyManifest reads a manifest from filename, or from in when // filename is "-", and parses it. -func loadEgressPolicyManifest(in io.Reader, filename string) (*ateapipb.EgressPolicy, error) { +func loadEgressPolicyManifest(in io.Reader, filename string) (*ateapi.EgressPolicy, error) { data, err := readFileOrStdin(in, filename) if err != nil { return nil, err @@ -161,15 +161,15 @@ func loadEgressPolicyManifest(in io.Reader, filename string) (*ateapipb.EgressPo // actorGetter abstracts the actor read that tells a missing actor from a // missing egress policy. type actorGetter interface { - GetActor(ctx context.Context, req *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) + GetActor(ctx context.Context, req *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) } // requireActor settles a NotFound from an egress policy RPC. The server answers // NotFound for a missing actor and for an actor without a policy alike, so it // reads the actor. It returns nil when the actor exists, which means the policy // is what is missing. -func requireActor(ctx context.Context, getter actorGetter, actor *ateapipb.ObjectRef) error { - if _, err := getter.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actor}); err != nil { +func requireActor(ctx context.Context, getter actorGetter, actor *ateapi.ObjectRef) error { + if _, err := getter.GetActor(ctx, &ateapi.GetActorRequest{Actor: actor}); err != nil { if status.Code(err) == codes.NotFound { return fmt.Errorf("actor %q in atespace %q not found", actor.GetName(), actor.GetAtespace()) } @@ -180,21 +180,21 @@ func requireActor(ctx context.Context, getter actorGetter, actor *ateapipb.Objec // egressPolicyGetter abstracts the RPCs get egress-policy makes. type egressPolicyGetter interface { - GetActorEgressPolicy(ctx context.Context, req *ateapipb.GetActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapipb.EgressPolicy, error) + GetActorEgressPolicy(ctx context.Context, req *ateapi.GetActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapi.EgressPolicy, error) actorGetter } // getEgressPolicyRunner executes the get egress-policy command logic. type getEgressPolicyRunner struct { getter egressPolicyGetter - actor *ateapipb.ObjectRef + actor *ateapi.ObjectRef outputFmt string stdout io.Writer stderr io.Writer } func (r *getEgressPolicyRunner) Run(ctx context.Context) error { - policy, err := r.getter.GetActorEgressPolicy(ctx, &ateapipb.GetActorEgressPolicyRequest{Actor: r.actor, Name: resources.SingletonName}) + policy, err := r.getter.GetActorEgressPolicy(ctx, &ateapi.GetActorEgressPolicyRequest{Actor: r.actor, Name: resources.SingletonName}) if status.Code(err) == codes.NotFound { if err := requireActor(ctx, r.getter, r.actor); err != nil { return err @@ -220,7 +220,7 @@ func runGetEgressPolicy(cmd *cobra.Command, args []string) error { runner := &getEgressPolicyRunner{ getter: apiClient, - actor: &ateapipb.ObjectRef{Atespace: egressPolicyFlags.atespace, Name: args[0]}, + actor: &ateapi.ObjectRef{Atespace: egressPolicyFlags.atespace, Name: args[0]}, outputFmt: outputFmt, stdout: cmd.OutOrStdout(), stderr: cmd.ErrOrStderr(), @@ -230,20 +230,20 @@ func runGetEgressPolicy(cmd *cobra.Command, args []string) error { // egressPolicyCreator abstracts CreateActorEgressPolicy RPC calls. type egressPolicyCreator interface { - CreateActorEgressPolicy(ctx context.Context, req *ateapipb.CreateActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapipb.EgressPolicy, error) + CreateActorEgressPolicy(ctx context.Context, req *ateapi.CreateActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapi.EgressPolicy, error) } // createEgressPolicyRunner executes the create egress-policy command logic. type createEgressPolicyRunner struct { creator egressPolicyCreator - actor *ateapipb.ObjectRef - policy *ateapipb.EgressPolicy + actor *ateapi.ObjectRef + policy *ateapi.EgressPolicy outputFmt string stdout io.Writer } func (r *createEgressPolicyRunner) Run(ctx context.Context) error { - created, err := r.creator.CreateActorEgressPolicy(ctx, &ateapipb.CreateActorEgressPolicyRequest{Actor: r.actor, EgressPolicy: r.policy}) + created, err := r.creator.CreateActorEgressPolicy(ctx, &ateapi.CreateActorEgressPolicyRequest{Actor: r.actor, EgressPolicy: r.policy}) if err != nil { return fmt.Errorf("failed to create egress policy for actor %q in atespace %q: %w", r.actor.GetName(), r.actor.GetAtespace(), err) } @@ -268,7 +268,7 @@ func runCreateEgressPolicy(cmd *cobra.Command, args []string) error { runner := &createEgressPolicyRunner{ creator: apiClient, - actor: &ateapipb.ObjectRef{Atespace: egressPolicyFlags.atespace, Name: args[0]}, + actor: &ateapi.ObjectRef{Atespace: egressPolicyFlags.atespace, Name: args[0]}, policy: policy, outputFmt: outputFmt, stdout: cmd.OutOrStdout(), @@ -278,21 +278,21 @@ func runCreateEgressPolicy(cmd *cobra.Command, args []string) error { // egressPolicyUpdater abstracts the RPCs update egress-policy makes. type egressPolicyUpdater interface { - UpdateActorEgressPolicy(ctx context.Context, req *ateapipb.UpdateActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapipb.EgressPolicy, error) + UpdateActorEgressPolicy(ctx context.Context, req *ateapi.UpdateActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapi.EgressPolicy, error) actorGetter } // updateEgressPolicyRunner executes the update egress-policy command logic. type updateEgressPolicyRunner struct { updater egressPolicyUpdater - actor *ateapipb.ObjectRef - policy *ateapipb.EgressPolicy + actor *ateapi.ObjectRef + policy *ateapi.EgressPolicy outputFmt string stdout io.Writer } func (r *updateEgressPolicyRunner) Run(ctx context.Context) error { - updated, err := r.updater.UpdateActorEgressPolicy(ctx, &ateapipb.UpdateActorEgressPolicyRequest{Actor: r.actor, EgressPolicy: r.policy}) + updated, err := r.updater.UpdateActorEgressPolicy(ctx, &ateapi.UpdateActorEgressPolicyRequest{Actor: r.actor, EgressPolicy: r.policy}) if status.Code(err) == codes.NotFound { if err := requireActor(ctx, r.updater, r.actor); err != nil { return err @@ -313,7 +313,7 @@ func (r *updateEgressPolicyRunner) Run(ctx context.Context) error { // requireEgressPolicyPreconditions rejects a manifest missing the uid and // version preconditions an update requires. The client can only see that they // are present; the server decides whether they still match. -func requireEgressPolicyPreconditions(policy *ateapipb.EgressPolicy, actor *ateapipb.ObjectRef) error { +func requireEgressPolicyPreconditions(policy *ateapi.EgressPolicy, actor *ateapi.ObjectRef) error { if policy.GetMetadata().GetUid() == "" || policy.GetMetadata().GetVersion() == 0 { return fmt.Errorf(`manifest for actor %q in atespace %q lacks the metadata.uid and metadata.version preconditions that "get egress-policy -o yaml" prints`, actor.GetName(), actor.GetAtespace()) @@ -329,7 +329,7 @@ func runUpdateEgressPolicy(cmd *cobra.Command, args []string) error { if err := overrideEgressPolicyMetadata(policy, egressPolicyFlags.atespace); err != nil { return err } - actor := &ateapipb.ObjectRef{Atespace: egressPolicyFlags.atespace, Name: args[0]} + actor := &ateapi.ObjectRef{Atespace: egressPolicyFlags.atespace, Name: args[0]} // Checked before dialing, so an unusable manifest costs no connection. if err := requireEgressPolicyPreconditions(policy, actor); err != nil { return err @@ -354,21 +354,21 @@ func runUpdateEgressPolicy(cmd *cobra.Command, args []string) error { // egressPolicyDeleter abstracts the RPCs delete egress-policy makes. type egressPolicyDeleter interface { - DeleteActorEgressPolicy(ctx context.Context, req *ateapipb.DeleteActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapipb.EgressPolicy, error) + DeleteActorEgressPolicy(ctx context.Context, req *ateapi.DeleteActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapi.EgressPolicy, error) actorGetter } // deleteEgressPolicyRunner executes the delete egress-policy command logic. type deleteEgressPolicyRunner struct { deleter egressPolicyDeleter - actor *ateapipb.ObjectRef + actor *ateapi.ObjectRef // options carries the uid/version guards; nil is an unguarded delete. - options *ateapipb.DeleteOptions + options *ateapi.DeleteOptions stdout io.Writer } func (r *deleteEgressPolicyRunner) Run(ctx context.Context) error { - _, err := r.deleter.DeleteActorEgressPolicy(ctx, &ateapipb.DeleteActorEgressPolicyRequest{Actor: r.actor, Name: resources.SingletonName, Options: r.options}) + _, err := r.deleter.DeleteActorEgressPolicy(ctx, &ateapi.DeleteActorEgressPolicyRequest{Actor: r.actor, Name: resources.SingletonName, Options: r.options}) if status.Code(err) == codes.NotFound { if err := requireActor(ctx, r.deleter, r.actor); err != nil { return err @@ -393,7 +393,7 @@ type deleteGuardFlags struct { // deleteOptionsFromFlags rejects a passed guard that is empty or zero, which // the server would read as "skip the check". -func deleteOptionsFromFlags(f deleteGuardFlags) (*ateapipb.DeleteOptions, error) { +func deleteOptionsFromFlags(f deleteGuardFlags) (*ateapi.DeleteOptions, error) { if !f.uidSet && !f.versionSet { return nil, nil } @@ -403,7 +403,7 @@ func deleteOptionsFromFlags(f deleteGuardFlags) (*ateapipb.DeleteOptions, error) if f.versionSet && f.version < 1 { return nil, fmt.Errorf("--version must be at least 1, got %d", f.version) } - return &ateapipb.DeleteOptions{Uid: f.uid, Version: f.version}, nil + return &ateapi.DeleteOptions{Uid: f.uid, Version: f.version}, nil } func runDeleteEgressPolicy(cmd *cobra.Command, args []string) error { @@ -427,7 +427,7 @@ func runDeleteEgressPolicy(cmd *cobra.Command, args []string) error { runner := &deleteEgressPolicyRunner{ deleter: apiClient, - actor: &ateapipb.ObjectRef{Atespace: egressPolicyFlags.atespace, Name: args[0]}, + actor: &ateapi.ObjectRef{Atespace: egressPolicyFlags.atespace, Name: args[0]}, options: options, stdout: cmd.OutOrStdout(), } diff --git a/cmd/kubectl-ate/internal/cmd/egress_policy_test.go b/cmd/kubectl-ate/internal/cmd/egress_policy_test.go index 8faae33123..0ffa37d77b 100644 --- a/cmd/kubectl-ate/internal/cmd/egress_policy_test.go +++ b/cmd/kubectl-ate/internal/cmd/egress_policy_test.go @@ -25,9 +25,9 @@ import ( "github.com/google/go-cmp/cmp" "github.com/spf13/cobra" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/kubectl-ate/internal/printer" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -39,15 +39,15 @@ import ( func TestEgressPolicyFromManifest(t *testing.T) { t.Parallel() - fullMetadata := &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "default"} - httpRules := []*ateapipb.EgressRule{{Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}}}} - tlsRules := []*ateapipb.EgressRule{{TlsPassthrough: &ateapipb.TlsPassthroughRule{Hostnames: []string{"*.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{443}}}}} - anyRules := []*ateapipb.EgressRule{{Http: &ateapipb.HttpRule{Hostnames: []string{"*"}}}} + fullMetadata := &ateapi.ResourceMetadata{Atespace: "team-a", Name: "default"} + httpRules := []*ateapi.EgressRule{{Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}}}} + tlsRules := []*ateapi.EgressRule{{TlsPassthrough: &ateapi.TlsPassthroughRule{Hostnames: []string{"*.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{443}}}}} + anyRules := []*ateapi.EgressRule{{Http: &ateapi.HttpRule{Hostnames: []string{"*"}}}} tests := []struct { name string manifest string - want *ateapipb.EgressPolicy + want *ateapi.EgressPolicy wantErr bool // wantErrContains is checked only for errors this package produces. wantErrContains string @@ -62,7 +62,7 @@ rules: hostnames: - api.example.com `, - want: &ateapipb.EgressPolicy{Metadata: fullMetadata, Rules: httpRules}, + want: &ateapi.EgressPolicy{Metadata: fullMetadata, Rules: httpRules}, }, { name: "snake case tls_passthrough", @@ -70,7 +70,7 @@ rules: rules: - tls_passthrough: {hostnames: ["*.example.com"], ports: {numbers: [443]}} `, - want: &ateapipb.EgressPolicy{Metadata: fullMetadata, Rules: tlsRules}, + want: &ateapi.EgressPolicy{Metadata: fullMetadata, Rules: tlsRules}, }, { name: "star pattern", @@ -78,14 +78,14 @@ rules: rules: - http: {hostnames: ["*"]} `, - want: &ateapipb.EgressPolicy{Metadata: fullMetadata, Rules: anyRules}, + want: &ateapi.EgressPolicy{Metadata: fullMetadata, Rules: anyRules}, }, { name: "metadata omitted is left nil", manifest: `rules: - http: {hostnames: [api.example.com]} `, - want: &ateapipb.EgressPolicy{Rules: httpRules}, + want: &ateapi.EgressPolicy{Rules: httpRules}, }, { name: "uid version and timestamps preserved", @@ -98,8 +98,8 @@ rules: rules: - http: {hostnames: [api.example.com]} `, - want: &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{ + want: &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "team-a", Name: "default", Uid: "3f2b1c0e-8d5a-4b6e-9c1d-2a7e4f6b8c0d", @@ -112,14 +112,14 @@ rules: { name: "json input", manifest: `{"metadata": {"atespace": "team-a", "name": "default"}, "rules": [{"tls_passthrough": {"hostnames": ["*.example.com"], "ports": {"numbers": [443]}}}]}`, - want: &ateapipb.EgressPolicy{Metadata: fullMetadata, Rules: tlsRules}, + want: &ateapi.EgressPolicy{Metadata: fullMetadata, Rules: tlsRules}, }, {name: "empty", manifest: "", wantErr: true, wantErrContains: "manifest is empty"}, {name: "unknown field", manifest: "rulez: []", wantErr: true, wantErrContains: "invalid EgressPolicy"}, {name: "rules not a list", manifest: "rules: {http: {}}", wantErr: true}, { name: "crd shape", - manifest: `apiVersion: ate.dev/v1alpha1 + manifest: `apiVersion: ate.dev/v1 kind: EgressPolicy metadata: {name: default} `, @@ -132,7 +132,7 @@ metadata: {name: default} rules: - http: {hostnames: ["*"]} `, - want: &ateapipb.EgressPolicy{Rules: anyRules}, + want: &ateapi.EgressPolicy{Rules: anyRules}, }, { name: "document end marker", @@ -140,7 +140,7 @@ rules: - http: {hostnames: ["*"]} ... `, - want: &ateapipb.EgressPolicy{Rules: anyRules}, + want: &ateapi.EgressPolicy{Rules: anyRules}, }, { name: "trailing document separator", @@ -284,49 +284,49 @@ rules: func TestOverrideEgressPolicyMetadata(t *testing.T) { t.Parallel() - rules := []*ateapipb.EgressRule{{Http: &ateapipb.HttpRule{Hostnames: []string{"*"}}}} - filled := &ateapipb.EgressPolicy{Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "default"}, Rules: rules} - pinned := &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "default", Uid: "3f2b1c0e-8d5a-4b6e-9c1d-2a7e4f6b8c0d", Version: 2} + rules := []*ateapi.EgressRule{{Http: &ateapi.HttpRule{Hostnames: []string{"*"}}}} + filled := &ateapi.EgressPolicy{Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "default"}, Rules: rules} + pinned := &ateapi.ResourceMetadata{Atespace: "team-a", Name: "default", Uid: "3f2b1c0e-8d5a-4b6e-9c1d-2a7e4f6b8c0d", Version: 2} tests := []struct { name string - policy *ateapipb.EgressPolicy - want *ateapipb.EgressPolicy + policy *ateapi.EgressPolicy + want *ateapi.EgressPolicy wantErrContains string }{ { name: "metadata omitted is filled", - policy: &ateapipb.EgressPolicy{Rules: rules}, + policy: &ateapi.EgressPolicy{Rules: rules}, want: filled, }, { name: "empty metadata object is filled", - policy: &ateapipb.EgressPolicy{Metadata: &ateapipb.ResourceMetadata{}, Rules: rules}, + policy: &ateapi.EgressPolicy{Metadata: &ateapi.ResourceMetadata{}, Rules: rules}, want: filled, }, { name: "name omitted is filled", - policy: &ateapipb.EgressPolicy{Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a"}, Rules: rules}, + policy: &ateapi.EgressPolicy{Metadata: &ateapi.ResourceMetadata{Atespace: "team-a"}, Rules: rules}, want: filled, }, { name: "atespace omitted is filled", - policy: &ateapipb.EgressPolicy{Metadata: &ateapipb.ResourceMetadata{Name: "default"}, Rules: rules}, + policy: &ateapi.EgressPolicy{Metadata: &ateapi.ResourceMetadata{Name: "default"}, Rules: rules}, want: filled, }, { name: "matching metadata is kept", - policy: &ateapipb.EgressPolicy{Metadata: proto.Clone(pinned).(*ateapipb.ResourceMetadata), Rules: rules}, - want: &ateapipb.EgressPolicy{Metadata: pinned, Rules: rules}, + policy: &ateapi.EgressPolicy{Metadata: proto.Clone(pinned).(*ateapi.ResourceMetadata), Rules: rules}, + want: &ateapi.EgressPolicy{Metadata: pinned, Rules: rules}, }, { name: "atespace mismatch", - policy: &ateapipb.EgressPolicy{Metadata: &ateapipb.ResourceMetadata{Atespace: "dev"}, Rules: rules}, + policy: &ateapi.EgressPolicy{Metadata: &ateapi.ResourceMetadata{Atespace: "dev"}, Rules: rules}, wantErrContains: `metadata.atespace "dev" does not match --atespace "team-a"`, }, { name: "name mismatch", - policy: &ateapipb.EgressPolicy{Metadata: &ateapipb.ResourceMetadata{Name: "other"}, Rules: rules}, + policy: &ateapi.EgressPolicy{Metadata: &ateapi.ResourceMetadata{Name: "other"}, Rules: rules}, wantErrContains: `metadata.name "other" must be "default"`, }, } @@ -356,8 +356,8 @@ func TestOverrideEgressPolicyMetadata(t *testing.T) { func TestEgressPolicyManifest_RoundTrip(t *testing.T) { t.Parallel() - policy := &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{ + policy := &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "team-a", Name: "default", Uid: "3f2b1c0e-8d5a-4b6e-9c1d-2a7e4f6b8c0d", @@ -365,12 +365,12 @@ func TestEgressPolicyManifest_RoundTrip(t *testing.T) { CreateTime: timestamppb.New(time.Date(2026, 1, 1, 11, 55, 0, 0, time.UTC)), UpdateTime: timestamppb.New(time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC)), }, - Rules: []*ateapipb.EgressRule{ - {Http: &ateapipb.HttpRule{Hostnames: []string{"*.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{80, 8080}}}}, - {Https: &ateapipb.HttpsRule{Hostnames: []string{"api.example.com"}, Effects: &ateapipb.HttpRuleEffects{ - ReplaceHeaders: []*ateapipb.CredentialHeader{{Header: "authorization", Prefix: "Bearer ", CredentialUri: "ate-secret://k8s/default/token"}}, + Rules: []*ateapi.EgressRule{ + {Http: &ateapi.HttpRule{Hostnames: []string{"*.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{80, 8080}}}}, + {Https: &ateapi.HttpsRule{Hostnames: []string{"api.example.com"}, Effects: &ateapi.HttpRuleEffects{ + ReplaceHeaders: []*ateapi.CredentialHeader{{Header: "authorization", Prefix: "Bearer ", CredentialUri: "ate-secret://k8s/default/token"}}, }}}, - {TlsPassthrough: &ateapipb.TlsPassthroughRule{Hostnames: []string{"*"}, Ports: &ateapipb.Ports{All: &ateapipb.AllPorts{}}}}, + {TlsPassthrough: &ateapi.TlsPassthroughRule{Hostnames: []string{"*"}, Ports: &ateapi.Ports{All: &ateapi.AllPorts{}}}}, }, } @@ -422,22 +422,22 @@ func TestEgressPolicyCommandArgs(t *testing.T) { // NotFound, and answers with a configured error. actorReq stays nil unless the // runner reads the actor. type fakeActorReader struct { - actorReq *ateapipb.GetActorRequest + actorReq *ateapi.GetActorRequest actorErr error } -func (f *fakeActorReader) GetActor(ctx context.Context, req *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { +func (f *fakeActorReader) GetActor(ctx context.Context, req *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { f.actorReq = req if f.actorErr != nil { return nil, f.actorErr } - return &ateapipb.Actor{}, nil + return &ateapi.Actor{}, nil } func TestRequireActor(t *testing.T) { t.Parallel() - actor := &ateapipb.ObjectRef{Atespace: "team-a", Name: "c1"} + actor := &ateapi.ObjectRef{Atespace: "team-a", Name: "c1"} tests := []struct { name string actorErr error @@ -469,7 +469,7 @@ func TestRequireActor(t *testing.T) { if gotErr != test.wantErr { t.Errorf("requireActor() error = %q, want %q", gotErr, test.wantErr) } - if diff := cmp.Diff(&ateapipb.GetActorRequest{Actor: actor}, getter.actorReq, protocmp.Transform()); diff != "" { + if diff := cmp.Diff(&ateapi.GetActorRequest{Actor: actor}, getter.actorReq, protocmp.Transform()); diff != "" { t.Errorf("actor request mismatch (-want +got):\n%s", diff) } }) @@ -480,12 +480,12 @@ func TestRequireActor(t *testing.T) { // configured policy or error. type fakeEgressPolicyGetter struct { fakeActorReader - req *ateapipb.GetActorEgressPolicyRequest - policy *ateapipb.EgressPolicy + req *ateapi.GetActorEgressPolicyRequest + policy *ateapi.EgressPolicy err error } -func (f *fakeEgressPolicyGetter) GetActorEgressPolicy(ctx context.Context, req *ateapipb.GetActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapipb.EgressPolicy, error) { +func (f *fakeEgressPolicyGetter) GetActorEgressPolicy(ctx context.Context, req *ateapi.GetActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapi.EgressPolicy, error) { f.req = req if f.err != nil { return nil, f.err @@ -497,24 +497,24 @@ func TestGetEgressPolicyRunner_Run(t *testing.T) { now := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC) pinTime(t, now) - actor := &ateapipb.ObjectRef{Atespace: "team-a", Name: "c1"} - policy := &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{ + actor := &ateapi.ObjectRef{Atespace: "team-a", Name: "c1"} + policy := &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "team-a", Name: "default", Uid: "3f2b1c0e-8d5a-4b6e-9c1d-2a7e4f6b8c0d", Version: 1, CreateTime: timestamppb.New(now.Add(-5 * time.Minute)), // table row prints AGE 5m }, - Rules: []*ateapipb.EgressRule{{Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}}}}, + Rules: []*ateapi.EgressRule{{Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}}}}, } tests := []struct { name string outputFmt string getter *fakeEgressPolicyGetter - wantReq *ateapipb.GetActorEgressPolicyRequest - wantActorReq *ateapipb.GetActorRequest + wantReq *ateapi.GetActorEgressPolicyRequest + wantActorReq *ateapi.GetActorRequest wantOut string wantErrOut string wantErr string @@ -523,7 +523,7 @@ func TestGetEgressPolicyRunner_Run(t *testing.T) { name: "table by default", outputFmt: "table", getter: &fakeEgressPolicyGetter{policy: policy}, - wantReq: &ateapipb.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}, + wantReq: &ateapi.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}, wantOut: `ATESPACE ACTOR RULES VERSION AGE team-a c1 1 1 5m `, @@ -532,7 +532,7 @@ team-a c1 1 1 5m name: "yaml", outputFmt: "yaml", getter: &fakeEgressPolicyGetter{policy: policy}, - wantReq: &ateapipb.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}, + wantReq: &ateapi.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}, wantOut: `metadata: atespace: team-a createTime: "2026-01-01T11:55:00Z" @@ -549,31 +549,31 @@ rules: name: "no policy on an existing actor writes a note and succeeds", outputFmt: "yaml", getter: &fakeEgressPolicyGetter{err: status.Error(codes.NotFound, "EgressPolicy not found")}, - wantReq: &ateapipb.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}, - wantActorReq: &ateapipb.GetActorRequest{Actor: actor}, + wantReq: &ateapi.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}, + wantActorReq: &ateapi.GetActorRequest{Actor: actor}, wantErrOut: "actor \"c1\" in atespace \"team-a\" has no egress policy\n", }, { name: "missing actor fails", outputFmt: "yaml", getter: &fakeEgressPolicyGetter{err: status.Error(codes.NotFound, "EgressPolicy not found"), fakeActorReader: fakeActorReader{actorErr: status.Error(codes.NotFound, "Actor team-a/c1 not found")}}, - wantReq: &ateapipb.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}, - wantActorReq: &ateapipb.GetActorRequest{Actor: actor}, + wantReq: &ateapi.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}, + wantActorReq: &ateapi.GetActorRequest{Actor: actor}, wantErr: `actor "c1" in atespace "team-a" not found`, }, { name: "actor lookup error wraps", outputFmt: "yaml", getter: &fakeEgressPolicyGetter{err: status.Error(codes.NotFound, "EgressPolicy not found"), fakeActorReader: fakeActorReader{actorErr: status.Error(codes.PermissionDenied, "denied")}}, - wantReq: &ateapipb.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}, - wantActorReq: &ateapipb.GetActorRequest{Actor: actor}, + wantReq: &ateapi.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}, + wantActorReq: &ateapi.GetActorRequest{Actor: actor}, wantErr: `failed to get actor "c1" in atespace "team-a": rpc error: code = PermissionDenied desc = denied`, }, { name: "other error wraps", outputFmt: "table", getter: &fakeEgressPolicyGetter{err: status.Error(codes.Unavailable, "api-server down")}, - wantReq: &ateapipb.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}, + wantReq: &ateapi.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}, wantErr: `failed to get egress policy for actor "c1" in atespace "team-a": rpc error: code = Unavailable desc = api-server down`, }, } @@ -615,12 +615,12 @@ rules: // fakeEgressPolicyCreator records the request it received and answers with a // configured policy or error. type fakeEgressPolicyCreator struct { - req *ateapipb.CreateActorEgressPolicyRequest - policy *ateapipb.EgressPolicy + req *ateapi.CreateActorEgressPolicyRequest + policy *ateapi.EgressPolicy err error } -func (f *fakeEgressPolicyCreator) CreateActorEgressPolicy(ctx context.Context, req *ateapipb.CreateActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapipb.EgressPolicy, error) { +func (f *fakeEgressPolicyCreator) CreateActorEgressPolicy(ctx context.Context, req *ateapi.CreateActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapi.EgressPolicy, error) { f.req = req if f.err != nil { return nil, f.err @@ -632,16 +632,16 @@ func TestCreateEgressPolicyRunner_Run(t *testing.T) { now := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC) pinTime(t, now) - actor := &ateapipb.ObjectRef{Atespace: "team-a", Name: "c1"} - rules := []*ateapipb.EgressRule{{Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}}}} + actor := &ateapi.ObjectRef{Atespace: "team-a", Name: "c1"} + rules := []*ateapi.EgressRule{{Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}}}} // A manifest cloned from another actor still carries that actor's // server-managed fields; the CLI sends them as is and the server scrubs them. - manifest := &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "default", Uid: "old-uid", Version: 7}, + manifest := &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "default", Uid: "old-uid", Version: 7}, Rules: rules, } - created := &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{ + created := &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "team-a", Name: "default", Uid: "3f2b1c0e-8d5a-4b6e-9c1d-2a7e4f6b8c0d", @@ -650,7 +650,7 @@ func TestCreateEgressPolicyRunner_Run(t *testing.T) { }, Rules: rules, } - wantReq := &ateapipb.CreateActorEgressPolicyRequest{Actor: actor, EgressPolicy: manifest} + wantReq := &ateapi.CreateActorEgressPolicyRequest{Actor: actor, EgressPolicy: manifest} tests := []struct { name string @@ -729,12 +729,12 @@ rules: // configured policy or error. type fakeEgressPolicyUpdater struct { fakeActorReader - req *ateapipb.UpdateActorEgressPolicyRequest - policy *ateapipb.EgressPolicy + req *ateapi.UpdateActorEgressPolicyRequest + policy *ateapi.EgressPolicy err error } -func (f *fakeEgressPolicyUpdater) UpdateActorEgressPolicy(ctx context.Context, req *ateapipb.UpdateActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapipb.EgressPolicy, error) { +func (f *fakeEgressPolicyUpdater) UpdateActorEgressPolicy(ctx context.Context, req *ateapi.UpdateActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapi.EgressPolicy, error) { f.req = req if f.err != nil { return nil, f.err @@ -746,16 +746,16 @@ func TestUpdateEgressPolicyRunner_Run(t *testing.T) { now := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC) pinTime(t, now) - actor := &ateapipb.ObjectRef{Atespace: "team-a", Name: "c1"} + actor := &ateapi.ObjectRef{Atespace: "team-a", Name: "c1"} const uid = "3f2b1c0e-8d5a-4b6e-9c1d-2a7e4f6b8c0d" - rules := []*ateapipb.EgressRule{ - {Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}}}, - {Https: &ateapipb.HttpsRule{Hostnames: []string{"www.example.com"}}}, + rules := []*ateapi.EgressRule{ + {Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}}}, + {Https: &ateapi.HttpsRule{Hostnames: []string{"www.example.com"}}}, } // The manifest is what `get -o yaml` printed, edited: it still carries the // uid, version, and timestamps of the policy being replaced. - manifest := &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{ + manifest := &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "team-a", Name: "default", Uid: uid, @@ -764,8 +764,8 @@ func TestUpdateEgressPolicyRunner_Run(t *testing.T) { }, Rules: rules, } - updated := &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{ + updated := &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "team-a", Name: "default", Uid: uid, @@ -775,13 +775,13 @@ func TestUpdateEgressPolicyRunner_Run(t *testing.T) { }, Rules: rules, } - wantReq := &ateapipb.UpdateActorEgressPolicyRequest{Actor: actor, EgressPolicy: manifest} + wantReq := &ateapi.UpdateActorEgressPolicyRequest{Actor: actor, EgressPolicy: manifest} tests := []struct { name string outputFmt string updater *fakeEgressPolicyUpdater - wantActorReq *ateapipb.GetActorRequest + wantActorReq *ateapi.GetActorRequest wantOut string wantErr string }{ @@ -829,21 +829,21 @@ rules: name: "missing actor names the actor", outputFmt: "table", updater: &fakeEgressPolicyUpdater{err: status.Error(codes.NotFound, "EgressPolicy not found"), fakeActorReader: fakeActorReader{actorErr: status.Error(codes.NotFound, "Actor team-a/c1 not found")}}, - wantActorReq: &ateapipb.GetActorRequest{Actor: actor}, + wantActorReq: &ateapi.GetActorRequest{Actor: actor}, wantErr: `actor "c1" in atespace "team-a" not found`, }, { name: "existing actor with no policy points at create", outputFmt: "table", updater: &fakeEgressPolicyUpdater{err: status.Error(codes.NotFound, "EgressPolicy not found")}, - wantActorReq: &ateapipb.GetActorRequest{Actor: actor}, + wantActorReq: &ateapi.GetActorRequest{Actor: actor}, wantErr: `actor "c1" in atespace "team-a" has no egress policy to update; create it with "kubectl ate create egress-policy"`, }, { name: "actor lookup error wraps", outputFmt: "table", updater: &fakeEgressPolicyUpdater{err: status.Error(codes.NotFound, "EgressPolicy not found"), fakeActorReader: fakeActorReader{actorErr: status.Error(codes.PermissionDenied, "denied")}}, - wantActorReq: &ateapipb.GetActorRequest{Actor: actor}, + wantActorReq: &ateapi.GetActorRequest{Actor: actor}, wantErr: `failed to get actor "c1" in atespace "team-a": rpc error: code = PermissionDenied desc = denied`, }, { @@ -888,24 +888,24 @@ rules: func TestRequireEgressPolicyPreconditions(t *testing.T) { t.Parallel() - actor := &ateapipb.ObjectRef{Atespace: "team-a", Name: "c1"} + actor := &ateapi.ObjectRef{Atespace: "team-a", Name: "c1"} const wantErr = `manifest for actor "c1" in atespace "team-a" lacks the metadata.uid and metadata.version preconditions that "get egress-policy -o yaml" prints` tests := []struct { name string - metadata *ateapipb.ResourceMetadata + metadata *ateapi.ResourceMetadata wantErr string }{ - {name: "uid and version present", metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "default", Uid: "u", Version: 1}}, - {name: "uid missing", metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "default", Version: 1}, wantErr: wantErr}, - {name: "version missing", metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "default", Uid: "u"}, wantErr: wantErr}, - {name: "both missing", metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "default"}, wantErr: wantErr}, + {name: "uid and version present", metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "default", Uid: "u", Version: 1}}, + {name: "uid missing", metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "default", Version: 1}, wantErr: wantErr}, + {name: "version missing", metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "default", Uid: "u"}, wantErr: wantErr}, + {name: "both missing", metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "default"}, wantErr: wantErr}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { t.Parallel() - err := requireEgressPolicyPreconditions(&ateapipb.EgressPolicy{Metadata: test.metadata}, actor) + err := requireEgressPolicyPreconditions(&ateapi.EgressPolicy{Metadata: test.metadata}, actor) gotErr := "" if err != nil { gotErr = err.Error() @@ -923,13 +923,13 @@ func TestDeleteOptionsFromFlags(t *testing.T) { tests := []struct { name string flags deleteGuardFlags - wantOptions *ateapipb.DeleteOptions + wantOptions *ateapi.DeleteOptions wantErr string }{ {name: "neither set leaves options nil"}, - {name: "uid alone", flags: deleteGuardFlags{uidSet: true, uid: "u"}, wantOptions: &ateapipb.DeleteOptions{Uid: "u"}}, - {name: "version alone", flags: deleteGuardFlags{versionSet: true, version: 3}, wantOptions: &ateapipb.DeleteOptions{Version: 3}}, - {name: "uid and version", flags: deleteGuardFlags{uidSet: true, uid: "u", versionSet: true, version: 3}, wantOptions: &ateapipb.DeleteOptions{Uid: "u", Version: 3}}, + {name: "uid alone", flags: deleteGuardFlags{uidSet: true, uid: "u"}, wantOptions: &ateapi.DeleteOptions{Uid: "u"}}, + {name: "version alone", flags: deleteGuardFlags{versionSet: true, version: 3}, wantOptions: &ateapi.DeleteOptions{Version: 3}}, + {name: "uid and version", flags: deleteGuardFlags{uidSet: true, uid: "u", versionSet: true, version: 3}, wantOptions: &ateapi.DeleteOptions{Uid: "u", Version: 3}}, {name: "empty uid rejected", flags: deleteGuardFlags{uidSet: true}, wantErr: "--uid must not be empty"}, {name: "zero version rejected", flags: deleteGuardFlags{versionSet: true}, wantErr: "--version must be at least 1, got 0"}, {name: "negative version rejected", flags: deleteGuardFlags{versionSet: true, version: -1}, wantErr: "--version must be at least 1, got -1"}, @@ -958,12 +958,12 @@ func TestDeleteOptionsFromFlags(t *testing.T) { // configured policy or error. type fakeEgressPolicyDeleter struct { fakeActorReader - req *ateapipb.DeleteActorEgressPolicyRequest - policy *ateapipb.EgressPolicy + req *ateapi.DeleteActorEgressPolicyRequest + policy *ateapi.EgressPolicy err error } -func (f *fakeEgressPolicyDeleter) DeleteActorEgressPolicy(ctx context.Context, req *ateapipb.DeleteActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapipb.EgressPolicy, error) { +func (f *fakeEgressPolicyDeleter) DeleteActorEgressPolicy(ctx context.Context, req *ateapi.DeleteActorEgressPolicyRequest, opts ...grpc.CallOption) (*ateapi.EgressPolicy, error) { f.req = req if f.err != nil { return nil, f.err @@ -974,13 +974,13 @@ func (f *fakeEgressPolicyDeleter) DeleteActorEgressPolicy(ctx context.Context, r func TestDeleteEgressPolicyRunner_Run(t *testing.T) { t.Parallel() - actor := &ateapipb.ObjectRef{Atespace: "team-a", Name: "c1"} - deleted := &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "default", Version: 1}, - Rules: []*ateapipb.EgressRule{{Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}}}}, + actor := &ateapi.ObjectRef{Atespace: "team-a", Name: "c1"} + deleted := &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "default", Version: 1}, + Rules: []*ateapi.EgressRule{{Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}}}}, } - unguarded := &ateapipb.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName} - wantActorReq := &ateapipb.GetActorRequest{Actor: actor} + unguarded := &ateapi.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName} + wantActorReq := &ateapi.GetActorRequest{Actor: actor} policyNotFound := status.Error(codes.NotFound, "EgressPolicy not found") const uid = "9a2b1c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d" confirmed := "egress policy for actor \"c1\" in atespace \"team-a\" deleted\n" @@ -988,9 +988,9 @@ func TestDeleteEgressPolicyRunner_Run(t *testing.T) { tests := []struct { name string deleter *fakeEgressPolicyDeleter - options *ateapipb.DeleteOptions - wantReq *ateapipb.DeleteActorEgressPolicyRequest - wantActorReq *ateapipb.GetActorRequest + options *ateapi.DeleteOptions + wantReq *ateapi.DeleteActorEgressPolicyRequest + wantActorReq *ateapi.GetActorRequest wantOut string wantErr string }{ @@ -1003,22 +1003,22 @@ func TestDeleteEgressPolicyRunner_Run(t *testing.T) { { name: "uid and version populate options", deleter: &fakeEgressPolicyDeleter{policy: deleted}, - options: &ateapipb.DeleteOptions{Uid: uid, Version: 3}, - wantReq: &ateapipb.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName, Options: &ateapipb.DeleteOptions{Uid: uid, Version: 3}}, + options: &ateapi.DeleteOptions{Uid: uid, Version: 3}, + wantReq: &ateapi.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName, Options: &ateapi.DeleteOptions{Uid: uid, Version: 3}}, wantOut: confirmed, }, { name: "uid alone", deleter: &fakeEgressPolicyDeleter{policy: deleted}, - options: &ateapipb.DeleteOptions{Uid: uid}, - wantReq: &ateapipb.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName, Options: &ateapipb.DeleteOptions{Uid: uid}}, + options: &ateapi.DeleteOptions{Uid: uid}, + wantReq: &ateapi.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName, Options: &ateapi.DeleteOptions{Uid: uid}}, wantOut: confirmed, }, { name: "version alone", deleter: &fakeEgressPolicyDeleter{policy: deleted}, - options: &ateapipb.DeleteOptions{Version: 3}, - wantReq: &ateapipb.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName, Options: &ateapipb.DeleteOptions{Version: 3}}, + options: &ateapi.DeleteOptions{Version: 3}, + wantReq: &ateapi.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName, Options: &ateapi.DeleteOptions{Version: 3}}, wantOut: confirmed, }, { @@ -1031,8 +1031,8 @@ func TestDeleteEgressPolicyRunner_Run(t *testing.T) { { name: "guarded delete not found still reads actor", deleter: &fakeEgressPolicyDeleter{err: policyNotFound}, - options: &ateapipb.DeleteOptions{Uid: uid, Version: 3}, - wantReq: &ateapipb.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName, Options: &ateapipb.DeleteOptions{Uid: uid, Version: 3}}, + options: &ateapi.DeleteOptions{Uid: uid, Version: 3}, + wantReq: &ateapi.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName, Options: &ateapi.DeleteOptions{Uid: uid, Version: 3}}, wantActorReq: wantActorReq, wantErr: `actor "c1" in atespace "team-a" has no egress policy`, }, @@ -1053,8 +1053,8 @@ func TestDeleteEgressPolicyRunner_Run(t *testing.T) { { name: "aborted conflict wraps", deleter: &fakeEgressPolicyDeleter{err: status.Error(codes.Aborted, "EgressPolicy version conflict")}, - options: &ateapipb.DeleteOptions{Version: 3}, - wantReq: &ateapipb.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName, Options: &ateapipb.DeleteOptions{Version: 3}}, + options: &ateapi.DeleteOptions{Version: 3}, + wantReq: &ateapi.DeleteActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName, Options: &ateapi.DeleteOptions{Version: 3}}, wantErr: `failed to delete egress policy for actor "c1" in atespace "team-a": rpc error: code = Aborted desc = EgressPolicy version conflict`, }, { @@ -1106,28 +1106,28 @@ func TestEgressPolicyFromManifest_NighthawkEgress(t *testing.T) { if err != nil { t.Fatalf("egressPolicyFromManifest: %v", err) } - want := &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{ + want := &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "nighthawk", Name: "default", }, - Rules: []*ateapipb.EgressRule{ + Rules: []*ateapi.EgressRule{ { - Http: &ateapipb.HttpRule{ + Http: &ateapi.HttpRule{ Hostnames: []string{"*"}, - Ports: &ateapipb.Ports{Numbers: []int32{80}}, + Ports: &ateapi.Ports{Numbers: []int32{80}}, }, }, { - Https: &ateapipb.HttpsRule{ + Https: &ateapi.HttpsRule{ Hostnames: []string{"*"}, - Ports: &ateapipb.Ports{Numbers: []int32{443}}, + Ports: &ateapi.Ports{Numbers: []int32{443}}, }, }, { - TlsPassthrough: &ateapipb.TlsPassthroughRule{ + TlsPassthrough: &ateapi.TlsPassthroughRule{ Hostnames: []string{"*"}, - Ports: &ateapipb.Ports{Numbers: []int32{8443}}, + Ports: &ateapi.Ports{Numbers: []int32{8443}}, }, }, }, diff --git a/cmd/kubectl-ate/internal/cmd/resourceref.go b/cmd/kubectl-ate/internal/cmd/resourceref.go index b2f43c59cf..98f8bd8a1e 100644 --- a/cmd/kubectl-ate/internal/cmd/resourceref.go +++ b/cmd/kubectl-ate/internal/cmd/resourceref.go @@ -18,13 +18,13 @@ import ( "fmt" "strings" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // parseAtespacedName parses a reference to an atespace-scoped resource, // either as / or as , which defaults to defaultAtespace -func parseAtespacedName(value, defaultAtespace string) (*ateapipb.ObjectRef, error) { +func parseAtespacedName(value, defaultAtespace string) (*ateapi.ObjectRef, error) { atespace, name, ok := strings.Cut(value, "/") if !ok { atespace, name = defaultAtespace, value @@ -32,5 +32,5 @@ func parseAtespacedName(value, defaultAtespace string) (*ateapipb.ObjectRef, err if !resources.IsValidResourceName(atespace) || !resources.IsValidResourceName(name) { return nil, fmt.Errorf("malformed reference %q (expected or /)", value) } - return &ateapipb.ObjectRef{Atespace: atespace, Name: name}, nil + return &ateapi.ObjectRef{Atespace: atespace, Name: name}, nil } diff --git a/cmd/kubectl-ate/internal/cmd/resourceref_test.go b/cmd/kubectl-ate/internal/cmd/resourceref_test.go index 8decc3ee9d..75cb1731a6 100644 --- a/cmd/kubectl-ate/internal/cmd/resourceref_test.go +++ b/cmd/kubectl-ate/internal/cmd/resourceref_test.go @@ -18,7 +18,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/protobuf/testing/protocmp" ) @@ -27,20 +27,20 @@ func TestParseAtespacedName(t *testing.T) { name string value string defaultAtespace string - want *ateapipb.ObjectRef + want *ateapi.ObjectRef wantErr bool }{ { name: "qualified reference", value: "team-a/before-upgrade", defaultAtespace: "default-atespace", - want: &ateapipb.ObjectRef{Atespace: "team-a", Name: "before-upgrade"}, + want: &ateapi.ObjectRef{Atespace: "team-a", Name: "before-upgrade"}, }, { name: "bare name uses the default atespace", value: "before-upgrade", defaultAtespace: "default-atespace", - want: &ateapipb.ObjectRef{Atespace: "default-atespace", Name: "before-upgrade"}, + want: &ateapi.ObjectRef{Atespace: "default-atespace", Name: "before-upgrade"}, }, { name: "bare name with no default atespace", diff --git a/cmd/kubectl-ate/internal/cmd/revert_actor.go b/cmd/kubectl-ate/internal/cmd/revert_actor.go index 8928ac8852..09d06219d0 100644 --- a/cmd/kubectl-ate/internal/cmd/revert_actor.go +++ b/cmd/kubectl-ate/internal/cmd/revert_actor.go @@ -18,9 +18,9 @@ import ( "fmt" "github.com/spf13/cobra" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/kubectl-ate/internal/printer" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) var revertAtespaceFlag string @@ -44,7 +44,7 @@ already at its durable snapshot, so there is nothing to revert.`, defer apiClient.Close() actorRef := resources.ActorRef{Atespace: revertAtespaceFlag, Name: args[0]} - resp, err := apiClient.RevertActor(ctx, &ateapipb.RevertActorRequest{ + resp, err := apiClient.RevertActor(ctx, &ateapi.RevertActorRequest{ Actor: actorRef.ToObjectRef(), }) if err != nil { diff --git a/cmd/kubectl-ate/internal/cmd/tag.go b/cmd/kubectl-ate/internal/cmd/tag.go index a99355971a..605c8084c7 100644 --- a/cmd/kubectl-ate/internal/cmd/tag.go +++ b/cmd/kubectl-ate/internal/cmd/tag.go @@ -20,8 +20,8 @@ import ( "strings" "github.com/spf13/cobra" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/kubectl-ate/internal/printer" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" ) @@ -54,10 +54,10 @@ var getTagsCmd = &cobra.Command{ defer client.Close() if len(args) > 0 { - tags := make([]*ateapipb.Tag, 0, len(args)) + tags := make([]*ateapi.Tag, 0, len(args)) for _, name := range args { - tag, err := client.GetTag(ctx, &ateapipb.GetTagRequest{ - Tag: &ateapipb.ObjectRef{Atespace: getTagAtespaceFlag, Name: name}, + tag, err := client.GetTag(ctx, &ateapi.GetTagRequest{ + Tag: &ateapi.ObjectRef{Atespace: getTagAtespaceFlag, Name: name}, }) if err != nil { return fmt.Errorf("failed to get tag %q: %w", name, err) @@ -70,10 +70,10 @@ var getTagsCmd = &cobra.Command{ return printer.PrintTagsTo(cmd.OutOrStdout(), tags, outputFmt) } - var tags []*ateapipb.Tag + var tags []*ateapi.Tag pageToken := "" for { - resp, err := client.ListTags(ctx, &ateapipb.ListTagsRequest{Atespace: getTagAtespaceFlag, Options: &ateapipb.ListOptions{PageSize: 1000, PageToken: pageToken}}) + resp, err := client.ListTags(ctx, &ateapi.ListTagsRequest{Atespace: getTagAtespaceFlag, Options: &ateapi.ListOptions{PageSize: 1000, PageToken: pageToken}}) if err != nil { return fmt.Errorf("failed to list tags: %w", err) } @@ -106,11 +106,11 @@ var createTagCmd = &cobra.Command{ } defer client.Close() - tag, err := client.CreateTag(ctx, &ateapipb.CreateTagRequest{ - Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: createTagAtespaceFlag, Name: args[0]}, + tag, err := client.CreateTag(ctx, &ateapi.CreateTagRequest{ + Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: createTagAtespaceFlag, Name: args[0]}, Scope: scope, - SourceActor: &ateapipb.ObjectRef{Atespace: createTagAtespaceFlag, Name: createTagActorFlag}, + SourceActor: &ateapi.ObjectRef{Atespace: createTagAtespaceFlag, Name: createTagActorFlag}, }, }) if err != nil { @@ -136,7 +136,7 @@ var updateTagCmd = &cobra.Command{ } defer client.Close() - ref := &ateapipb.ObjectRef{Atespace: updateTagAtespaceFlag, Name: args[0]} + ref := &ateapi.ObjectRef{Atespace: updateTagAtespaceFlag, Name: args[0]} resp, err := updateTagScope(ctx, client, ref, scope) if err != nil { return err @@ -157,7 +157,7 @@ var deleteTagCmd = &cobra.Command{ } defer client.Close() - _, err = client.DeleteTag(ctx, &ateapipb.DeleteTagRequest{Tag: &ateapipb.ObjectRef{Atespace: deleteTagAtespaceFlag, Name: args[0]}}) + _, err = client.DeleteTag(ctx, &ateapi.DeleteTagRequest{Tag: &ateapi.ObjectRef{Atespace: deleteTagAtespaceFlag, Name: args[0]}}) if err != nil { return fmt.Errorf("failed to delete tag: %w", err) } @@ -167,32 +167,32 @@ var deleteTagCmd = &cobra.Command{ } type tagClient interface { - GetTag(ctx context.Context, in *ateapipb.GetTagRequest, opts ...grpc.CallOption) (*ateapipb.Tag, error) - UpdateTag(ctx context.Context, in *ateapipb.UpdateTagRequest, opts ...grpc.CallOption) (*ateapipb.Tag, error) + GetTag(ctx context.Context, in *ateapi.GetTagRequest, opts ...grpc.CallOption) (*ateapi.Tag, error) + UpdateTag(ctx context.Context, in *ateapi.UpdateTagRequest, opts ...grpc.CallOption) (*ateapi.Tag, error) } -func updateTagScope(ctx context.Context, client tagClient, ref *ateapipb.ObjectRef, scope ateapipb.TagScope) (*ateapipb.Tag, error) { - tag, err := client.GetTag(ctx, &ateapipb.GetTagRequest{Tag: ref}) +func updateTagScope(ctx context.Context, client tagClient, ref *ateapi.ObjectRef, scope ateapi.TagScope) (*ateapi.Tag, error) { + tag, err := client.GetTag(ctx, &ateapi.GetTagRequest{Tag: ref}) if err != nil { return nil, fmt.Errorf("failed to get tag %q: %w", ref.GetName(), err) } tag.Scope = scope - resp, err := client.UpdateTag(ctx, &ateapipb.UpdateTagRequest{Tag: tag}) + resp, err := client.UpdateTag(ctx, &ateapi.UpdateTagRequest{Tag: tag}) if err != nil { return nil, fmt.Errorf("failed to update tag: %w", err) } return resp, nil } -func parseTagScope(value string) (ateapipb.TagScope, error) { +func parseTagScope(value string) (ateapi.TagScope, error) { switch strings.ToLower(value) { case "atespace": - return ateapipb.TagScope_TAG_SCOPE_ATESPACE, nil + return ateapi.TagScope_TAG_SCOPE_ATESPACE, nil case "published": - return ateapipb.TagScope_TAG_SCOPE_PUBLISHED, nil + return ateapi.TagScope_TAG_SCOPE_PUBLISHED, nil default: - return ateapipb.TagScope_TAG_SCOPE_UNSPECIFIED, fmt.Errorf("invalid scope %q; must be atespace or published", value) + return ateapi.TagScope_TAG_SCOPE_UNSPECIFIED, fmt.Errorf("invalid scope %q; must be atespace or published", value) } } diff --git a/cmd/kubectl-ate/internal/cmd/tag_test.go b/cmd/kubectl-ate/internal/cmd/tag_test.go index 52c3053e40..a6ae387316 100644 --- a/cmd/kubectl-ate/internal/cmd/tag_test.go +++ b/cmd/kubectl-ate/internal/cmd/tag_test.go @@ -19,7 +19,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/grpc" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" @@ -28,22 +28,22 @@ import ( // fakeTagClient serves GetTag from a stored tag and records the // update it is asked to make. type fakeTagClient struct { - tag *ateapipb.Tag + tag *ateapi.Tag getCalls int - updateReq *ateapipb.UpdateTagRequest + updateReq *ateapi.UpdateTagRequest } -func (f *fakeTagClient) GetTag(_ context.Context, _ *ateapipb.GetTagRequest, _ ...grpc.CallOption) (*ateapipb.Tag, error) { +func (f *fakeTagClient) GetTag(_ context.Context, _ *ateapi.GetTagRequest, _ ...grpc.CallOption) (*ateapi.Tag, error) { f.getCalls++ - return proto.Clone(f.tag).(*ateapipb.Tag), nil + return proto.Clone(f.tag).(*ateapi.Tag), nil } -func (f *fakeTagClient) UpdateTag(_ context.Context, in *ateapipb.UpdateTagRequest, _ ...grpc.CallOption) (*ateapipb.Tag, error) { +func (f *fakeTagClient) UpdateTag(_ context.Context, in *ateapi.UpdateTagRequest, _ ...grpc.CallOption) (*ateapi.Tag, error) { f.updateReq = in // Bump the version the way a real server does, so the returned tag is // distinguishable from the one the caller sent. - updated := proto.Clone(in.GetTag()).(*ateapipb.Tag) + updated := proto.Clone(in.GetTag()).(*ateapi.Tag) updated.Metadata.Version++ return updated, nil } @@ -51,28 +51,28 @@ func (f *fakeTagClient) UpdateTag(_ context.Context, in *ateapipb.UpdateTagReque // TestUpdateTagScope checks the read-modify-write wiring: the scope // change is written against the uid and version that were just read. func TestUpdateTagScope(t *testing.T) { - testTag := &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{ + testTag := &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "space-1", Name: "tag-1", Uid: "8ba9b6ee-2e1a-4c0f-9f4e-2f0a0f1c3d55", Version: 1, }, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - Status: &ateapipb.TagStatus{ - Snapshot: &ateapipb.Snapshot{ - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - DurableSnapshot: &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: "gs://private/atespaces/space-1/tags/tag-1"}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + Status: &ateapi.TagStatus{ + Snapshot: &ateapi.Snapshot{ + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + DurableSnapshot: &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, + Object: &ateapi.ObjectSnapshot{SnapshotUri: "gs://private/atespaces/space-1/tags/tag-1"}, }, }, }, } client := &fakeTagClient{tag: testTag} - ref := &ateapipb.ObjectRef{Atespace: "space-1", Name: "tag-1"} - want := ateapipb.TagScope_TAG_SCOPE_PUBLISHED + ref := &ateapi.ObjectRef{Atespace: "space-1", Name: "tag-1"} + want := ateapi.TagScope_TAG_SCOPE_PUBLISHED resp, err := updateTagScope(context.Background(), client, ref, want) if err != nil { @@ -92,7 +92,7 @@ func TestUpdateTagScope(t *testing.T) { } func TestParseTagScope(t *testing.T) { - if got, err := parseTagScope("published"); err != nil || got != ateapipb.TagScope_TAG_SCOPE_PUBLISHED { + if got, err := parseTagScope("published"); err != nil || got != ateapi.TagScope_TAG_SCOPE_PUBLISHED { t.Fatalf("parseTagScope(published) = (%v, %v)", got, err) } if _, err := parseTagScope("global"); err == nil { diff --git a/cmd/kubectl-ate/internal/cmd/verbose_test.go b/cmd/kubectl-ate/internal/cmd/verbose_test.go index ad36577387..66dc39863b 100644 --- a/cmd/kubectl-ate/internal/cmd/verbose_test.go +++ b/cmd/kubectl-ate/internal/cmd/verbose_test.go @@ -24,8 +24,8 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/protobuf/proto" corev1 "k8s.io/api/core/v1" @@ -75,9 +75,9 @@ func TestVlogfLevels(t *testing.T) { } func TestLoggingUnaryInterceptor(t *testing.T) { - req := &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: "demo", Name: "act-1"}} - wantActor := &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Atespace: "demo", Name: "act-1"}} - const method = ateapipb.Control_GetActor_FullMethodName + req := &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: "demo", Name: "act-1"}} + wantActor := &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Atespace: "demo", Name: "act-1"}} + const method = ateapi.Control_GetActor_FullMethodName okInvoker := func(_ context.Context, _ string, _, reply any, _ *grpc.ClientConn, _ ...grpc.CallOption) error { proto.Merge(reply.(proto.Message), wantActor) @@ -92,7 +92,7 @@ func TestLoggingUnaryInterceptor(t *testing.T) { var errOut bytes.Buffer ic := newLoggingUnaryInterceptor(&errOut) - reply := &ateapipb.Actor{} + reply := &ateapi.Actor{} if err := ic(context.Background(), method, req, reply, nil, okInvoker); err != nil { t.Fatalf("interceptor unexpected error: %v", err) } @@ -101,8 +101,8 @@ func TestLoggingUnaryInterceptor(t *testing.T) { } _ = ic(context.Background(), method, req, reply, nil, errInvoker) - if !strings.Contains(errOut.String(), "gRPC /ateapi.Control/GetActor failed") { - t.Errorf("vBasic failure stderr = %q, want 'gRPC /ateapi.Control/GetActor failed'", errOut.String()) + if !strings.Contains(errOut.String(), "gRPC /substrate.ateapi.v1.Control/GetActor failed") { + t.Errorf("vBasic failure stderr = %q, want 'gRPC /substrate.ateapi.v1.Control/GetActor failed'", errOut.String()) } }) @@ -111,12 +111,12 @@ func TestLoggingUnaryInterceptor(t *testing.T) { var errOut bytes.Buffer ic := newLoggingUnaryInterceptor(&errOut) - reply := &ateapipb.Actor{} + reply := &ateapi.Actor{} if err := ic(context.Background(), method, req, reply, nil, okInvoker); err != nil { t.Fatalf("interceptor unexpected error: %v", err) } got := errOut.String() - if !strings.Contains(got, "gRPC /ateapi.Control/GetActor\n") || !strings.Contains(got, "gRPC /ateapi.Control/GetActor completed in ") { + if !strings.Contains(got, "gRPC /substrate.ateapi.v1.Control/GetActor\n") || !strings.Contains(got, "gRPC /substrate.ateapi.v1.Control/GetActor completed in ") { t.Errorf("vFlow stderr = %q, want call and completion lines", got) } }) @@ -126,12 +126,12 @@ func TestLoggingUnaryInterceptor(t *testing.T) { var errOut bytes.Buffer ic := newLoggingUnaryInterceptor(&errOut) - reply := &ateapipb.Actor{} + reply := &ateapi.Actor{} if err := ic(context.Background(), method, req, reply, nil, okInvoker); err != nil { t.Fatalf("interceptor unexpected error: %v", err) } got := errOut.String() - if !strings.Contains(got, "gRPC /ateapi.Control/GetActor request:") || !strings.Contains(got, `"act-1"`) || !strings.Contains(got, "gRPC /ateapi.Control/GetActor response") { + if !strings.Contains(got, "gRPC /substrate.ateapi.v1.Control/GetActor request:") || !strings.Contains(got, `"act-1"`) || !strings.Contains(got, "gRPC /substrate.ateapi.v1.Control/GetActor response") { t.Errorf("vTrace stderr = %q, want request and response payloads", got) } }) @@ -143,7 +143,7 @@ func TestLogsActorRunner_FollowVerboseSurfacesDelaysAndErrors(t *testing.T) { var mu sync.Mutex var getCalls int mockAPI := &mockAteAPIClient{ - GetActorFunc: func(ctx context.Context, in *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { + GetActorFunc: func(ctx context.Context, in *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { mu.Lock() defer mu.Unlock() getCalls++ @@ -151,16 +151,16 @@ func TestLogsActorRunner_FollowVerboseSurfacesDelaysAndErrors(t *testing.T) { case 1: return nil, errors.New("transient apiserver error") case 2: - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "act-1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "act-1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }, nil default: - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Name: "act-1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{ + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Name: "act-1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{ WorkerPod: "pod-1", WorkerNamespace: "ns-1", }, @@ -217,15 +217,15 @@ func TestLogsActorRunner_FollowVerboseSurfacesDelaysAndErrors(t *testing.T) { } func TestTopWorkersRunner_VerboseSurfacesMetricsIssues(t *testing.T) { - workers := []*ateapipb.Worker{ + workers := []*ateapi.Worker{ { - Metadata: &ateapipb.ResourceMetadata{Name: "w-1"}, + Metadata: &ateapi.ResourceMetadata{Name: "w-1"}, WorkerNamespace: "ns-1", WorkerPool: "pool-1", WorkerPod: "pod-1", }, { - Metadata: &ateapipb.ResourceMetadata{Name: "w-2"}, + Metadata: &ateapi.ResourceMetadata{Name: "w-2"}, WorkerNamespace: "ns-1", WorkerPool: "pool-1", WorkerPod: "pod-2", diff --git a/cmd/kubectl-ate/internal/cmd/worker.go b/cmd/kubectl-ate/internal/cmd/worker.go index 920ee4f493..82a353db4a 100644 --- a/cmd/kubectl-ate/internal/cmd/worker.go +++ b/cmd/kubectl-ate/internal/cmd/worker.go @@ -20,10 +20,10 @@ import ( "io" "github.com/spf13/cobra" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/kubectl-ate/internal/printer" "go.ate.dev/substrate/internal/ateclient" "go.ate.dev/substrate/internal/hardware" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -62,18 +62,18 @@ var topWorkersCmd = &cobra.Command{ // WorkerLister abstracts ListWorkers RPC calls. type WorkerLister interface { - ListWorkers(ctx context.Context, req *ateapipb.ListWorkersRequest, opts ...grpc.CallOption) (*ateapipb.ListWorkersResponse, error) + ListWorkers(ctx context.Context, req *ateapi.ListWorkersRequest, opts ...grpc.CallOption) (*ateapi.ListWorkersResponse, error) } // ActorLister abstracts ListActors RPC calls, which is how the worker commands // resolve an atespace filter. type ActorLister interface { - ListActors(ctx context.Context, req *ateapipb.ListActorsRequest, opts ...grpc.CallOption) (*ateapipb.ListActorsResponse, error) + ListActors(ctx context.Context, req *ateapi.ListActorsRequest, opts ...grpc.CallOption) (*ateapi.ListActorsResponse, error) } // WorkerGetter abstracts GetWorker RPC calls. type WorkerGetter interface { - GetWorker(ctx context.Context, req *ateapipb.GetWorkerRequest, opts ...grpc.CallOption) (*ateapipb.Worker, error) + GetWorker(ctx context.Context, req *ateapi.GetWorkerRequest, opts ...grpc.CallOption) (*ateapi.Worker, error) } // workersHostingAtespace names the Workers hosting an Actor in atespace. Asked @@ -83,8 +83,8 @@ func workersHostingAtespace(ctx context.Context, lister ActorLister, atespace st hosting := map[string]bool{} pageToken := "" for { - resp, err := lister.ListActors(ctx, &ateapipb.ListActorsRequest{ - Options: &ateapipb.ListOptions{PageSize: 1000, PageToken: pageToken}, + resp, err := lister.ListActors(ctx, &ateapi.ListActorsRequest{ + Options: &ateapi.ListOptions{PageSize: 1000, PageToken: pageToken}, Atespace: atespace, }) if err != nil { @@ -103,12 +103,12 @@ func workersHostingAtespace(ctx context.Context, lister ActorLister, atespace st } // listAllWorkers pages through ListWorkers and returns all workers. -func listAllWorkers(ctx context.Context, lister WorkerLister) ([]*ateapipb.Worker, error) { - var workers []*ateapipb.Worker +func listAllWorkers(ctx context.Context, lister WorkerLister) ([]*ateapi.Worker, error) { + var workers []*ateapi.Worker pageToken := "" for { - resp, err := lister.ListWorkers(ctx, &ateapipb.ListWorkersRequest{ - Options: &ateapipb.ListOptions{PageSize: 1000, PageToken: pageToken}, + resp, err := lister.ListWorkers(ctx, &ateapi.ListWorkersRequest{ + Options: &ateapi.ListOptions{PageSize: 1000, PageToken: pageToken}, }) if err != nil { return nil, fmt.Errorf("failed to list workers: %w", err) @@ -125,7 +125,7 @@ func listAllWorkers(ctx context.Context, lister WorkerLister) ([]*ateapipb.Worke // filterWorkers filters workers by Kubernetes namespace, assigned-actor // atespace, worker pool label selector, and sandbox class. Empty values match // everything; an atespace filter only matches workers with an assigned actor. -func filterWorkers(ctx context.Context, actors ActorLister, workers []*ateapipb.Worker, namespace, atespace, selector, sandboxClass string) ([]*ateapipb.Worker, error) { +func filterWorkers(ctx context.Context, actors ActorLister, workers []*ateapi.Worker, namespace, atespace, selector, sandboxClass string) ([]*ateapi.Worker, error) { var labelSel labels.Selector if selector != "" { var err error @@ -144,7 +144,7 @@ func filterWorkers(ctx context.Context, actors ActorLister, workers []*ateapipb. } } - var filtered []*ateapipb.Worker + var filtered []*ateapi.Worker for _, w := range workers { if namespace != "" && w.GetWorkerNamespace() != namespace { continue @@ -182,9 +182,9 @@ func (r *GetWorkersRunner) Run(ctx context.Context) error { if err := validateWorkerFlags(r.names, r.namespace, r.atespace, r.selector, r.sandboxClass); err != nil { return err } - workers := make([]*ateapipb.Worker, 0, len(r.names)) + workers := make([]*ateapi.Worker, 0, len(r.names)) for _, name := range r.names { - worker, err := r.workerGetter.GetWorker(ctx, &ateapipb.GetWorkerRequest{Worker: &ateapipb.ObjectRef{Name: name}}) + worker, err := r.workerGetter.GetWorker(ctx, &ateapi.GetWorkerRequest{Worker: &ateapi.ObjectRef{Name: name}}) if err != nil { return fmt.Errorf("failed to get worker %q: %w", name, err) } diff --git a/cmd/kubectl-ate/internal/cmd/worker_test.go b/cmd/kubectl-ate/internal/cmd/worker_test.go index e560f25ecb..4be89ace16 100644 --- a/cmd/kubectl-ate/internal/cmd/worker_test.go +++ b/cmd/kubectl-ate/internal/cmd/worker_test.go @@ -22,8 +22,8 @@ import ( "time" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/kubectl-ate/internal/printer" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/protobuf/types/known/timestamppb" corev1 "k8s.io/api/core/v1" @@ -43,37 +43,37 @@ func TestWorkerCommandArgs(t *testing.T) { } type mockWorkerLister struct { - workers []*ateapipb.Worker + workers []*ateapi.Worker err error } -func (m *mockWorkerLister) ListWorkers(ctx context.Context, req *ateapipb.ListWorkersRequest, opts ...grpc.CallOption) (*ateapipb.ListWorkersResponse, error) { +func (m *mockWorkerLister) ListWorkers(ctx context.Context, req *ateapi.ListWorkersRequest, opts ...grpc.CallOption) (*ateapi.ListWorkersResponse, error) { if m.err != nil { return nil, m.err } - return &ateapipb.ListWorkersResponse{Workers: m.workers}, nil + return &ateapi.ListWorkersResponse{Workers: m.workers}, nil } // mockActorLister serves the actors of one atespace at a time, as the real // listing does, so an atespace filter sees only that atespace's placements. type mockActorLister struct { - byAtespace map[string][]*ateapipb.Actor + byAtespace map[string][]*ateapi.Actor err error } -func (m *mockActorLister) ListActors(ctx context.Context, req *ateapipb.ListActorsRequest, opts ...grpc.CallOption) (*ateapipb.ListActorsResponse, error) { +func (m *mockActorLister) ListActors(ctx context.Context, req *ateapi.ListActorsRequest, opts ...grpc.CallOption) (*ateapi.ListActorsResponse, error) { if m.err != nil { return nil, m.err } - return &ateapipb.ListActorsResponse{Actors: m.byAtespace[req.GetAtespace()]}, nil + return &ateapi.ListActorsResponse{Actors: m.byAtespace[req.GetAtespace()]}, nil } // actorOn is an actor of atespace placed on the named worker. -func actorOn(atespace, name, workerName string) *ateapipb.Actor { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: name}, - Status: &ateapipb.ActorStatus{ - WorkerAssignment: &ateapipb.WorkerAssignment{Worker: &ateapipb.ObjectRef{Name: workerName}}, +func actorOn(atespace, name, workerName string) *ateapi.Actor { + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: name}, + Status: &ateapi.ActorStatus{ + WorkerAssignment: &ateapi.WorkerAssignment{Worker: &ateapi.ObjectRef{Name: workerName}}, }, } } @@ -93,11 +93,11 @@ func (m *mockPodMetricsLister) ListPodMetrics(ctx context.Context, namespace str // mockWorkerGetter serves GetWorker calls from a name-keyed map, as the // GetWorkersRunner requires when getting workers by name. type mockWorkerGetter struct { - workers map[string]*ateapipb.Worker + workers map[string]*ateapi.Worker err error } -func (m *mockWorkerGetter) GetWorker(ctx context.Context, req *ateapipb.GetWorkerRequest, opts ...grpc.CallOption) (*ateapipb.Worker, error) { +func (m *mockWorkerGetter) GetWorker(ctx context.Context, req *ateapi.GetWorkerRequest, opts ...grpc.CallOption) (*ateapi.Worker, error) { if m.err != nil { return nil, m.err } @@ -119,46 +119,46 @@ func TestGetWorkersRunner_Filters(t *testing.T) { now := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC) pinTime(t, now) - workers := []*ateapipb.Worker{ + workers := []*ateapi.Worker{ { - Metadata: &ateapipb.ResourceMetadata{Name: "worker-1", CreateTime: timestamppb.New(now.Add(-5 * time.Minute))}, + Metadata: &ateapi.ResourceMetadata{Name: "worker-1", CreateTime: timestamppb.New(now.Add(-5 * time.Minute))}, WorkerNamespace: "ns-1", WorkerPool: "counter", WorkerPod: "pod-1", Labels: map[string]string{"ate.dev/worker-pool": "counter"}, - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, - Allocated: &ateapipb.WorkerResources{Actors: 1}, - SandboxClasses: []*ateapipb.WorkerSandboxClass{{SandboxClass: "microvm"}}, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, + Allocated: &ateapi.WorkerResources{Actors: 1}, + SandboxClasses: []*ateapi.WorkerSandboxClass{{SandboxClass: "microvm"}}, }, }, { - Metadata: &ateapipb.ResourceMetadata{Name: "worker-2", CreateTime: timestamppb.New(now.Add(-3 * time.Hour))}, + Metadata: &ateapi.ResourceMetadata{Name: "worker-2", CreateTime: timestamppb.New(now.Add(-3 * time.Hour))}, WorkerNamespace: "ns-1", WorkerPool: "other", WorkerPod: "pod-2", Labels: map[string]string{"ate.dev/worker-pool": "other"}, - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - SandboxClasses: []*ateapipb.WorkerSandboxClass{{SandboxClass: "gvisor"}}, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + SandboxClasses: []*ateapi.WorkerSandboxClass{{SandboxClass: "gvisor"}}, }, }, { - Metadata: &ateapipb.ResourceMetadata{Name: "worker-3", CreateTime: timestamppb.New(now.Add(-72 * time.Hour))}, + Metadata: &ateapi.ResourceMetadata{Name: "worker-3", CreateTime: timestamppb.New(now.Add(-72 * time.Hour))}, WorkerNamespace: "ns-2", WorkerPool: "counter", WorkerPod: "pod-3", Labels: map[string]string{"ate.dev/worker-pool": "counter"}, - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 1}, - Allocated: &ateapipb.WorkerResources{Actors: 1}, - SandboxClasses: []*ateapipb.WorkerSandboxClass{{SandboxClass: "gvisor"}}, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 1}, + Allocated: &ateapi.WorkerResources{Actors: 1}, + SandboxClasses: []*ateapi.WorkerSandboxClass{{SandboxClass: "gvisor"}}, }, }, } - actors := &mockActorLister{byAtespace: map[string][]*ateapipb.Actor{ + actors := &mockActorLister{byAtespace: map[string][]*ateapi.Actor{ "space-a": {actorOn("space-a", "actor-a", "worker-1")}, "space-b": {actorOn("space-b", "actor-b", "worker-3")}, }} @@ -225,24 +225,24 @@ func TestGetWorkersRunner_GetByName(t *testing.T) { now := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC) pinTime(t, now) - getter := &mockWorkerGetter{workers: map[string]*ateapipb.Worker{ + getter := &mockWorkerGetter{workers: map[string]*ateapi.Worker{ "worker-1": { - Metadata: &ateapipb.ResourceMetadata{Name: "worker-1", CreateTime: timestamppb.New(now.Add(-5 * time.Minute))}, + Metadata: &ateapi.ResourceMetadata{Name: "worker-1", CreateTime: timestamppb.New(now.Add(-5 * time.Minute))}, WorkerNamespace: "ns-1", WorkerPool: "counter", WorkerPod: "pod-1", - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 4, CpuMillicores: 2000, MemoryBytes: 4 << 30}, - Allocated: &ateapipb.WorkerResources{Actors: 1, CpuMillicores: 500, MemoryBytes: 1 << 30}, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 4, CpuMillicores: 2000, MemoryBytes: 4 << 30}, + Allocated: &ateapi.WorkerResources{Actors: 1, CpuMillicores: 500, MemoryBytes: 1 << 30}, }, }, "worker-2": { - Metadata: &ateapipb.ResourceMetadata{Name: "worker-2", CreateTime: timestamppb.New(now.Add(-72 * time.Hour))}, + Metadata: &ateapi.ResourceMetadata{Name: "worker-2", CreateTime: timestamppb.New(now.Add(-72 * time.Hour))}, WorkerNamespace: "ns-1", WorkerPool: "counter", WorkerPod: "pod-2", - Status: &ateapipb.WorkerStatus{State: ateapipb.WorkerState_WORKER_STATE_DRAINING}, + Status: &ateapi.WorkerStatus{State: ateapi.WorkerState_WORKER_STATE_DRAINING}, }, }} @@ -266,8 +266,8 @@ func TestGetWorkersRunner_GetByName(t *testing.T) { } func TestGetWorkersRunner_GetByName_Single(t *testing.T) { - getter := &mockWorkerGetter{workers: map[string]*ateapipb.Worker{ - "worker-1": {Metadata: &ateapipb.ResourceMetadata{Name: "worker-1"}}, + getter := &mockWorkerGetter{workers: map[string]*ateapi.Worker{ + "worker-1": {Metadata: &ateapi.ResourceMetadata{Name: "worker-1"}}, }} var buf bytes.Buffer @@ -324,16 +324,16 @@ func TestGetWorkersRunner_GetByName_RejectsFilters(t *testing.T) { } func TestTopWorkersRunner_Success(t *testing.T) { - workers := []*ateapipb.Worker{ + workers := []*ateapi.Worker{ { WorkerNamespace: "ate-demo-counter", WorkerPool: "counter", WorkerPod: "counter-worker-pool-7b9f8-x123", Labels: map[string]string{"ate.dev/worker-pool": "counter"}, - Status: &ateapipb.WorkerStatus{ - Capacity: &ateapipb.WorkerResources{Actors: 1}, - Allocated: &ateapipb.WorkerResources{Actors: 1}, - SandboxClasses: []*ateapipb.WorkerSandboxClass{{SandboxClass: "gvisor"}}, + Status: &ateapi.WorkerStatus{ + Capacity: &ateapi.WorkerResources{Actors: 1}, + Allocated: &ateapi.WorkerResources{Actors: 1}, + SandboxClasses: []*ateapi.WorkerSandboxClass{{SandboxClass: "gvisor"}}, }, }, { @@ -341,8 +341,8 @@ func TestTopWorkersRunner_Success(t *testing.T) { WorkerPool: "counter", WorkerPod: "counter-worker-pool-7b9f8-y456", Labels: map[string]string{"ate.dev/worker-pool": "counter"}, - Status: &ateapipb.WorkerStatus{ - SandboxClasses: []*ateapipb.WorkerSandboxClass{{SandboxClass: "microvm"}}, + Status: &ateapi.WorkerStatus{ + SandboxClasses: []*ateapi.WorkerSandboxClass{{SandboxClass: "microvm"}}, }, }, } @@ -402,13 +402,13 @@ counter-worker-pool-7b9f8-y456 counter microvm FREE 2m } func TestTopWorkersRunner_FilterNamespace(t *testing.T) { - workers := []*ateapipb.Worker{ + workers := []*ateapi.Worker{ { WorkerNamespace: "ns-1", WorkerPool: "pool-1", WorkerPod: "pod-1", - Status: &ateapipb.WorkerStatus{ - SandboxClasses: []*ateapipb.WorkerSandboxClass{{SandboxClass: "gvisor"}}, + Status: &ateapi.WorkerStatus{ + SandboxClasses: []*ateapi.WorkerSandboxClass{{SandboxClass: "gvisor"}}, }, }, { @@ -440,31 +440,31 @@ pod-1 pool-1 gvisor FREE metrics unavailable metrics unavailable } func TestTopWorkersRunner_FilterAtespace(t *testing.T) { - workers := []*ateapipb.Worker{ + workers := []*ateapi.Worker{ { - Metadata: &ateapipb.ResourceMetadata{Name: "worker-1"}, + Metadata: &ateapi.ResourceMetadata{Name: "worker-1"}, WorkerNamespace: "ns-1", WorkerPool: "pool-1", WorkerPod: "pod-1", - Status: &ateapipb.WorkerStatus{ - Capacity: &ateapipb.WorkerResources{Actors: 1}, - Allocated: &ateapipb.WorkerResources{Actors: 1}, - SandboxClasses: []*ateapipb.WorkerSandboxClass{{SandboxClass: "microvm"}}, + Status: &ateapi.WorkerStatus{ + Capacity: &ateapi.WorkerResources{Actors: 1}, + Allocated: &ateapi.WorkerResources{Actors: 1}, + SandboxClasses: []*ateapi.WorkerSandboxClass{{SandboxClass: "microvm"}}, }, }, { - Metadata: &ateapipb.ResourceMetadata{Name: "worker-2"}, + Metadata: &ateapi.ResourceMetadata{Name: "worker-2"}, WorkerNamespace: "ns-1", WorkerPool: "pool-1", WorkerPod: "pod-2", - Status: &ateapipb.WorkerStatus{Capacity: &ateapipb.WorkerResources{Actors: 1}, Allocated: &ateapipb.WorkerResources{Actors: 1}}, + Status: &ateapi.WorkerStatus{Capacity: &ateapi.WorkerResources{Actors: 1}, Allocated: &ateapi.WorkerResources{Actors: 1}}, }, } var buf bytes.Buffer runner := &TopWorkersRunner{ workerLister: &mockWorkerLister{workers: workers}, - actorLister: &mockActorLister{byAtespace: map[string][]*ateapipb.Actor{ + actorLister: &mockActorLister{byAtespace: map[string][]*ateapi.Actor{ "space-a": {actorOn("space-a", "actor-a", "worker-1")}, "space-b": {actorOn("space-b", "actor-b", "worker-2")}, }}, @@ -487,14 +487,14 @@ pod-1 pool-1 microvm ASSIGNED(1/1) metrics unavailable metrics unavail } func TestTopWorkersRunner_FilterSelector(t *testing.T) { - workers := []*ateapipb.Worker{ + workers := []*ateapi.Worker{ { WorkerNamespace: "ns-1", WorkerPool: "counter", WorkerPod: "pod-1", Labels: map[string]string{"ate.dev/worker-pool": "counter"}, - Status: &ateapipb.WorkerStatus{ - SandboxClasses: []*ateapipb.WorkerSandboxClass{{SandboxClass: "gvisor"}}, + Status: &ateapi.WorkerStatus{ + SandboxClasses: []*ateapi.WorkerSandboxClass{{SandboxClass: "gvisor"}}, }, }, { @@ -527,7 +527,7 @@ pod-1 counter gvisor FREE metrics unavailable metrics unavailable } func TestTopWorkersRunner_MetricsUnavailable(t *testing.T) { - workers := []*ateapipb.Worker{ + workers := []*ateapi.Worker{ { WorkerNamespace: "ns-1", WorkerPool: "pool-1", diff --git a/cmd/kubectl-ate/internal/printer/access_policy.go b/cmd/kubectl-ate/internal/printer/access_policy.go index a260e02897..d4c1100ad7 100644 --- a/cmd/kubectl-ate/internal/printer/access_policy.go +++ b/cmd/kubectl-ate/internal/printer/access_policy.go @@ -20,13 +20,13 @@ import ( "strings" "text/tabwriter" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) // PrintAccessPolicyTo prints an access policy, one table row per binding. // json and yaml emit the bare AccessPolicy. The policy's metadata carries no // atespace, so the caller passes it; empty means the global policy. -func PrintAccessPolicyTo(out io.Writer, atespace string, policy *ateapipb.AccessPolicy, format string) error { +func PrintAccessPolicyTo(out io.Writer, atespace string, policy *ateapi.AccessPolicy, format string) error { switch format { case "json", "yaml": return printProto(out, policy, format) diff --git a/cmd/kubectl-ate/internal/printer/access_policy_test.go b/cmd/kubectl-ate/internal/printer/access_policy_test.go index e068c025ce..329739a81f 100644 --- a/cmd/kubectl-ate/internal/printer/access_policy_test.go +++ b/cmd/kubectl-ate/internal/printer/access_policy_test.go @@ -19,13 +19,13 @@ import ( "strings" "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) func TestPrintAccessPolicyTo(t *testing.T) { - policy := &ateapipb.AccessPolicy{ - Metadata: &ateapipb.ResourceMetadata{Name: "default", Uid: "u-1", Version: 2}, - Bindings: []*ateapipb.Binding{ + policy := &ateapi.AccessPolicy{ + Metadata: &ateapi.ResourceMetadata{Name: "default", Uid: "u-1", Version: 2}, + Bindings: []*ateapi.Binding{ {Role: "owner", Members: []string{"user:alice", "user:bob"}}, {Role: "viewer", Members: []string{"user:carol"}}, }, @@ -33,7 +33,7 @@ func TestPrintAccessPolicyTo(t *testing.T) { tests := []struct { name string atespace string - policy *ateapipb.AccessPolicy + policy *ateapi.AccessPolicy format string want []string wantErr bool @@ -47,7 +47,7 @@ func TestPrintAccessPolicyTo(t *testing.T) { want: []string{" owner"}, }, { - name: "no bindings", atespace: "team-a", policy: &ateapipb.AccessPolicy{}, format: "table", + name: "no bindings", atespace: "team-a", policy: &ateapi.AccessPolicy{}, format: "table", want: []string{"team-a "}, }, { diff --git a/cmd/kubectl-ate/internal/printer/egress_policy.go b/cmd/kubectl-ate/internal/printer/egress_policy.go index 7af33d316e..26b8c2d3b6 100644 --- a/cmd/kubectl-ate/internal/printer/egress_policy.go +++ b/cmd/kubectl-ate/internal/printer/egress_policy.go @@ -19,12 +19,12 @@ import ( "io" "text/tabwriter" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) // PrintEgressPolicyTo prints one actor's egress policy. json and yaml emit the // bare EgressPolicy. The policy carries no actor name, so the caller passes it. -func PrintEgressPolicyTo(out io.Writer, actor string, policy *ateapipb.EgressPolicy, format string) error { +func PrintEgressPolicyTo(out io.Writer, actor string, policy *ateapi.EgressPolicy, format string) error { switch format { case "json", "yaml": return printProto(out, policy, format) diff --git a/cmd/kubectl-ate/internal/printer/egress_policy_test.go b/cmd/kubectl-ate/internal/printer/egress_policy_test.go index e1ee36cd67..323706b151 100644 --- a/cmd/kubectl-ate/internal/printer/egress_policy_test.go +++ b/cmd/kubectl-ate/internal/printer/egress_policy_test.go @@ -20,7 +20,7 @@ import ( "time" "github.com/google/go-cmp/cmp" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -28,28 +28,28 @@ func TestPrintEgressPolicyTo(t *testing.T) { now := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC) pinNow(t, now) - policy := &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{ + policy := &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "team-a", Name: "default", Uid: "3f2b1c0e-8d5a-4b6e-9c1d-2a7e4f6b8c0d", Version: 2, CreateTime: timestamppb.New(now.Add(-5 * time.Minute)), }, - Rules: []*ateapipb.EgressRule{ - {Http: &ateapipb.HttpRule{Hostnames: []string{"api.example.com"}}}, - {Https: &ateapipb.HttpsRule{Hostnames: []string{"www.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{8443}}}}, + Rules: []*ateapi.EgressRule{ + {Http: &ateapi.HttpRule{Hostnames: []string{"api.example.com"}}}, + {Https: &ateapi.HttpsRule{Hostnames: []string{"www.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{8443}}}}, }, } - empty := &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "default", Version: 1, CreateTime: timestamppb.New(now.Add(-30 * time.Second))}, + empty := &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "default", Version: 1, CreateTime: timestamppb.New(now.Add(-30 * time.Second))}, } tests := []struct { name string format string actor string - policy *ateapipb.EgressPolicy + policy *ateapi.EgressPolicy want string wantErr bool }{ diff --git a/cmd/kubectl-ate/internal/printer/printer.go b/cmd/kubectl-ate/internal/printer/printer.go index c1fa8504c4..8d418c46c9 100644 --- a/cmd/kubectl-ate/internal/printer/printer.go +++ b/cmd/kubectl-ate/internal/printer/printer.go @@ -25,7 +25,7 @@ import ( "text/tabwriter" "time" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" @@ -45,8 +45,8 @@ func formatAge(ts *timestamppb.Timestamp) string { return duration.HumanDuration(TimeNow().Sub(ts.AsTime())) } -func sortActors(actors []*ateapipb.Actor) { - slices.SortFunc(actors, func(a, b *ateapipb.Actor) int { +func sortActors(actors []*ateapi.Actor) { + slices.SortFunc(actors, func(a, b *ateapi.Actor) int { if c := cmp.Compare(a.GetMetadata().GetAtespace(), b.GetMetadata().GetAtespace()); c != 0 { return c } @@ -59,17 +59,17 @@ func sortActors(actors []*ateapipb.Actor) { // actorTemplateDisplay renders the template an actor references, in // "/" form. -func actorTemplateDisplay(a *ateapipb.Actor) string { +func actorTemplateDisplay(a *ateapi.Actor) string { ref := a.GetActorTemplate() return ref.GetAtespace() + "/" + ref.GetName() } // PrintActorsTo prints a slice of actors to the provided writer. -func PrintActorsTo(out io.Writer, actors []*ateapipb.Actor, format string) error { +func PrintActorsTo(out io.Writer, actors []*ateapi.Actor, format string) error { sortActors(actors) switch format { case "json", "yaml": - return printProto(out, &ateapipb.ListActorsResponse{Actors: actors}, format) + return printProto(out, &ateapi.ListActorsResponse{Actors: actors}, format) case "table": w := tabwriter.NewWriter(out, 0, 0, 3, ' ', 0) fmt.Fprintln(w, "ATESPACE\tNAME\tTEMPLATE\tSTATE\tWORKER POD\tWORKER IPS\tVERSION\tAGE") @@ -98,7 +98,7 @@ func PrintActorsTo(out io.Writer, actors []*ateapipb.Actor, format string) error // WorkerOccupancy is how full a Worker is, as a count against its limit. A // count rather than the Actors themselves: a listing does not carry them, and // naming them all would be unreadable long before a Worker is full. -func WorkerOccupancy(worker *ateapipb.Worker) string { +func WorkerOccupancy(worker *ateapi.Worker) string { hosted := worker.GetStatus().GetAllocated().GetActors() if hosted == 0 { return "FREE" @@ -106,8 +106,8 @@ func WorkerOccupancy(worker *ateapipb.Worker) string { return fmt.Sprintf("ASSIGNED(%d/%d)", hosted, worker.GetStatus().GetCapacity().GetActors()) } -func sortWorkers(workers []*ateapipb.Worker) { - slices.SortFunc(workers, func(a, b *ateapipb.Worker) int { +func sortWorkers(workers []*ateapi.Worker) { + slices.SortFunc(workers, func(a, b *ateapi.Worker) int { if c := cmp.Compare(a.GetWorkerNamespace(), b.GetWorkerNamespace()); c != 0 { return c } @@ -120,7 +120,7 @@ func sortWorkers(workers []*ateapipb.Worker) { // workerActorsColumn renders a Worker's actor count as allocated/capacity // (e.g. "3/10"). -func workerActorsColumn(worker *ateapipb.Worker) string { +func workerActorsColumn(worker *ateapi.Worker) string { return fmt.Sprintf("%d/%d", worker.GetStatus().GetAllocated().GetActors(), worker.GetStatus().GetCapacity().GetActors()) } @@ -144,11 +144,11 @@ func formatInt(n int64) string { } // PrintWorkersTo prints a slice of workers to the provided writer. -func PrintWorkersTo(out io.Writer, workers []*ateapipb.Worker, format string) error { +func PrintWorkersTo(out io.Writer, workers []*ateapi.Worker, format string) error { sortWorkers(workers) switch format { case "json", "yaml": - return printProto(out, &ateapipb.ListWorkersResponse{Workers: workers}, format) + return printProto(out, &ateapi.ListWorkersResponse{Workers: workers}, format) case "table": w := tabwriter.NewWriter(out, 0, 0, 3, ' ', 0) fmt.Fprintln(w, "NAME\tPOOL\tSTATE\tACTORS\tCPU(MILLICORES)\tMEMORY\tPOD\tAGE") @@ -173,12 +173,12 @@ func PrintWorkersTo(out io.Writer, workers []*ateapipb.Worker, format string) er } // PrintWorkerTo prints a single worker to the provided writer. -func PrintWorkerTo(out io.Writer, worker *ateapipb.Worker, format string) error { +func PrintWorkerTo(out io.Writer, worker *ateapi.Worker, format string) error { if format == "json" || format == "yaml" { return printProto(out, worker, format) } // table has no singular/plural distinction, so reuse the list renderer. - return PrintWorkersTo(out, []*ateapipb.Worker{worker}, format) + return PrintWorkersTo(out, []*ateapi.Worker{worker}, format) } // WorkerTopItem represents real-time hardware resource utilization for a worker pod. @@ -265,16 +265,16 @@ func PrintWorkerTopYAML(out io.Writer, items []*WorkerTopItem) error { } // PrintActorTo prints a single actor to the provided writer. -func PrintActorTo(out io.Writer, actor *ateapipb.Actor, format string) error { +func PrintActorTo(out io.Writer, actor *ateapi.Actor, format string) error { if format == "json" || format == "yaml" { return printProto(out, actor, format) } // table has no singular/plural distinction, so reuse the list renderer. - return PrintActorsTo(out, []*ateapipb.Actor{actor}, format) + return PrintActorsTo(out, []*ateapi.Actor{actor}, format) } -func sortActorTemplates(templates []*ateapipb.ActorTemplate) { - slices.SortFunc(templates, func(a, b *ateapipb.ActorTemplate) int { +func sortActorTemplates(templates []*ateapi.ActorTemplate) { + slices.SortFunc(templates, func(a, b *ateapi.ActorTemplate) int { if c := cmp.Compare(a.GetMetadata().GetAtespace(), b.GetMetadata().GetAtespace()); c != 0 { return c } @@ -283,18 +283,18 @@ func sortActorTemplates(templates []*ateapipb.ActorTemplate) { } // PrintActorTemplatesTo prints a slice of actor templates to the provided writer. -func PrintActorTemplatesTo(out io.Writer, templates []*ateapipb.ActorTemplate, format string) error { +func PrintActorTemplatesTo(out io.Writer, templates []*ateapi.ActorTemplate, format string) error { sortActorTemplates(templates) switch format { case "json", "yaml": - return printProto(out, &ateapipb.ListActorTemplatesResponse{ActorTemplates: templates}, format) + return printProto(out, &ateapi.ListActorTemplatesResponse{ActorTemplates: templates}, format) case "table": w := tabwriter.NewWriter(out, 0, 0, 3, ' ', 0) fmt.Fprintln(w, "ATESPACE\tNAME\tGOLDEN TAG\tERROR\tAGE") for _, t := range templates { gss := t.GetStatus().GetGoldenSnapshotStatus() goldenTag := gss.GetGoldenTag().GetName() - if t.GetSnapshotConfig().GetGoldenSnapshotConfig().GetMode() == ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED { + if t.GetSnapshotConfig().GetGoldenSnapshotConfig().GetMode() == ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED { goldenTag = "DISABLED" } // Error messages are too long for a table cell. @@ -314,18 +314,18 @@ func PrintActorTemplatesTo(out io.Writer, templates []*ateapipb.ActorTemplate, f } // PrintActorTemplateTo prints a single actor template to the provided writer. -func PrintActorTemplateTo(out io.Writer, template *ateapipb.ActorTemplate, format string) error { +func PrintActorTemplateTo(out io.Writer, template *ateapi.ActorTemplate, format string) error { if format == "json" || format == "yaml" { return printProto(out, template, format) } // table has no singular/plural distinction, so reuse the list renderer. - return PrintActorTemplatesTo(out, []*ateapipb.ActorTemplate{template}, format) + return PrintActorTemplatesTo(out, []*ateapi.ActorTemplate{template}, format) } // PrintTagsTo prints a slice of tags to the // provided writer. -func PrintTagsTo(out io.Writer, tags []*ateapipb.Tag, format string) error { - slices.SortFunc(tags, func(a, b *ateapipb.Tag) int { +func PrintTagsTo(out io.Writer, tags []*ateapi.Tag, format string) error { + slices.SortFunc(tags, func(a, b *ateapi.Tag) int { if c := cmp.Compare(a.GetMetadata().GetAtespace(), b.GetMetadata().GetAtespace()); c != 0 { return c } @@ -333,7 +333,7 @@ func PrintTagsTo(out io.Writer, tags []*ateapipb.Tag, format string) error { }) switch format { case "json", "yaml": - return printProto(out, &ateapipb.ListTagsResponse{Tags: tags}, format) + return printProto(out, &ateapi.ListTagsResponse{Tags: tags}, format) case "table": w := tabwriter.NewWriter(out, 0, 0, 3, ' ', 0) fmt.Fprintln(w, "ATESPACE\tNAME\tSCOPE\tSTATE\tSNAPSHOT\tFIDELITY\tAGE") @@ -357,9 +357,9 @@ func PrintTagsTo(out io.Writer, tags []*ateapipb.Tag, format string) error { } } -func durableSnapshotStorage(snapshot *ateapipb.Snapshot) *ateapipb.SnapshotStorage { +func durableSnapshotStorage(snapshot *ateapi.Snapshot) *ateapi.SnapshotStorage { st := snapshot.GetDurableSnapshot() - if st.GetStatus() == ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED && + if st.GetStatus() == ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED && st.GetObject().GetSnapshotUri() != "" { return st } @@ -369,7 +369,7 @@ func durableSnapshotStorage(snapshot *ateapipb.Snapshot) *ateapipb.SnapshotStora // tagState reports whether a tag is usable. A tag is Pending until // the copy of its own snapshot lands; until then it names nothing an Actor can // be created from, and deleting it collects whatever the create stranded. -func tagState(tag *ateapipb.Tag) string { +func tagState(tag *ateapi.Tag) string { if durableSnapshotStorage(tag.GetStatus().GetSnapshot()) == nil { return "Pending" } @@ -377,26 +377,26 @@ func tagState(tag *ateapipb.Tag) string { } // PrintTagTo prints a single tag to the provided writer. -func PrintTagTo(out io.Writer, tag *ateapipb.Tag, format string) error { +func PrintTagTo(out io.Writer, tag *ateapi.Tag, format string) error { if format == "json" || format == "yaml" { return printProto(out, tag, format) } // table has no singular/plural distinction, so reuse the list renderer. - return PrintTagsTo(out, []*ateapipb.Tag{tag}, format) + return PrintTagsTo(out, []*ateapi.Tag{tag}, format) } -func sortAtespaces(atespaces []*ateapipb.Atespace) { - slices.SortFunc(atespaces, func(a, b *ateapipb.Atespace) int { +func sortAtespaces(atespaces []*ateapi.Atespace) { + slices.SortFunc(atespaces, func(a, b *ateapi.Atespace) int { return cmp.Compare(a.GetMetadata().GetName(), b.GetMetadata().GetName()) }) } // PrintAtespacesTo prints a slice of atespaces to the provided writer. -func PrintAtespacesTo(out io.Writer, atespaces []*ateapipb.Atespace, format string) error { +func PrintAtespacesTo(out io.Writer, atespaces []*ateapi.Atespace, format string) error { sortAtespaces(atespaces) switch format { case "json", "yaml": - return printProto(out, &ateapipb.ListAtespacesResponse{Atespaces: atespaces}, format) + return printProto(out, &ateapi.ListAtespacesResponse{Atespaces: atespaces}, format) case "table": w := tabwriter.NewWriter(out, 0, 0, 3, ' ', 0) fmt.Fprintln(w, "NAME\tAGE") @@ -410,12 +410,12 @@ func PrintAtespacesTo(out io.Writer, atespaces []*ateapipb.Atespace, format stri } // PrintAtespaceTo prints a single atespace to the provided writer. -func PrintAtespaceTo(out io.Writer, atespace *ateapipb.Atespace, format string) error { +func PrintAtespaceTo(out io.Writer, atespace *ateapi.Atespace, format string) error { if format == "json" || format == "yaml" { return printProto(out, atespace, format) } // table has no singular/plural distinction, so reuse the list renderer. - return PrintAtespacesTo(out, []*ateapipb.Atespace{atespace}, format) + return PrintAtespacesTo(out, []*ateapi.Atespace{atespace}, format) } func printProto(out io.Writer, msg proto.Message, format string) error { diff --git a/cmd/kubectl-ate/internal/printer/printer_test.go b/cmd/kubectl-ate/internal/printer/printer_test.go index 26494e717b..bcbf0a3bfd 100644 --- a/cmd/kubectl-ate/internal/printer/printer_test.go +++ b/cmd/kubectl-ate/internal/printer/printer_test.go @@ -20,7 +20,7 @@ import ( "time" "github.com/google/go-cmp/cmp" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -58,18 +58,18 @@ func TestPrintActorsTo_Table(t *testing.T) { pinNow(t, now) var buf bytes.Buffer - actors := []*ateapipb.Actor{ + actors := []*ateapi.Actor{ { - Metadata: &ateapipb.ResourceMetadata{ + Metadata: &ateapi.ResourceMetadata{ Name: "id-1", Atespace: "team-a", Version: 2, CreateTime: timestamppb.New(now.Add(-5 * time.Minute)), }, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "default", Name: "template-1"}, - Status: &ateapipb.ActorStatus{ - State: ateapipb.ActorState_ACTOR_STATE_RUNNING, - WorkerAssignment: &ateapipb.WorkerAssignment{ + ActorTemplate: &ateapi.ObjectRef{Atespace: "default", Name: "template-1"}, + Status: &ateapi.ActorStatus{ + State: ateapi.ActorState_ACTOR_STATE_RUNNING, + WorkerAssignment: &ateapi.WorkerAssignment{ WorkerNamespace: "worker-ns", WorkerPod: "pod-1", WorkerPodIps: []string{"1.2.3.4", "fd00::1"}, @@ -93,9 +93,9 @@ team-a id-1 default/template-1 ACTOR_STATE_RUNNING worker-ns/pod-1 1 func TestPrintActorsTo_JSON(t *testing.T) { var buf bytes.Buffer - actors := []*ateapipb.Actor{ + actors := []*ateapi.Actor{ { - Metadata: &ateapipb.ResourceMetadata{Name: "id-1", Version: 2}, + Metadata: &ateapi.ResourceMetadata{Name: "id-1", Version: 2}, }, } @@ -122,9 +122,9 @@ func TestPrintActorsTo_JSON(t *testing.T) { func TestPrintActorsTo_YAML(t *testing.T) { var buf bytes.Buffer - actors := []*ateapipb.Actor{ + actors := []*ateapi.Actor{ { - Metadata: &ateapipb.ResourceMetadata{Name: "id-1", Version: 2}, + Metadata: &ateapi.ResourceMetadata{Name: "id-1", Version: 2}, }, } @@ -148,33 +148,33 @@ func TestPrintActorsTo_Table_Sorted(t *testing.T) { pinNow(t, now) var buf bytes.Buffer - actors := []*ateapipb.Actor{ + actors := []*ateapi.Actor{ { - Metadata: &ateapipb.ResourceMetadata{ + Metadata: &ateapi.ResourceMetadata{ Name: "zebra", Atespace: "team-b", CreateTime: timestamppb.New(now.Add(-72 * time.Hour)), }, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "default", Name: "template-1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "default", Name: "template-1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }, { - Metadata: &ateapipb.ResourceMetadata{ + Metadata: &ateapi.ResourceMetadata{ Name: "alpha", Atespace: "team-a", CreateTime: timestamppb.New(now.Add(-5 * time.Minute)), }, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "default", Name: "template-1"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "default", Name: "template-1"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, }, { - Metadata: &ateapipb.ResourceMetadata{ + Metadata: &ateapi.ResourceMetadata{ Name: "beta", Atespace: "team-a", CreateTime: timestamppb.New(now.Add(-5 * time.Hour)), }, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "other", Name: "template-2"}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "other", Name: "template-2"}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }, } @@ -198,18 +198,18 @@ func TestPrintActorsTo_Table_TemplateRef(t *testing.T) { pinNow(t, now) var buf bytes.Buffer - actors := []*ateapipb.Actor{ + actors := []*ateapi.Actor{ { - Metadata: &ateapipb.ResourceMetadata{ + Metadata: &ateapi.ResourceMetadata{ Name: "id-1", Atespace: "team-a", CreateTime: timestamppb.New(now.Add(-5 * time.Minute)), }, - ActorTemplate: &ateapipb.ObjectRef{ + ActorTemplate: &ateapi.ObjectRef{ Atespace: "ate-demo-counter-substrate", Name: "counter", }, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }, } @@ -235,7 +235,7 @@ func TestPrintActorsTo_Invalid(t *testing.T) { func TestPrintActorTo_JSON(t *testing.T) { var buf bytes.Buffer - actor := &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Name: "id-1", Version: 2}} + actor := &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Name: "id-1", Version: 2}} if err := PrintActorTo(&buf, actor, "json"); err != nil { t.Fatalf("unexpected error: %v", err) @@ -255,7 +255,7 @@ func TestPrintActorTo_JSON(t *testing.T) { func TestPrintActorTo_YAML(t *testing.T) { var buf bytes.Buffer - actor := &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Name: "id-1", Version: 2}} + actor := &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Name: "id-1", Version: 2}} if err := PrintActorTo(&buf, actor, "yaml"); err != nil { t.Fatalf("unexpected error: %v", err) @@ -275,16 +275,16 @@ func TestPrintWorkersTo_Table(t *testing.T) { pinNow(t, now) var buf bytes.Buffer - workers := []*ateapipb.Worker{ + workers := []*ateapi.Worker{ { - Metadata: &ateapipb.ResourceMetadata{Name: "worker-1", CreateTime: timestamppb.New(now.Add(-72 * time.Hour))}, + Metadata: &ateapi.ResourceMetadata{Name: "worker-1", CreateTime: timestamppb.New(now.Add(-72 * time.Hour))}, WorkerNamespace: "default", WorkerPool: "pool-1", WorkerPod: "pod-1", - Status: &ateapipb.WorkerStatus{ - State: ateapipb.WorkerState_WORKER_STATE_ACTIVE, - Capacity: &ateapipb.WorkerResources{Actors: 4, CpuMillicores: 2000, MemoryBytes: 4 << 30}, - Allocated: &ateapipb.WorkerResources{Actors: 1, CpuMillicores: 500, MemoryBytes: 1 << 30}, + Status: &ateapi.WorkerStatus{ + State: ateapi.WorkerState_WORKER_STATE_ACTIVE, + Capacity: &ateapi.WorkerResources{Actors: 4, CpuMillicores: 2000, MemoryBytes: 4 << 30}, + Allocated: &ateapi.WorkerResources{Actors: 1, CpuMillicores: 500, MemoryBytes: 1 << 30}, }, }, } @@ -312,7 +312,7 @@ func TestPrintWorkersTo_Table_Free(t *testing.T) { pinNow(t, now) var buf bytes.Buffer - workers := []*ateapipb.Worker{ + workers := []*ateapi.Worker{ { WorkerNamespace: "default", WorkerPool: "pool-1", @@ -338,21 +338,21 @@ func TestPrintWorkersTo_Table_Sorted(t *testing.T) { pinNow(t, now) var buf bytes.Buffer - workers := []*ateapipb.Worker{ + workers := []*ateapi.Worker{ { - Metadata: &ateapipb.ResourceMetadata{Name: "worker-z", CreateTime: timestamppb.New(now.Add(-5 * time.Minute))}, + Metadata: &ateapi.ResourceMetadata{Name: "worker-z", CreateTime: timestamppb.New(now.Add(-5 * time.Minute))}, WorkerNamespace: "default", WorkerPool: "pool-1", WorkerPod: "pod-z", }, { - Metadata: &ateapipb.ResourceMetadata{Name: "worker-a", CreateTime: timestamppb.New(now.Add(-5 * time.Minute))}, + Metadata: &ateapi.ResourceMetadata{Name: "worker-a", CreateTime: timestamppb.New(now.Add(-5 * time.Minute))}, WorkerNamespace: "default", WorkerPool: "pool-1", WorkerPod: "pod-a", }, { - Metadata: &ateapipb.ResourceMetadata{Name: "worker-o", CreateTime: timestamppb.New(now.Add(-5 * time.Minute))}, + Metadata: &ateapi.ResourceMetadata{Name: "worker-o", CreateTime: timestamppb.New(now.Add(-5 * time.Minute))}, WorkerNamespace: "other", WorkerPool: "pool-2", WorkerPod: "pod-1", @@ -383,7 +383,7 @@ func TestPrintWorkersTo_Invalid(t *testing.T) { func TestPrintWorkerTo_JSON(t *testing.T) { var buf bytes.Buffer - worker := &ateapipb.Worker{Metadata: &ateapipb.ResourceMetadata{Name: "worker-1"}} + worker := &ateapi.Worker{Metadata: &ateapi.ResourceMetadata{Name: "worker-1"}} if err := PrintWorkerTo(&buf, worker, "json"); err != nil { t.Fatalf("unexpected error: %v", err) @@ -402,7 +402,7 @@ func TestPrintWorkerTo_JSON(t *testing.T) { func TestPrintWorkerTo_YAML(t *testing.T) { var buf bytes.Buffer - worker := &ateapipb.Worker{Metadata: &ateapipb.ResourceMetadata{Name: "worker-1"}} + worker := &ateapi.Worker{Metadata: &ateapi.ResourceMetadata{Name: "worker-1"}} if err := PrintWorkerTo(&buf, worker, "yaml"); err != nil { t.Fatalf("unexpected error: %v", err) @@ -421,35 +421,35 @@ func TestPrintActorTemplatesTo_Table(t *testing.T) { pinNow(t, now) var buf bytes.Buffer - templates := []*ateapipb.ActorTemplate{ + templates := []*ateapi.ActorTemplate{ { - Metadata: &ateapipb.ResourceMetadata{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "ate-demo-counter-substrate", Name: "counter", Version: 1, CreateTime: timestamppb.New(now.Add(-5 * time.Minute)), }, - Status: &ateapipb.ActorTemplateStatus{ - GoldenSnapshotStatus: &ateapipb.GoldenSnapshotStatus{ - GoldenTag: &ateapipb.ObjectRef{Atespace: "ate-demo-counter-substrate", Name: "golden-tag"}, + Status: &ateapi.ActorTemplateStatus{ + GoldenSnapshotStatus: &ateapi.GoldenSnapshotStatus{ + GoldenTag: &ateapi.ObjectRef{Atespace: "ate-demo-counter-substrate", Name: "golden-tag"}, }, }, }, { - Metadata: &ateapipb.ResourceMetadata{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "ate-demo-counter-substrate-microvm", Name: "counter-microvm", Version: 1, CreateTime: timestamppb.New(now.Add(-5 * time.Hour)), }, - Status: &ateapipb.ActorTemplateStatus{ - GoldenSnapshotStatus: &ateapipb.GoldenSnapshotStatus{ + Status: &ateapi.ActorTemplateStatus{ + GoldenSnapshotStatus: &ateapi.GoldenSnapshotStatus{ ErrorMessage: "golden actor failed to start", }, }, }, { - Metadata: &ateapipb.ResourceMetadata{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "ate-demo-counter-substrate", Name: "counter-2", Version: 1, @@ -457,13 +457,13 @@ func TestPrintActorTemplatesTo_Table(t *testing.T) { }, }, { - Metadata: &ateapipb.ResourceMetadata{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "ate-demo-counter-substrate", Name: "counter-3", CreateTime: timestamppb.New(now.Add(-15 * time.Minute)), }, - SnapshotConfig: &ateapipb.SnapshotConfig{ - GoldenSnapshotConfig: &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED}, + SnapshotConfig: &ateapi.SnapshotConfig{ + GoldenSnapshotConfig: &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED}, }, }, } @@ -487,8 +487,8 @@ ate-demo-counter-substrate-microvm counter-microvm ERROR 5h func TestPrintActorTemplatesTo_JSON(t *testing.T) { var buf bytes.Buffer - templates := []*ateapipb.ActorTemplate{ - {Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "counter", Version: 1}}, + templates := []*ateapi.ActorTemplate{ + {Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "counter", Version: 1}}, } if err := PrintActorTemplatesTo(&buf, templates, "json"); err != nil { @@ -514,8 +514,8 @@ func TestPrintActorTemplatesTo_JSON(t *testing.T) { func TestPrintActorTemplatesTo_YAML(t *testing.T) { var buf bytes.Buffer - templates := []*ateapipb.ActorTemplate{ - {Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "counter", Version: 1}}, + templates := []*ateapi.ActorTemplate{ + {Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "counter", Version: 1}}, } if err := PrintActorTemplatesTo(&buf, templates, "yaml"); err != nil { @@ -542,7 +542,7 @@ func TestPrintActorTemplatesTo_Invalid(t *testing.T) { func TestPrintActorTemplateTo_JSON(t *testing.T) { var buf bytes.Buffer - template := &ateapipb.ActorTemplate{Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "counter", Version: 1}} + template := &ateapi.ActorTemplate{Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "counter", Version: 1}} if err := PrintActorTemplateTo(&buf, template, "json"); err != nil { t.Fatalf("unexpected error: %v", err) @@ -563,7 +563,7 @@ func TestPrintActorTemplateTo_JSON(t *testing.T) { func TestPrintActorTemplateTo_YAML(t *testing.T) { var buf bytes.Buffer - template := &ateapipb.ActorTemplate{Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "counter", Version: 1}} + template := &ateapi.ActorTemplate{Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "counter", Version: 1}} if err := PrintActorTemplateTo(&buf, template, "yaml"); err != nil { t.Fatalf("unexpected error: %v", err) @@ -584,37 +584,37 @@ func TestPrintTagsTo_Table(t *testing.T) { pinNow(t, now) var buf bytes.Buffer - tags := []*ateapipb.Tag{ + tags := []*ateapi.Tag{ { - Metadata: &ateapipb.ResourceMetadata{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "team-a", Name: "v2", CreateTime: timestamppb.New(now.Add(-5 * time.Minute)), }, - Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED, - Status: &ateapipb.TagStatus{ - Snapshot: &ateapipb.Snapshot{ - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - DurableSnapshot: &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: "gs://private/atespaces/team-a/tags/v2"}, + Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED, + Status: &ateapi.TagStatus{ + Snapshot: &ateapi.Snapshot{ + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + DurableSnapshot: &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, + Object: &ateapi.ObjectSnapshot{SnapshotUri: "gs://private/atespaces/team-a/tags/v2"}, }, }, }, }, { - Metadata: &ateapipb.ResourceMetadata{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "team-a", Name: "v1", CreateTime: timestamppb.New(now.Add(-5 * time.Hour)), }, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - Status: &ateapipb.TagStatus{ - Snapshot: &ateapipb.Snapshot{ - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - DurableSnapshot: &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: "gs://private/atespaces/team-a/tags/v1"}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + Status: &ateapi.TagStatus{ + Snapshot: &ateapi.Snapshot{ + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + DurableSnapshot: &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, + Object: &ateapi.ObjectSnapshot{SnapshotUri: "gs://private/atespaces/team-a/tags/v1"}, }, }, }, @@ -622,18 +622,18 @@ func TestPrintTagsTo_Table(t *testing.T) { { // A tag whose create never finished: it names nothing an Actor can // be created from yet, which the STATE column is there to say. - Metadata: &ateapipb.ResourceMetadata{ + Metadata: &ateapi.ResourceMetadata{ Atespace: "team-a", Name: "v3", CreateTime: timestamppb.New(now.Add(-30 * time.Second)), }, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - Status: &ateapipb.TagStatus{ - Snapshot: &ateapipb.Snapshot{ - Fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - DurableSnapshot: &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: "gs://private/atespaces/team-a/tags/v3"}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + Status: &ateapi.TagStatus{ + Snapshot: &ateapi.Snapshot{ + Fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + DurableSnapshot: &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING, + Object: &ateapi.ObjectSnapshot{SnapshotUri: "gs://private/atespaces/team-a/tags/v3"}, }, }, }, @@ -664,7 +664,7 @@ func TestPrintTagsTo_Invalid(t *testing.T) { func TestPrintTagTo_JSON(t *testing.T) { var buf bytes.Buffer - tag := &ateapipb.Tag{Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "v1"}} + tag := &ateapi.Tag{Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "v1"}} if err := PrintTagTo(&buf, tag, "json"); err != nil { t.Fatalf("unexpected error: %v", err) @@ -684,7 +684,7 @@ func TestPrintTagTo_JSON(t *testing.T) { func TestPrintTagTo_YAML(t *testing.T) { var buf bytes.Buffer - tag := &ateapipb.Tag{Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "v1"}} + tag := &ateapi.Tag{Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "v1"}} if err := PrintTagTo(&buf, tag, "yaml"); err != nil { t.Fatalf("unexpected error: %v", err) @@ -704,8 +704,8 @@ func TestPrintAtespacesTo_Table(t *testing.T) { pinNow(t, now) var buf bytes.Buffer - atespaces := []*ateapipb.Atespace{ - {Metadata: &ateapipb.ResourceMetadata{ + atespaces := []*ateapi.Atespace{ + {Metadata: &ateapi.ResourceMetadata{ Name: "team-a", CreateTime: timestamppb.New(now.Add(-5 * time.Minute)), }}, @@ -725,8 +725,8 @@ team-a 5m func TestPrintAtespacesTo_JSON(t *testing.T) { var buf bytes.Buffer - atespaces := []*ateapipb.Atespace{ - {Metadata: &ateapipb.ResourceMetadata{Name: "team-a"}}, + atespaces := []*ateapi.Atespace{ + {Metadata: &ateapi.ResourceMetadata{Name: "team-a"}}, } if err := PrintAtespacesTo(&buf, atespaces, "json"); err != nil { @@ -750,8 +750,8 @@ func TestPrintAtespacesTo_JSON(t *testing.T) { func TestPrintAtespacesTo_YAML(t *testing.T) { var buf bytes.Buffer - atespaces := []*ateapipb.Atespace{ - {Metadata: &ateapipb.ResourceMetadata{Name: "team-a"}}, + atespaces := []*ateapi.Atespace{ + {Metadata: &ateapi.ResourceMetadata{Name: "team-a"}}, } if err := PrintAtespacesTo(&buf, atespaces, "yaml"); err != nil { @@ -772,10 +772,10 @@ func TestPrintAtespacesTo_Table_Sorted(t *testing.T) { pinNow(t, now) var buf bytes.Buffer - atespaces := []*ateapipb.Atespace{ - {Metadata: &ateapipb.ResourceMetadata{Name: "team-c", CreateTime: timestamppb.New(now.Add(-72 * time.Hour))}}, - {Metadata: &ateapipb.ResourceMetadata{Name: "team-a", CreateTime: timestamppb.New(now.Add(-5 * time.Minute))}}, - {Metadata: &ateapipb.ResourceMetadata{Name: "team-b", CreateTime: timestamppb.New(now.Add(-5 * time.Hour))}}, + atespaces := []*ateapi.Atespace{ + {Metadata: &ateapi.ResourceMetadata{Name: "team-c", CreateTime: timestamppb.New(now.Add(-72 * time.Hour))}}, + {Metadata: &ateapi.ResourceMetadata{Name: "team-a", CreateTime: timestamppb.New(now.Add(-5 * time.Minute))}}, + {Metadata: &ateapi.ResourceMetadata{Name: "team-b", CreateTime: timestamppb.New(now.Add(-5 * time.Hour))}}, } if err := PrintAtespacesTo(&buf, atespaces, "table"); err != nil { @@ -802,7 +802,7 @@ func TestPrintAtespacesTo_Invalid(t *testing.T) { func TestPrintAtespaceTo_JSON(t *testing.T) { var buf bytes.Buffer - atespace := &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "team-a"}} + atespace := &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "team-a"}} if err := PrintAtespaceTo(&buf, atespace, "json"); err != nil { t.Fatalf("unexpected error: %v", err) @@ -821,7 +821,7 @@ func TestPrintAtespaceTo_JSON(t *testing.T) { func TestPrintAtespaceTo_YAML(t *testing.T) { var buf bytes.Buffer - atespace := &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: "team-a"}} + atespace := &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: "team-a"}} if err := PrintAtespaceTo(&buf, atespace, "yaml"); err != nil { t.Fatalf("unexpected error: %v", err) diff --git a/cmd/objectstore-plugin/main.go b/cmd/objectstore-plugin/main.go index 87585bf334..cce96b46ff 100644 --- a/cmd/objectstore-plugin/main.go +++ b/cmd/objectstore-plugin/main.go @@ -34,6 +34,7 @@ import ( "cloud.google.com/go/storage" "github.com/spf13/pflag" + objectstorev1 "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/internal/installdefaults" "go.ate.dev/substrate/internal/nodepath" "go.ate.dev/substrate/internal/objectstore" @@ -44,7 +45,6 @@ import ( "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/serverboot" "go.ate.dev/substrate/pkg/objectstorage" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "google.golang.org/grpc" "google.golang.org/grpc/health" diff --git a/demos/claude-code-multiplex/agent-luna-template.yaml.tmpl b/demos/claude-code-multiplex/agent-luna-template.yaml.tmpl index 0507117c0d..72bde3b0dc 100644 --- a/demos/claude-code-multiplex/agent-luna-template.yaml.tmpl +++ b/demos/claude-code-multiplex/agent-luna-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the luna agent +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the luna agent # of the claude-code-multiplex demo; one of three agents sharing the 2-pod # pool in claude-code-multiplex.yaml.tmpl. Applied with # `kubectl ate create actor-template -f -`; the claude-multiplex-demo diff --git a/demos/claude-code-multiplex/agent-mars-template.yaml.tmpl b/demos/claude-code-multiplex/agent-mars-template.yaml.tmpl index 7afab88f99..96b0ec95de 100644 --- a/demos/claude-code-multiplex/agent-mars-template.yaml.tmpl +++ b/demos/claude-code-multiplex/agent-mars-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the mars agent +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the mars agent # of the claude-code-multiplex demo; see agent-luna-template.yaml.tmpl for # the placeholder and apply conventions. metadata: diff --git a/demos/claude-code-multiplex/agent-orion-template.yaml.tmpl b/demos/claude-code-multiplex/agent-orion-template.yaml.tmpl index 5b1c886885..ce3240cda2 100644 --- a/demos/claude-code-multiplex/agent-orion-template.yaml.tmpl +++ b/demos/claude-code-multiplex/agent-orion-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the orion +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the orion # agent of the claude-code-multiplex demo; see agent-luna-template.yaml.tmpl # for the placeholder and apply conventions. metadata: diff --git a/demos/claude-code-multiplex/claude-code-multiplex.yaml.tmpl b/demos/claude-code-multiplex/claude-code-multiplex.yaml.tmpl index 005a859c88..c45357e164 100644 --- a/demos/claude-code-multiplex/claude-code-multiplex.yaml.tmpl +++ b/demos/claude-code-multiplex/claude-code-multiplex.yaml.tmpl @@ -25,7 +25,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: claude-workerpool diff --git a/demos/claude-code-multiplex/ui/server.go b/demos/claude-code-multiplex/ui/server.go index 734f0d9e10..5c5d908d61 100644 --- a/demos/claude-code-multiplex/ui/server.go +++ b/demos/claude-code-multiplex/ui/server.go @@ -58,8 +58,8 @@ import ( "sync" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateclient" - "go.ate.dev/substrate/pkg/proto/ateapipb" corev1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -137,7 +137,7 @@ var ( mu sync.Mutex assignments = make([]*assignment, 0, maxAssignments) // newest first - ateClient ateapipb.ControlClient + ateClient ateapi.ControlClient ateAPI *ateclient.Client kubeClient *kubernetes.Clientset ) @@ -198,17 +198,17 @@ func newKubeClient() (*kubernetes.Clientset, error) { // actorStateString maps the proto State enum to the human-readable // phase string the UI's badge logic understands (running / suspended // / etc). -func actorStateString(s ateapipb.ActorState) string { +func actorStateString(s ateapi.ActorState) string { switch s { - case ateapipb.ActorState_ACTOR_STATE_RESUMING: + case ateapi.ActorState_ACTOR_STATE_RESUMING: return "Resuming" - case ateapipb.ActorState_ACTOR_STATE_RUNNING: + case ateapi.ActorState_ACTOR_STATE_RUNNING: return "Running" - case ateapipb.ActorState_ACTOR_STATE_SUSPENDING: + case ateapi.ActorState_ACTOR_STATE_SUSPENDING: return "Suspending" - case ateapipb.ActorState_ACTOR_STATE_SUSPENDED: + case ateapi.ActorState_ACTOR_STATE_SUSPENDED: return "Suspended" - case ateapipb.ActorState_ACTOR_STATE_DELETING: + case ateapi.ActorState_ACTOR_STATE_DELETING: return "Deleting" default: return "?" @@ -219,7 +219,7 @@ func actorStateString(s ateapipb.ActorState) string { // A worker hosting an actor is "Running"; an idle worker is "Idle". // The UI's badgeFor() treats "running" as green; "idle" falls through // to the neutral badge, which is the right visual treatment. -func workerPhase(w *ateapipb.Worker) string { +func workerPhase(w *ateapi.Worker) string { if w.GetStatus().GetAllocated().GetActors() > 0 { return "Running" } @@ -234,7 +234,7 @@ func listActorNames(ctx context.Context) []string { } rctx, cancel := context.WithTimeout(ctx, rpcTimeout) defer cancel() - resp, err := ateClient.ListActors(rctx, &ateapipb.ListActorsRequest{}) + resp, err := ateClient.ListActors(rctx, &ateapi.ListActorsRequest{}) if err != nil { log.Printf("[ui] ListActors error: %v", err) return nil @@ -365,7 +365,7 @@ func handlePods(w http.ResponseWriter, r *http.Request) { } ctx, cancel := context.WithTimeout(r.Context(), rpcTimeout) defer cancel() - resp, err := ateClient.ListWorkers(ctx, &ateapipb.ListWorkersRequest{}) + resp, err := ateClient.ListWorkers(ctx, &ateapi.ListWorkersRequest{}) if err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": "ListWorkers: " + err.Error()}) return @@ -397,7 +397,7 @@ func handleActors(w http.ResponseWriter, r *http.Request) { } ctx, cancel := context.WithTimeout(r.Context(), rpcTimeout) defer cancel() - resp, err := ateClient.ListActors(ctx, &ateapipb.ListActorsRequest{}) + resp, err := ateClient.ListActors(ctx, &ateapi.ListActorsRequest{}) if err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": "ListActors: " + err.Error()}) return diff --git a/demos/counter/README.md b/demos/counter/README.md index 4098d6aa71..161997d7df 100644 --- a/demos/counter/README.md +++ b/demos/counter/README.md @@ -4,7 +4,7 @@ This directory contains a demo of a stateful counter application running on Agen It deploys a simple Go HTTP server (`counter.go`) that increments two counters on every request — one in process memory, one in a file on a durable volume — and preserves both across suspends and resumes: the template's `MEMORY` `preferredFidelity` snapshot captures process memory alongside the durable volumes, so the in-memory count continues from where it left off. (With a `VOLUMES` fidelity, only the durable-volume counter would survive and the in-memory counter would restart from a cold boot. `ROOTFS` also keeps each container's rootfs writes, but not process memory, so the in-memory counter would restart under it too.) -The demo uses two kinds of resources: the `WorkerPool` is a Kubernetes CRD, while the actor template is a Substrate `ActorTemplate` resource — an `ateapipb.ActorTemplate` living in an **atespace** rather than a Kubernetes namespace, managed through the ate API with `kubectl ate`. +The demo uses two kinds of resources: the `WorkerPool` is a Kubernetes CRD, while the actor template is a Substrate `ActorTemplate` resource — an `ateapi.ActorTemplate` living in an **atespace** rather than a Kubernetes namespace, managed through the ate API with `kubectl ate`. ## Prerequisites diff --git a/demos/counter/counter-microvm-csi-test-template.yaml b/demos/counter/counter-microvm-csi-test-template.yaml index 1dfc37bc54..4b74997769 100644 --- a/demos/counter/counter-microvm-csi-test-template.yaml +++ b/demos/counter/counter-microvm-csi-test-template.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the manual +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the manual # micro-VM CSI test. Applied with `kubectl ate create actor-template -f -` # after `ko resolve` replaces the ko:// image reference; the # ate-demo-counter-microvm-csi atespace must exist. diff --git a/demos/counter/counter-microvm-csi-test.yaml b/demos/counter/counter-microvm-csi-test.yaml index 06916b100c..1f4d13457b 100644 --- a/demos/counter/counter-microvm-csi-test.yaml +++ b/demos/counter/counter-microvm-csi-test.yaml @@ -23,7 +23,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: counter-microvm-csi diff --git a/demos/counter/counter-microvm-template.yaml.tmpl b/demos/counter/counter-microvm-template.yaml.tmpl index 1a1dd448f2..052bc209b6 100644 --- a/demos/counter/counter-microvm-template.yaml.tmpl +++ b/demos/counter/counter-microvm-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the micro-VM +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the micro-VM # counter demo. Applied with `kubectl ate create actor-template -f -` after # `ko resolve` replaces the ko:// image reference; the # ate-demo-counter-microvm atespace must exist. diff --git a/demos/counter/counter-microvm.yaml.tmpl b/demos/counter/counter-microvm.yaml.tmpl index a3b33e23c5..56381dd579 100644 --- a/demos/counter/counter-microvm.yaml.tmpl +++ b/demos/counter/counter-microvm.yaml.tmpl @@ -28,7 +28,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: counter-microvm diff --git a/demos/counter/counter-template.yaml.tmpl b/demos/counter/counter-template.yaml.tmpl index 43c6b33640..9f53b504c5 100644 --- a/demos/counter/counter-template.yaml.tmpl +++ b/demos/counter/counter-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the counter +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the counter # demo. Applied with `kubectl ate create actor-template -f -` after # `ko resolve` replaces the ko:// image reference; the ate-demo-counter # atespace must exist. diff --git a/demos/counter/counter.yaml.tmpl b/demos/counter/counter.yaml.tmpl index 007016795e..190ec65e19 100644 --- a/demos/counter/counter.yaml.tmpl +++ b/demos/counter/counter.yaml.tmpl @@ -23,7 +23,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: counter diff --git a/demos/egress/egress-microvm-template.yaml.tmpl b/demos/egress/egress-microvm-template.yaml.tmpl index 767b4d8450..6c21947f10 100644 --- a/demos/egress/egress-microvm-template.yaml.tmpl +++ b/demos/egress/egress-microvm-template.yaml.tmpl @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Substrate ActorTemplate resource (protojson-shaped ateapipb.ActorTemplate, -# NOT the ate.dev/v1alpha1 CRD) for the micro-VM egress demo. The actor's +# Substrate ActorTemplate resource (protojson-shaped ateapi.ActorTemplate, +# NOT the ate.dev/v1 CRD) for the micro-VM egress demo. The actor's # outbound TCP is redirected into atunnel by nftables in the ateworker # (prepareActorEgress), which the micro-VM ateworker implements the same way the # gVisor one does — this fixture is what proves it end to end. Delivery of the diff --git a/demos/egress/egress-microvm.yaml.tmpl b/demos/egress/egress-microvm.yaml.tmpl index e45313d9b9..d4f589b596 100644 --- a/demos/egress/egress-microvm.yaml.tmpl +++ b/demos/egress/egress-microvm.yaml.tmpl @@ -27,7 +27,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: egress-microvm diff --git a/demos/egress/egress-template.yaml.tmpl b/demos/egress/egress-template.yaml.tmpl index 4d544c1443..0815d4aeb4 100644 --- a/demos/egress/egress-template.yaml.tmpl +++ b/demos/egress/egress-template.yaml.tmpl @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Substrate ActorTemplate resource (protojson-shaped ateapipb.ActorTemplate, -# NOT the ate.dev/v1alpha1 CRD) for the egress demo. Applied with +# Substrate ActorTemplate resource (protojson-shaped ateapi.ActorTemplate, +# NOT the ate.dev/v1 CRD) for the egress demo. Applied with # `kubectl ate create actor-template -f -` after `ko resolve` replaces the # ko:// image reference; the ate-demo-egress atespace must exist. # diff --git a/demos/egress/egress.yaml.tmpl b/demos/egress/egress.yaml.tmpl index 234ad18330..0f1ecf0987 100644 --- a/demos/egress/egress.yaml.tmpl +++ b/demos/egress/egress.yaml.tmpl @@ -24,7 +24,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: egress diff --git a/demos/jupyter/jupyter-template.yaml.tmpl b/demos/jupyter/jupyter-template.yaml.tmpl index 66c345f8ed..239fa4b022 100644 --- a/demos/jupyter/jupyter-template.yaml.tmpl +++ b/demos/jupyter/jupyter-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the jupyter +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the jupyter # demo. Applied with `kubectl ate create actor-template -f -`; the # ate-demo-jupyter atespace must exist. The image is already pinned by # digest, so ko resolve passes it through unchanged. diff --git a/demos/jupyter/jupyter.yaml.tmpl b/demos/jupyter/jupyter.yaml.tmpl index e8382d39e8..e68cdd9817 100644 --- a/demos/jupyter/jupyter.yaml.tmpl +++ b/demos/jupyter/jupyter.yaml.tmpl @@ -23,7 +23,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: jupyter diff --git a/demos/multi-template/counter-template.yaml.tmpl b/demos/multi-template/counter-template.yaml.tmpl index 4cc31c5488..e689b1f599 100644 --- a/demos/multi-template/counter-template.yaml.tmpl +++ b/demos/multi-template/counter-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the counter +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the counter # half of the multi-template demo. It lives in its own atespace but selects # the same shared-pool as fspersist-template.yaml.tmpl. Applied with # `kubectl ate create actor-template -f -` after `ko resolve` replaces the diff --git a/demos/multi-template/fspersist-template.yaml.tmpl b/demos/multi-template/fspersist-template.yaml.tmpl index 411a091e77..1b573243f2 100644 --- a/demos/multi-template/fspersist-template.yaml.tmpl +++ b/demos/multi-template/fspersist-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the fspersist +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the fspersist # half of the multi-template demo. It lives in its own atespace but selects # the same shared-pool as counter-template.yaml.tmpl. Applied with # `kubectl ate create actor-template -f -` after `ko resolve` replaces the diff --git a/demos/multi-template/multi-template.yaml.tmpl b/demos/multi-template/multi-template.yaml.tmpl index b4465c20f5..d7bb1fb61b 100644 --- a/demos/multi-template/multi-template.yaml.tmpl +++ b/demos/multi-template/multi-template.yaml.tmpl @@ -27,7 +27,7 @@ kind: Namespace metadata: name: ate-demo-multi-template-pool --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: shared-pool diff --git a/demos/parking/parking-template.yaml.tmpl b/demos/parking/parking-template.yaml.tmpl index 9d808864d2..4753f7a02a 100644 --- a/demos/parking/parking-template.yaml.tmpl +++ b/demos/parking/parking-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the parking +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the parking # demo. Applied with `kubectl ate create actor-template -f -` after # `ko resolve` replaces the ko:// image reference; the ate-demo-parking # atespace must exist. diff --git a/demos/parking/parking.yaml.tmpl b/demos/parking/parking.yaml.tmpl index 16a01db8ca..b8a5cb3f58 100644 --- a/demos/parking/parking.yaml.tmpl +++ b/demos/parking/parking.yaml.tmpl @@ -32,7 +32,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: parking diff --git a/demos/sandbox/client/main.go b/demos/sandbox/client/main.go index 05dfdf3ed5..186b35ff90 100644 --- a/demos/sandbox/client/main.go +++ b/demos/sandbox/client/main.go @@ -29,9 +29,9 @@ import ( "syscall" "github.com/spf13/pflag" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/atenet" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) @@ -49,7 +49,7 @@ type ProcessResponse struct { Error string `json:"error,omitempty"` } -func dialAteAPI(endpoint string) (ateapipb.ControlClient, *grpc.ClientConn, error) { +func dialAteAPI(endpoint string) (ateapi.ControlClient, *grpc.ClientConn, error) { creds := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true}) conn, err := grpc.NewClient(endpoint, grpc.WithTransportCredentials(creds)) @@ -57,7 +57,7 @@ func dialAteAPI(endpoint string) (ateapipb.ControlClient, *grpc.ClientConn, erro return nil, nil, err } - return ateapipb.NewControlClient(conn), conn, nil + return ateapi.NewControlClient(conn), conn, nil } func main() { @@ -96,7 +96,7 @@ func main() { defer conn.Close() log.Printf("Resuming actor %s...", actorRef.Name) - _, err = cli.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actorRef.ToObjectRef()}) + _, err = cli.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef.ToObjectRef()}) if err != nil { log.Fatalf("Failed to resume actor: %v", err) } @@ -106,7 +106,7 @@ func main() { defer func() { log.Printf("Suspending actor %s...", actorRef.Name) suspendCtx := context.Background() - _, err := cli.SuspendActor(suspendCtx, &ateapipb.SuspendActorRequest{Actor: actorRef.ToObjectRef()}) + _, err := cli.SuspendActor(suspendCtx, &ateapi.SuspendActorRequest{Actor: actorRef.ToObjectRef()}) if err != nil { log.Printf("Failed to suspend actor: %v", err) } else { diff --git a/demos/sandbox/manual-test-multi-template.yaml b/demos/sandbox/manual-test-multi-template.yaml index d64dd70601..5399ed7ead 100644 --- a/demos/sandbox/manual-test-multi-template.yaml +++ b/demos/sandbox/manual-test-multi-template.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the manual +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the manual # multi-volume test. Applied with `kubectl ate create actor-template -f -` # after `ko resolve` replaces the ko:// image reference; the # ate-manual-test-multi atespace must exist. diff --git a/demos/sandbox/manual-test-multi.yaml b/demos/sandbox/manual-test-multi.yaml index 5dbb69627b..2f78b2cf52 100644 --- a/demos/sandbox/manual-test-multi.yaml +++ b/demos/sandbox/manual-test-multi.yaml @@ -21,7 +21,7 @@ kind: Namespace metadata: name: ate-manual-test-multi --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: sandbox-pool diff --git a/demos/sandbox/sandbox-template.yaml.tmpl b/demos/sandbox/sandbox-template.yaml.tmpl index b63a1c9f36..358d32b294 100644 --- a/demos/sandbox/sandbox-template.yaml.tmpl +++ b/demos/sandbox/sandbox-template.yaml.tmpl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the sandbox +# ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the sandbox # demo. Applied with `kubectl ate create actor-template -f -` after # `ko resolve` replaces the ko:// image reference; the ate-demo-sandbox # atespace must exist. diff --git a/demos/sandbox/sandbox.yaml.tmpl b/demos/sandbox/sandbox.yaml.tmpl index d51fe8ff9b..735d7e9522 100644 --- a/demos/sandbox/sandbox.yaml.tmpl +++ b/demos/sandbox/sandbox.yaml.tmpl @@ -21,7 +21,7 @@ kind: Namespace metadata: name: ate-demo-sandbox --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: sandbox-workerpool diff --git a/docs/api-guide.md b/docs/api-guide.md index 563a6a519f..ef7a3db7af 100644 --- a/docs/api-guide.md +++ b/docs/api-guide.md @@ -48,7 +48,7 @@ Setting `resources.limits` (CPU and Memory) on a `WorkerPool` establishes each w ### Example ```yaml -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: agent-pool @@ -343,6 +343,7 @@ How it behaves: - **When it runs.** On every `ResumeActor` that actually wakes the actor. A `ResumeActor` on an actor that is already `RUNNING` is a no-op and does not probe. - **Block-until-ready semantics.** `ResumeActor` returns successfully only after every container with a `wakeupProbe` has returned HTTP 200. If any container has not done so within `timeoutSeconds` (30s by default), `ResumeActor` fails and the actor moves to `ACTOR_STATE_CRASHED`, as it does for any other error while waking. A crashed actor cannot be resumed directly: `ResumeActor` rejects it with `FAILED_PRECONDITION`. Call `RevertActor` first, which returns it to `ACTOR_STATE_SUSPENDED` with its last snapshot, then resume it again. - **Aggressive polling.** The poll loop is tuned for single-millisecond detection latency: a keep-alive HTTP client with a 1ms interval and 250ms per-request timeout. While the workload is still booting, kernel `RST`s return in microseconds, so the loop spends almost no time blocked; once the listener is up, the next attempt completes on veth-local latency. +- **Egress while waking.** The actor's egress is active before its containers start, so a workload can download what it needs to become ready (a model, a Git repository) before it answers the probe. A micro-VM restored from a memory snapshot is already past its boot, and gets egress just before the probe starts. Its EgressPolicy applies as it does once the actor is `RUNNING`; inbound traffic still waits for the probe. A wake that fails or is cut short after egress is active can be retried from the same snapshot, so outbound requests made while waking can be sent more than once. - **Golden snapshot warm-up shortcut.** When **every** container in a template declares `wakeupProbe`, the actor template controller skips its default ~20s "give the workload time to settle" delay before taking the golden snapshot — `ResumeActor` already blocked until the workload reported 200, so the workload is known to be initialized. Templates that omit `wakeupProbe` on any container keep the 20s warm-up as a safety net. - **Snapshot/restore interaction.** The TCP listener is part of the checkpointed RAM, so on resume `wakeupProbe` typically returns 200 on the first attempt, with no observable latency penalty. @@ -350,7 +351,7 @@ If `wakeupProbe` is omitted from a container, `ResumeActor` returns as soon as t ### Example -A protojson-shaped `ateapipb.ActorTemplate`, created through the ate API with +A protojson-shaped `ateapi.ActorTemplate`, created through the ate API with `kubectl ate create actor-template -f secret-agent.yaml` (the `ate-demo` atespace must exist): @@ -424,7 +425,7 @@ a `Snapshot` with the following fields: it restores. A snapshot captured under a replaced template restores volume data and boots fresh. - `locality`: The node holding the snapshot's local files. For attachment rules, - see `ActorStatus.assigned_node` in the [API schema](../pkg/proto/ateapipb/ateapi.proto). + see `ActorStatus.assigned_node` in the [API schema](../api/ateapi/v1/ateapi.proto). - `durableSnapshot`: The copy in object storage, with its URI in `object.snapshotUri` and a `status` that is `PENDING` while the copy is being written and `COMPLETED` once it can be restored from. A synchronous suspend @@ -455,8 +456,8 @@ a `Snapshot` with the following fields: retries placement. Detach uploads it if needed, deletes the local files, and releases the binding. The retry prefers compatible workers before using the durable fallback above. A detach error leaves the actor attached, - unless its node was deleted before the checkpoint finished uploading. See - [`ResumeActor`](#resumeactor) for that case. + unless its node was deleted. See [`ResumeActor`](#resumeactor) for that + case. A snapshot without `sandboxRuntime` or with `SNAPSHOT_FIDELITY_ROOTFS` or `SNAPSHOT_FIDELITY_VOLUMES` imposes no runtime placement constraint. Because a @@ -533,7 +534,7 @@ atecontroller alone adds and releases the finalizer. While it is down, `kubectl ### Example ```yaml -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: SandboxConfig metadata: name: gvisor-default @@ -641,7 +642,7 @@ The node can cut the 30 minutes short. GKE node upgrades and cluster autoscaler The Substrate Control Plane (`ate-api-server`) exposes a gRPC interface for managing actors and workers. This is the primary API used by the `kubectl-ate` CLI and higher-level frameworks. -### Service: `ateapi.Control` +### Service: `substrate.ateapi.v1.Control` #### `CreateActor` Registers a new logical actor in the system. @@ -668,7 +669,7 @@ Activates a suspended actor by restoring it onto a physical worker. * **Request:** `ResumeActorRequest` * `actor`: `ObjectRef` of the actor to resume. * **Response:** `ResumeActorResponse` containing the updated `Actor` object (including the physical worker placement in `status.worker_assignment`). -* **Errors:** `RESOURCE_EXHAUSTED` if no eligible worker has room. `FAILED_PRECONDITION` if the actor is `ACTOR_STATE_CRASHED`. A suspended actor loses its local snapshot when its node is deleted before that snapshot finishes uploading. Once another node has room, resume moves the actor to `ACTOR_STATE_CRASHED` and returns `FAILED_PRECONDITION`. `RevertActor` then returns it to its last completed external snapshot. +* **Errors:** `RESOURCE_EXHAUSTED` if no eligible worker has room. `FAILED_PRECONDITION` if the actor is `ACTOR_STATE_CRASHED`. When a suspended actor's node is deleted, resume restores its local snapshot on another node from the snapshot's upload, even if atelet never reported the upload complete. Resume does this once another node has room. If atelet finds no upload, resume moves the actor to `ACTOR_STATE_CRASHED` and returns `FAILED_PRECONDITION`. `RevertActor` then returns it to its last completed external snapshot. Revert deletes an upload that was never reported complete, so a snapshot is lost if its restore fails for another reason, or if the actor is reverted before it resumes. #### `SuspendActor` Hibernate a running actor, capturing its current RAM and disk state into a snapshot. @@ -727,7 +728,7 @@ Query the physical resource pool. ate-api-server mints credentials that identify an actor to services outside Substrate. They name the logical actor, so they stay the same as the actor moves between workers. This is distinct from the `actorMetadata` data source described under [SystemInfo Volumes](#systeminfo-volumes), which only tells an actor its own identity fields (name, atespace, uid). -Both RPCs are on `ateapi.Control`. Only the egress gateway may call them; see [authorization.md](authorization.md). It calls `MintActorJwt` when an egress policy injects an actor JWT into a request. +Both RPCs are on `substrate.ateapi.v1.Control`. Only the egress gateway may call them; see [authorization.md](authorization.md). It calls `MintActorJwt` when an egress policy injects an actor JWT into a request. ### `MintActorJwt` diff --git a/docs/csi-deployment.md b/docs/csi-deployment.md index 21c2382295..b646ce1fb5 100644 --- a/docs/csi-deployment.md +++ b/docs/csi-deployment.md @@ -274,7 +274,7 @@ spec: #### 4. Corresponding `CSIDriverConfig` ```yaml -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: CSIDriverConfig metadata: name: nfs.csi.k8s.io diff --git a/docs/csi-volumes.md b/docs/csi-volumes.md index f9052dbd45..d44fb43762 100644 --- a/docs/csi-volumes.md +++ b/docs/csi-volumes.md @@ -30,7 +30,7 @@ To discover and communicate with CSI drivers, Substrate uses dynamic discovery d `CSIDriverConfig` defines the gRPC connection parameters for a specific CSI driver. It bridges the Kubernetes `StorageClass` (referenced in the `ActorTemplate`) to the network endpoint of the CSI Controller service and the local socket path of the CSI Node plugin. ```yaml -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: CSIDriverConfig metadata: name: nfs.csi.k8s.io @@ -132,7 +132,7 @@ mountOptions: ### Step 2: Register the CSIDriverConfig ```yaml -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: CSIDriverConfig metadata: name: nfs.csi.k8s.io @@ -153,7 +153,7 @@ Refer to [ActorTemplate: The Workload Blueprint](api-guide.md#2-actortemplate-th The `WorkerPool` is a Kubernetes resource, applied with `kubectl apply`: ```yaml -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: agent-pool @@ -167,7 +167,7 @@ spec: - name: gvisor ``` -The `ActorTemplate` is a protojson-shaped `ateapipb.ActorTemplate`, created +The `ActorTemplate` is a protojson-shaped `ateapi.ActorTemplate`, created through the ate API with `kubectl ate --preview create actor-template -f -` (the `ate-demo` atespace must exist): diff --git a/docs/dev/code-layout.md b/docs/dev/code-layout.md index b06ce2f72e..ffbde39fee 100644 --- a/docs/dev/code-layout.md +++ b/docs/dev/code-layout.md @@ -8,6 +8,7 @@ file, read this first. ``` substrate/ +├── api/ # Public APIs: protos and CRD types, one directory per API and version ├── cmd/ # Binary entry points (one subdirectory per binary) ├── internal/ # Shared Go packages, not importable outside this module ├── pkg/ # Shared Go packages, intentionally importable by external users @@ -43,6 +44,24 @@ that nothing else in the repo should depend on or import. > adding to `pkg/` is: "I am confident external users need to import this, and I > am prepared to maintain its API indefinitely." +### `api/` + +Public APIs, one directory per API and version: `api//`, and +`api/infra/k8s//` for CRD types. + +| Directory | API | +|---|---| +| `api/ateapi/v1` | Control-plane gRPC API | +| `api/credprovider/v1` | Credential provider plugin gRPC API | +| `api/objectstore/v1` | Object store plugin gRPC API | +| `api/infra/k8s/ate/v1` | Kubernetes CRD types, group `ate.dev` | + +Each `.proto` sits next to its generated Go. Proto packages are +`substrate..`. The Go package is named after the API, as in +`package ateapi`, so imports need no alias. The CRD types follow the Kubernetes +convention instead: `package v1`, imported as `atev1`. A new version of an +API goes in a new directory next to the old one. + ### `cmd//` Each subdirectory of `cmd/` corresponds to one compiled binary: @@ -99,7 +118,8 @@ When adding a new Go package, ask: 1. **Is it only used by one binary?** → `cmd//internal/` 2. **Is it shared by multiple binaries but not meant for external import?** → `internal/` 3. **Is it a deliberately public API for external users?** → `pkg/` -4. **Is it a protobuf-generated package?** - - Public gRPC API (control plane) → `pkg/proto/` +4. **Is it a public API, or a protobuf-generated package?** + - Public gRPC API → `api//` + - Kubernetes CRD types → `api/infra/k8s//` - Internal gRPC API (atelet, ateworker) → `internal/proto/` 5. **Is it a script or dev tool?** → `hack/` (shell) or `tools/` (Go) diff --git a/docs/dev/microvm-local.md b/docs/dev/microvm-local.md index 54d582b323..cbbb25e541 100644 --- a/docs/dev/microvm-local.md +++ b/docs/dev/microvm-local.md @@ -107,18 +107,13 @@ brew install lima docker ### 2. Launch Lima with nested virtualization -The arm64 nested-virtualization kernel regression affects kernels 6.19 and -newer, so use a guest image with an older kernel — pinned here to Ubuntu -24.04 LTS: +Start the `docker-rootful` template with nested virtualization and a writable home mount: ```sh -limactl start --name=docker-nested template://docker-rootful --nested-virt --set '.images = [ -{"location":"https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img","arch":"aarch64"}, -{"location":"https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img","arch":"x86_64"} -]' +limactl start --name=docker-nested template:docker-rootful --cpus=8 --memory=16 --nested-virt --mount-writable ``` -When prompted to edit the configuration, set at least: +If prompted to edit the configuration, verify it includes at least: ```yaml cpus: 8 @@ -135,6 +130,23 @@ The writable home mount lets the kind/ko workflows write into your checkout, 8 CPUs / 16 GiB is a comfortable floor for the control plane plus a microVM worker, and `vzNAT` gives the VM outbound networking under the vz VM type. +On `arm64` (`amd64` is unaffected), Linux 6.19 and newer clear the active state +of GICv3 LPIs when folding list registers on a VM exit (upstream commit +`73c9726975af`). Under nested virtualization, hardware EOI in the L2 microVM +guest then leaves the interrupt priority active in `ICH_AP1R0_EL2` and blocks +subsequent `virtio` interrupts. Enable `kvm-arm.vgic_v3_group1_trap=1` on the +Lima guest kernel so L1 KVM traps Group 1 EOI writes and clears the active +priority in software: + +```sh +limactl shell docker-nested sudo tee /etc/default/grub.d/99-vgic-trap.cfg <<'EOF' +GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_DEFAULT:-} kvm-arm.vgic_v3_group1_trap=1" +EOF +limactl shell docker-nested sudo update-grub +limactl stop docker-nested +limactl start docker-nested +``` + ### 3. Assemble the arm64 assets inside the Lima VM Assemble the arm64 assets in the guest because macOS does not ship `zstd` by default: @@ -142,10 +154,6 @@ Assemble the arm64 assets in the guest because macOS does not ship `zstd` by def ```sh limactl shell docker-nested -# Inside the VM — 24.04's git 2.43 can't read a reftable checkout: -sudo add-apt-repository -y ppa:git-core/ppa -sudo apt-get install -y git - cd # visible via the writable home mount ./hack/microvm-assets/assemble.sh exit @@ -188,3 +196,4 @@ requires a full guest boot and checkpoint. |---|---|---| | `/dev/kvm: permission denied` during the kind KVM probe | Rootless Docker: the probe container's root is remapped to your user, which can't open the device (`660 root:kvm`) | Use rootful Docker, or `sudo chmod 666 /dev/kvm` before `./hack/create-kind-cluster.sh` | | Lima: `[hostagent] Starting VZ ... FATA exiting` on M1/M2 | Apple's Virtualization framework supports nested virtualization only on M3 and later | Use an M3+ Mac, or a Linux/KVM host (Option A) | +| MicroVM golden build or actor boot hangs on arm64 Linux 6.19+ | L1 KVM drops LPI active state on VM exits, stalling `virtio` interrupts in nested guests | Add `kvm-arm.vgic_v3_group1_trap=1` to the Lima VM kernel command line and reboot (Option B, step 2) | diff --git a/docs/egress-credential-injection.md b/docs/egress-credential-injection.md index d402b017a7..daa1ea9adf 100644 --- a/docs/egress-credential-injection.md +++ b/docs/egress-credential-injection.md @@ -306,7 +306,7 @@ serve (see the note in `k8s-credential-provider.yaml`). ### The plugin API The provider is a plugin: any gRPC service that implements -`CredentialProvider.FetchSecret` (`pkg/proto/credproviderpb/credprovider.proto`) +`CredentialProvider.FetchSecret` (`api/credprovider/v1/credprovider.proto`) can back injection. To bring your own — reading HashiCorp Vault, Google Secret Manager, or any other secret store — implement the API under your own provider class (the URI host, e.g. `ate-secret://vault.example.com/...`), then have a @@ -353,7 +353,7 @@ may only resolve Secrets in namespaces explicitly granted to it. projection needed for HTTPS injection. * `demos/egress/README.md` — how tunneled egress, actor identity, and policy authorization fit together. -* `pkg/proto/credproviderpb/credprovider.proto` — the provider plugin API and +* `api/credprovider/v1/credprovider.proto` — the provider plugin API and its trust model. * `cmd/credential-provider/kubernetes-secrets` — the reference provider. * `internal/e2e/suites/egresscredinject` — the e2e suite that proves the diff --git a/docs/egress-trust-bundle.md b/docs/egress-trust-bundle.md index d0a0f3be31..c4bd330253 100644 --- a/docs/egress-trust-bundle.md +++ b/docs/egress-trust-bundle.md @@ -41,7 +41,7 @@ rule, are answered `NXDOMAIN`. Add a `systemInfo` volume with a `trustBundle` data source, and mount it: ```yaml -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: ActorTemplate metadata: name: my-actor diff --git a/docs/kubernetes-credential-provider.md b/docs/kubernetes-credential-provider.md index 8dec0ef9ea..638a1f16af 100644 --- a/docs/kubernetes-credential-provider.md +++ b/docs/kubernetes-credential-provider.md @@ -23,7 +23,7 @@ which namespaces each actor may use. Empty policies deny all requests. AGW must support protocol-specific egress rules and `replace_headers`, along with the [actor identity update](https://github.com/agentgateway/agentgateway/pull/3677) -and the current [FetchSecret contract](../pkg/proto/credproviderpb/credprovider.proto). +and the current [FetchSecret contract](../api/credprovider/v1/credprovider.proto). Create the MITM CA Secret using the existing installation tooling: diff --git a/docs/metrics/registry/metrics.yaml b/docs/metrics/registry/metrics.yaml index 491577f943..5201d98c32 100644 --- a/docs/metrics/registry/metrics.yaml +++ b/docs/metrics/registry/metrics.yaml @@ -88,7 +88,7 @@ groups: note: > Logs only. It is bounded, but it is only ever recorded beside actor identity, which no metric may carry. The values mirror - ateapipb.ActorState with the ACTOR_STATE_ prefix dropped, so the log + ateapi.ActorState with the ACTOR_STATE_ prefix dropped, so the log vocabulary and the state machine cannot fork. type: members: @@ -526,13 +526,21 @@ groups: value: unavailable brief: > The request got an Unavailable status, or a 503 without a gRPC - cause. For example, a denied egress request, a failed policy or - credential lookup, or a full parking lot when the resume did not - fail with ResourceExhausted. + cause. For example, a failed policy or credential lookup, or a + full parking lot when the resume did not fail with + ResourceExhausted. - id: rate_limited stability: development value: rate_limited brief: The router limited the rate of the request. + - id: denied + stability: development + value: denied + brief: > + The router refused the request by policy, with a 403 or a + PermissionDenied status. For example, an egress request that + the actor's egress policy does not allow. It is a policy + decision, not a defect. - id: resume_error stability: development value: resume_error @@ -770,7 +778,7 @@ groups: stability: stable type: string brief: The gRPC method of the request. - examples: ["ateapi.Control/ResumeActor"] + examples: ["substrate.ateapi.v1.Control/ResumeActor"] - id: rpc.response.status_code stability: stable type: string diff --git a/docs/network-egress.md b/docs/network-egress.md index 94344e9072..5400c1cede 100644 --- a/docs/network-egress.md +++ b/docs/network-egress.md @@ -24,9 +24,9 @@ In the default Kubernetes deployment, the PEP obtains its certificate and privat ## Client Authorization -`atunnel` MUST present an actor-specific client certificate when connecting to the PEP. At actor activation, `atunnel` generates a private key and requests a short-lived certificate from substrate through the node-local atelet. The private key remains in `atunnel`. The certificate identifies the actor by its atespace, name, and UID and is scoped to the `atunnel` purpose. +`atunnel` MUST present an actor-specific client certificate when connecting to the PEP. Before the actor's workload starts, `atunnel` generates a private key and requests a short-lived certificate from substrate through the node-local atelet, and egress is active from then on: a workload may need the network to become ready, so egress does not wait for the wakeup probe the way ingress does. The private key remains in `atunnel`. The certificate identifies the actor by its atespace, name, and UID and is scoped to the `atunnel` purpose. -The PEP MUST require and verify the client certificate before accepting a CONNECT request. It MUST verify the certificate chain and lifetime against the Actor Identity CA, require the client authentication usage, and require exactly one valid `ActorIdentity` extension whose atespace, actor name, actor UID, and purpose are present. The current extension OID is `1.3.6.1.4.1.11129.2.12.2`; it is allocated under Google's enterprise number and will change after the CNCF donation is complete. The purpose MUST be `atunnel`, and the certificate's actor URI SAN MUST identify the same actor as the extension. The PEP MUST then confirm with ate-api-server that the actor still exists, that its current UID matches the certificate, and that it is running. The PEP MUST reject the CONNECT request if any of these checks fail. +The PEP MUST require and verify the client certificate before accepting a CONNECT request. It MUST verify the certificate chain and lifetime against the Actor Identity CA, require the client authentication usage, and require exactly one valid `ActorIdentity` extension whose atespace, actor name, actor UID, and purpose are present. The current extension OID is `1.3.6.1.4.1.11129.2.12.2`; it is allocated under Google's enterprise number and will change after the CNCF donation is complete. The purpose MUST be `atunnel`, and the certificate's actor URI SAN MUST identify the same actor as the extension. The PEP MUST then confirm with ate-api-server that the actor still exists, that its current UID matches the certificate, and that it is placed on a worker: `RESUMING` (booting or restoring there) or `RUNNING`. The PEP MUST reject the CONNECT request if any of these checks fail. ```text CURRENT CONNECT EGRESS PATH (one tunnel per actor TCP connection except destination port 53) diff --git a/docs/observability.md b/docs/observability.md index 9b2d79ee34..f94c0b2480 100644 --- a/docs/observability.md +++ b/docs/observability.md @@ -171,7 +171,7 @@ ateapi's `Actor state changed` is written once per committed actor state transit "trace_id":"4bf92f…","span_id":"00f067…","trace_flags":"01"} ``` -`ate.actor.state` takes the `ateapipb.ActorState` values lowercased, so the log vocabulary and the state machine cannot fork. The last record for an actor's uid is the state it is in now, and its timestamp is when that state began. Query it per actor, not in aggregate: neither key is a metric label, because both only ever appear beside actor identity, which [the cardinality rules](#the-metric-registry) keep off metrics entirely. +`ate.actor.state` takes the `ateapi.ActorState` values lowercased, so the log vocabulary and the state machine cannot fork. The last record for an actor's uid is the state it is in now, and its timestamp is when that state began. Query it per actor, not in aggregate: neither key is a metric label, because both only ever appear beside actor identity, which [the cardinality rules](#the-metric-registry) keep off metrics entirely. `ate.actor.operation.name` says which operation drove the transition, which the state alone does not: an actor reaches `suspended` both when it is created and when it is suspended. SuspendActor in either durability mode is one operation, labeled `suspend`. @@ -179,7 +179,7 @@ The record goes out after the store commit, never before, and the state is read Creating an actor counts as a change. A new actor is born suspended, so it gets a record saying so, with `ate.actor.operation.name` set to `create`. Otherwise an actor that is created and never resumed would have no record at all, no matter how long you keep your logs. -`deleted` is the only state with no `ateapipb.ActorState` behind it. It is written once the actor row is gone, so there is nothing left to read back. It is also the last record an actor ever gets. Without it, `deleting` would be the end of the story, and a delete that finished would look just like one that got stuck. +`deleted` is the only state with no `ateapi.ActorState` behind it. It is written once the actor row is gone, so there is nothing left to read back. It is also the last record an actor ever gets. Without it, `deleting` would be the end of the story, and a delete that finished would look just like one that got stuck. **What this stream won't tell you.** It only writes when something changes. So an actor that has been sitting in the same state since before your logs roll over has no record, and no state. Ask the control plane what state something is in right now. Use this stream to see how it got there and when. Records can also go missing, like any other log, and a gap looks the same as an actor that just sat still. If you want to count activations, use the router's access log instead. @@ -320,7 +320,7 @@ For `ate.workerpool.workers`: When one backend receives several clusters, add `cluster` to both groupings, or same-named pools in different clusters merge. For `atenet.router.route.duration`: -* `ate.router.outcome` categorizes the route attempt result: `ok`, `cancelled`, `timeout`, `no_capacity`, `failed_precondition`, `lock_conflict`, `not_found`, `unavailable`, `rate_limited`, or `resume_error`. +* `ate.router.outcome` categorizes the route attempt result: `ok`, `cancelled`, `timeout`, `no_capacity`, `failed_precondition`, `lock_conflict`, `not_found`, `unavailable`, `rate_limited`, `denied`, or `resume_error`. `denied` is a request the router refused by policy (a 403 or `PermissionDenied`), such as an egress request outside the actor's egress policy; `resume_error` is left for a resume that failed for any other reason, a router defect. * The router and the scheduler both report `no_capacity` for one condition, but they count different events. The scheduler records one sample on `ate.scheduler.assignment.duration` for each resume. The router records one sample for each request. Many requests can join one resume, and one parked request can cause more than one resume. Thus do not compare the two counts directly. * `ate.router.resume` indicates the singleflight execution state of actor resumption: `none` (the resume found the actor already running), `triggered` (this request completed a cold activation), `joined` (this request waited on another request's resume, which activated the actor), or `unknown` (the resume did not complete, so whether an activation ran is unknown). `ate.template.atespace` and `ate.template.name` hold `unknown` when the router has no template to name. diff --git a/docs/resource-model.md b/docs/resource-model.md index 6aba72da9d..8a28734a06 100644 --- a/docs/resource-model.md +++ b/docs/resource-model.md @@ -2,10 +2,10 @@ Substrate exposes resources through two APIs: -- a **gRPC API** (`pkg/proto/ateapipb/ateapi.proto`), served by the +- a **gRPC API** (`api/ateapi/v1/ateapi.proto`), served by the Substrate API server. Its resources follow the [API Style Guide](api-style-guide.md). -- The **Kubernetes API**, through CRDs in `pkg/api/v1alpha1`, for +- The **Kubernetes API**, through CRDs in `api/infra/k8s/ate/v1`, for managing compute infrastructure. Its resources follow the [Kubernetes API conventions](https://github.com/kubernetes/community/blob/main/contributors/devel/sig-architecture/api-conventions.md) diff --git a/docs/roadmap.md b/docs/roadmap.md deleted file mode 100644 index c9e0426df9..0000000000 --- a/docs/roadmap.md +++ /dev/null @@ -1,141 +0,0 @@ -# Agent Substrate Roadmap - -## Overview - -Agent Substrate is a security-hardened, zero-trust runtime for sandboxed agents, engineered to safely run millions of agents and tools with 10x higher density than standard containers. Purpose-built for the era of autonomous agents, Substrate delivers fast resume operations in less than 400ms, with more than 1500 activations per second. Agents get isolated compute, identity, networking, and storage. Sensitive credentials are kept out of reach from untrusted code. It supports multiple sandbox technologies, including microVMs and gVisor, while enabling a consistent lifecycle and management of all sandboxes. - -Substrate builds on sandboxed, snapshottable Pods by adding the ability to update running containers in the Pod leveraging the high scale and low latency Agent Substrate control plane. Substrate enables these containers to rapidly cycle between active and inactive lifecycle phases with fast suspend and resume from snapshots in inexpensive cloud object storage, without losing in-memory or filesystem state. This is especially critical for agentic workloads, which frequently oscillate between active (handling user input) and idle (waiting for LLMs or tool calls to complete). With Substrate, resources can be reclaimed during these idle moments for use by other workloads. This enables both greater efficiency and greater scale than using Pods alone, while still leveraging Kubernetes to provision capacity, configure networking and storage, and manage Substrate itself. - -This project is trying to move very quickly to find the right set of capabilities for the ever-changing agentic workloads market. Below are our priorities. Any efforts which are not aligned with these priorities should probably be deferred. - -1. Pinning down architectural decisions which influence the rest of these priorities. -2. Performance and reliability of wakeups, including suspend/resume and snapshot management. -3. A fast, scalable control-plane, including the storage layer, reliability, and security. -4. Useful identity, such that policies can be written in terms of identity. -5. Useful policy, including how users can specify ingress, egress, and peer networking. -6. Runtime modularity, such that different kinds of sandboxes (gVisor, microVMs, etc) can be used. - -Below is a collection of finer-grained efforts which we believe align with the above. - -## Coming Soon: High Priority - -### Actor Management (Compute) - -* Actor versioning via ActorTemplate (or new ActorDeployment API), with support for A/B testing and rollout strategies. -* Namespaces or a similar concept for grouping related actors together for both management and convenience of writing actor-to-actor authorization policy. -* Actor Forking/Cloning: Ability to branch a new logical actor from an existing checkpoint (the 'State Root') to support complex agent reasoning paths. -* Worker horizontal autoscaling: Ability to rapidly scale up nodes and warm Pods to meet actor demand. -* Clarify the actor lifecycle, including what data is retained across which events (e.g. gvisor upgrade \-\> loss of memory snapshot) -* Decide: What mode(s) of actor runs do we support? Can we prioritize and phase this? Assuming we always persist “working” data - * Clean start from OCI for every activation - * Resume from golden for every activation - * Persist rootfs (when possible), clean binary start for every activation - * Persist rootfs and memory (when possible), full process resume - -### Worker management - -* Worker class (e.g. free-tier on cheap hardware, premium on good hardware) -* Fungible worker pools (any worker in a class can run any actor in that class) - -### Control-plane - -* User authorization -* Good CLI - -### Networking - -* Actor security boundary implementation, default deny with explicit ACLs at scale with low latency. This overlaps with some of the security items (see below). -* Policy definition: between framework (outside) and Actors, between Actors, Actor Egress. -* Actor-to-actor routing through explicit actor-reference headers. - -### Storage - -* gVisor snapshot/resume optimizations - * storage tiering (local zswap, local SSD, peer-to-peer, blob) - * incremental snapshots -* Support for S3 (via plugin) -* Distinct lifecycle for “rootfs” and memory snapshots vs. “working” space. Needs API surface of where to mount. -* ConfigMaps as volumes -* Data locality in scheduling (needs to expose per-node available snapshots via API) - -### Security - -* Goal of two security boundaries between mutually untrusted actors that share the same Kubernetes node. -* Secure mTLS authentication and authorization between all system components. -* Secure actor-to-actor authentication and authorization policy that can be deployed in-band with actor lifecycle, maintaining low latency deployment. -* Ability to specify network policy for individual actors, including L7 protocol-aware filtering rules, that can be deployed in-band with actor lifecycle, maintaining low latency deployment. -* Credential injection, including actor identity, via proxies to eliminate exposure of cryptographic keys and bearer tokens to actors. -* Audit logging on API and lifecycle operations. -* Sandbox integrations for threat detection telemetry. -* Harden actor networking to further isolate from the surrounding node (e.g. with current networking - -### Observability - -* Actor-Aware Telemetry Correlation: Automated OTLP export where all logs, metrics, and traces are natively tagged with the Substrate actor name and worker ID. -* Prometheus metrics - -### Performance and Reliability - -* Representative workloads/traffic patterns -* Provisioning load test and benchmarking compute/infrastructure -* Storage and visualization for benchmark results -* Integrate debugging into load tests -* State Store Scale: PostgreSQL scaling and partitioning support to enable management of 1M+ concurrent actors. -* Disk-Only Resume Policy: Support for cost-optimized hibernation where only the filesystem state is preserved, skipping the RAM restore for stateless or "cold" start-capable agents. - -### Testing - -* Support for local development and testing on KinD clusters. -* Define sufficient test matrices (what container system, clouds, other configuration knobs should be tested) -* Burn-in testing to detect memory/other resource leaks -* Mock LLMs/other dependencies - -### Integrations - -* Tight integration with Agent Executor for deploying AX on Kubernetes. -* Agent Development Kit (ADK) Native Support: Developing first-class bindings for ADK, allowing developers to build stateful agents that natively leverage Substrate’s lifecycle management and persistent working memory. -* LangChain Remote Execution Provider: A dedicated provider for LangChain to run complex, long-running agent tools in durable, sandboxed environments. -* Native MCP Server Hosting: Built-in support for deploying Model Context Protocol (MCP) servers as managed Substrate Actors, creating a secure tool ecosystem for any LLM. -* Actor-to-Actor (A2A) Calling Model: Standardized protocol for actors to discover and call other actors within Substrate via the gateway. -* Native MCP Tool Hosting: Ability to define and deploy standard Model Context Protocol (MCP) servers as managed Substrate Actors, providing a plug-and-play ecosystem for agentic tools. - -### Operability - -* Control-plane upgrades -* Worker upgrades -* Gvisor upgrades -* API schema changes -* Plan for growth from small to large (esp. wrt CP sharding) - -## Additional ideas we are thinking about - -### Actor Management (Compute) - -* Vertical worker autoscaling and IPPU (e.g. retain the memory/CPU config of the previous snapshot and update the worker pod when we assign an actor) -* Actor-\>worker selectors, taints, etc. -* Automated Garbage Collection: Background cleanup of idle actors based on configurable TTL - -### Storage - -* Policies to drive retention of old snapshots and controller(s) to do automated cleanups -* Peer-to-peer OCI and snapshot sharing -* K8s “projected” volumes, other than ConfigMap -* Storage model supported by external storage plugins (via CSI drivers?). -* Shared writeable storage across actors (e.g. an NFS volume). - -### Security - -* Ability for actors to delegate downscoped rights to children and peers. -* Image-pull credentials - -### Performance and Reliability - -* Shared image cache - -### Integrations - -* Stateful Coding Adapters: Standardized environment templates for Claude Code and CodeX to enable AI coding tasks that maintain persistent filesystem state across terminal sessions. - -### Administrative - -* Ability to run multiple substrates in a single cluster diff --git a/hack/ate-dev-env.sh.example b/hack/ate-dev-env.sh.example index 0e9a8bc72b..653e1e42c1 100644 --- a/hack/ate-dev-env.sh.example +++ b/hack/ate-dev-env.sh.example @@ -25,9 +25,9 @@ export NETWORK=default export SUBNETWORK=default export CLUSTER_NAME=substrate-poc -# Supported: 1.36 (needs the beta APIs enabled at cluster creation, which -# setup-gcp does) or 1.37+ (APIs served by default). Anything below 1.36 does -# not work. GKE retires patch versions over time — if cluster creation rejects +# Supported: 1.36 with the v1beta1 PodCertificate APIs enabled, which setup-gcp +# does, or 1.37+, which serves them under v1. Anything below 1.36 does not +# work. GKE retires patch versions over time — if cluster creation rejects # this pin, pick a current one from: # gcloud container get-server-config --zone ${CLUSTER_LOCATION} --format="value(defaultClusterVersion)" # See tools/setup-gcp/README.md ("Create Cluster") for the full constraint. diff --git a/hack/setup-csi-hostpath-kind.sh b/hack/setup-csi-hostpath-kind.sh index c412fc89ce..37b575e44f 100755 --- a/hack/setup-csi-hostpath-kind.sh +++ b/hack/setup-csi-hostpath-kind.sh @@ -119,7 +119,7 @@ kubectl rollout status statefulset/csi-hostpath-socat -n default --timeout=120s # 8. Create the CSIDriverConfig for Substrate echo "Creating hostpath.csi.k8s.io CSIDriverConfig..." cat <= 0 { // Expiry blocks only new tunnels. Connections admitted with a valid // certificate have completed mTLS and are allowed to drain normally. e.mu.Unlock() + // renew logs the expiry or the denied renewal once at Warn. + slog.DebugContext(active.ctx, "atunnel dropped an egress connection: actor has no valid certificate", + slog.String("actorUID", active.actorUID)) _ = downstream.Close() return } diff --git a/internal/atunnel/tunnel.go b/internal/atunnel/tunnel.go index 484b288995..4372bbb125 100644 --- a/internal/atunnel/tunnel.go +++ b/internal/atunnel/tunnel.go @@ -236,12 +236,10 @@ func (t *Tunnel) PrepareEgress(ctx context.Context, actor resources.ActorAttribu return &ActorEgress{client: gatewayClient, certificateSource: certificateSource, expiresAt: expiresAt}, nil } -// Activate starts admitting the actor's traffic. Ingress reaches the actor -// through dial; egress is activated only when it was prepared. -func (t *Tunnel) Activate(actor resources.ActorAttribution, dial ingress.DialFunc, actorEgress *ActorEgress) error { - if err := t.Ingress.Activate(actor.Ref.Atespace, actor.Ref.Name, actor.UID, dial); err != nil { - return fmt.Errorf("while activating actor ingress: %w", err) - } +// ActivateEgress starts tunneling the actor's outbound traffic. Call it before +// the workload starts, since a workload may need the network to become ready. +// A nil egress is a no-op. +func (t *Tunnel) ActivateEgress(actor resources.ActorAttribution, actorEgress *ActorEgress) error { if actorEgress == nil { return nil } @@ -251,6 +249,15 @@ func (t *Tunnel) Activate(actor resources.ActorAttribution, dial ingress.DialFun return nil } +// ActivateIngress starts admitting the actor's inbound traffic through dial. +// Call it once the workload is ready to serve. +func (t *Tunnel) ActivateIngress(actor resources.ActorAttribution, dial ingress.DialFunc) error { + if err := t.Ingress.Activate(actor.Ref.Atespace, actor.Ref.Name, actor.UID, dial); err != nil { + return fmt.Errorf("while activating actor ingress: %w", err) + } + return nil +} + // Deactivate stops admitting the actor's traffic and drains its active streams, // before the actor network is torn down. It attempts both directions even if // one fails. diff --git a/internal/atunnel/tunnel_test.go b/internal/atunnel/tunnel_test.go index 8a0b7aa5e6..0a28956cac 100644 --- a/internal/atunnel/tunnel_test.go +++ b/internal/atunnel/tunnel_test.go @@ -327,8 +327,11 @@ func TestActivateAndDeactivate(t *testing.T) { actor := resources.ActorAttribution{Ref: resources.ActorRef{Atespace: "space", Name: "actor"}, UID: "uid"} dial := func(context.Context, string, string) (net.Conn, error) { return nil, net.ErrClosed } - if err := tunnel.Activate(actor, dial, nil); err != nil { - t.Fatalf("Activate without egress: %v", err) + if err := tunnel.ActivateEgress(actor, nil); err != nil { + t.Fatalf("ActivateEgress without a gateway: %v", err) + } + if err := tunnel.ActivateIngress(actor, dial); err != nil { + t.Fatalf("ActivateIngress: %v", err) } if err := tunnel.Deactivate(ctx, actor); err != nil { t.Fatalf("Deactivate: %v", err) @@ -338,8 +341,8 @@ func TestActivateAndDeactivate(t *testing.T) { t.Fatalf("second Deactivate: %v", err) } - err := tunnel.Activate(resources.ActorAttribution{UID: "uid"}, dial, nil) + err := tunnel.ActivateIngress(resources.ActorAttribution{UID: "uid"}, dial) if err == nil || !strings.Contains(err.Error(), "while activating actor ingress") { - t.Fatalf("Activate with no actor reference = %v, want an ingress error", err) + t.Fatalf("ActivateIngress with no actor reference = %v, want an ingress error", err) } } diff --git a/internal/benchmarking/boomer/agentsession/agentsession.go b/internal/benchmarking/boomer/agentsession/agentsession.go index 9f1dbc013d..647b22e1a9 100644 --- a/internal/benchmarking/boomer/agentsession/agentsession.go +++ b/internal/benchmarking/boomer/agentsession/agentsession.go @@ -49,6 +49,7 @@ import ( "github.com/google/uuid" "github.com/prometheus/client_golang/prometheus" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateinterceptors" "go.ate.dev/substrate/internal/atenet" "go.ate.dev/substrate/internal/benchmarking/boomer/boomerutil" @@ -57,7 +58,6 @@ import ( "go.ate.dev/substrate/internal/benchmarking/boomer/userclass" "go.ate.dev/substrate/internal/benchmarking/glutton" gluttonpb "go.ate.dev/substrate/internal/proto/glutton" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/propagation" "google.golang.org/grpc" @@ -344,8 +344,8 @@ func (r *runtime) checkTemplateMemory(ctx context.Context, script *Script) error if r.templateErr != nil && r.templateErrFor == script && time.Since(r.templateErrAt) < templateRecheckInterval { return r.templateErr } - ref := &ateapipb.ObjectRef{Atespace: templateNS, Name: templateName} - tmpl, err := r.cfg.APIStub.GetActorTemplate(ctx, &ateapipb.GetActorTemplateRequest{ActorTemplate: ref}) + ref := &ateapi.ObjectRef{Atespace: templateNS, Name: templateName} + tmpl, err := r.cfg.APIStub.GetActorTemplate(ctx, &ateapi.GetActorTemplateRequest{ActorTemplate: ref}) if err != nil { // Not a verdict: the next startUser asks again. return fmt.Errorf("GetActorTemplate %s/%s: %w", templateNS, templateName, err) @@ -373,7 +373,7 @@ func (r *runtime) checkTemplateMemory(ctx context.Context, script *Script) error // memoryLimit reads the template's memory limit in bytes. found is false // when the template sets none. -func memoryLimit(tmpl *ateapipb.ActorTemplate) (limit int64, found bool, err error) { +func memoryLimit(tmpl *ateapi.ActorTemplate) (limit int64, found bool, err error) { limit = tmpl.GetResources().GetLimits().GetMemoryBytes() return limit, limit != 0, nil } @@ -708,8 +708,8 @@ func (u *sessionUser) noteSuccess() { u.consecutiveFailures = 0 } -func (u *sessionUser) ref() *ateapipb.ObjectRef { - return &ateapipb.ObjectRef{Atespace: u.cfg.Atespace, Name: u.actorName} +func (u *sessionUser) ref() *ateapi.ObjectRef { + return &ateapi.ObjectRef{Atespace: u.cfg.Atespace, Name: u.actorName} } // shouldHibernateAtStart reports whether a freshly started session should be @@ -1017,9 +1017,9 @@ func (u *sessionUser) postProto(ctx context.Context, route string, req, resp pro // success so concurrent sessions racing the first creation all proceed. func (u *sessionUser) ensureAtespace(ctx context.Context) error { return u.tracedCall(ctx, "CreateAtespace", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.CreateAtespace(callCtx, &ateapipb.CreateAtespaceRequest{ - Atespace: &ateapipb.Atespace{ - Metadata: &ateapipb.ResourceMetadata{Name: u.cfg.Atespace}, + _, err := u.cfg.APIStub.CreateAtespace(callCtx, &ateapi.CreateAtespaceRequest{ + Atespace: &ateapi.Atespace{ + Metadata: &ateapi.ResourceMetadata{Name: u.cfg.Atespace}, }, }, grpc.Trailer(tr)) if s, ok := status.FromError(err); ok && s.Code() == codes.AlreadyExists { @@ -1031,10 +1031,10 @@ func (u *sessionUser) ensureAtespace(ctx context.Context) error { func (u *sessionUser) create(ctx context.Context) error { return u.tracedCall(ctx, "CreateActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.CreateActor(callCtx, &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: u.cfg.Atespace, Name: u.actorName}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: templateNS, Name: templateName}, + _, err := u.cfg.APIStub.CreateActor(callCtx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: u.cfg.Atespace, Name: u.actorName}, + ActorTemplate: &ateapi.ObjectRef{Atespace: templateNS, Name: templateName}, }, }, grpc.Trailer(tr)) return err @@ -1068,7 +1068,7 @@ func (u *sessionUser) waitServing(ctx context.Context) error { func (u *sessionUser) resume(ctx context.Context) error { err := u.tracedCall(ctx, "ResumeActor", func(callCtx context.Context, tr *metadata.MD) error { return boomerutil.RetryOnConflict(callCtx, func() error { - _, err := u.cfg.APIStub.ResumeActor(callCtx, &ateapipb.ResumeActorRequest{Actor: u.ref()}, grpc.Trailer(tr)) + _, err := u.cfg.APIStub.ResumeActor(callCtx, &ateapi.ResumeActorRequest{Actor: u.ref()}, grpc.Trailer(tr)) return err }) }) @@ -1099,12 +1099,12 @@ func (u *sessionUser) hibernate(ctx context.Context) { var err error if mode == dynconfig.LifecycleModeSync { err = u.tracedCall(ctx, "SuspendActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapipb.SuspendActorRequest{Actor: u.ref(), Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}, grpc.Trailer(tr)) + _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapi.SuspendActorRequest{Actor: u.ref(), Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}, grpc.Trailer(tr)) return err }) } else { err = u.tracedCall(ctx, "SuspendActorAsync", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapipb.SuspendActorRequest{Actor: u.ref(), Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}, grpc.Trailer(tr)) + _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapi.SuspendActorRequest{Actor: u.ref(), Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}, grpc.Trailer(tr)) return err }) } @@ -1124,10 +1124,10 @@ func (u *sessionUser) suspendAndDelete(ctx context.Context) { return } suspendCtx, cancel := context.WithTimeout(ctx, controlRPCTimeout) - _, _ = u.cfg.APIStub.SuspendActor(suspendCtx, &ateapipb.SuspendActorRequest{Actor: u.ref()}) + _, _ = u.cfg.APIStub.SuspendActor(suspendCtx, &ateapi.SuspendActorRequest{Actor: u.ref()}) cancel() _ = u.tracedCall(ctx, "DeleteActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.DeleteActor(callCtx, &ateapipb.DeleteActorRequest{Actor: u.ref()}, grpc.Trailer(tr)) + _, err := u.cfg.APIStub.DeleteActor(callCtx, &ateapi.DeleteActorRequest{Actor: u.ref()}, grpc.Trailer(tr)) return err }) bmetrics.UpdateUsers(agentSessionUserClass, -1) diff --git a/internal/benchmarking/boomer/agentsession/agentsession_test.go b/internal/benchmarking/boomer/agentsession/agentsession_test.go index 23d0e76f18..9c46dc1227 100644 --- a/internal/benchmarking/boomer/agentsession/agentsession_test.go +++ b/internal/benchmarking/boomer/agentsession/agentsession_test.go @@ -31,11 +31,11 @@ import ( "time" "github.com/prometheus/client_golang/prometheus" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/benchmarking/boomer/boomerutil" "go.ate.dev/substrate/internal/benchmarking/boomer/dynconfig" "go.ate.dev/substrate/internal/benchmarking/boomer/userclass" "go.ate.dev/substrate/internal/benchmarking/glutton/fake" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -637,13 +637,13 @@ func TestThinkScaling(t *testing.T) { // fakeControlClient records control-plane calls and fails ResumeActor / // SuspendActor with queued errors, in order, until each queue drains. type fakeControlClient struct { - ateapipb.ControlClient + ateapi.ControlClient mu sync.Mutex calls []string resumeErrs []error suspendErrs []error // suspendReqs holds every SuspendActor request, in arrival order. - suspendReqs []*ateapipb.SuspendActorRequest + suspendReqs []*ateapi.SuspendActorRequest // sawDeadline is set when a call arrived with a context deadline. sawDeadline bool // templateMemory is the memory limit GetActorTemplate reports in bytes; 0 means @@ -679,21 +679,21 @@ func (f *fakeControlClient) record(ctx context.Context, name string) { } } -func (f *fakeControlClient) GetActorTemplate(ctx context.Context, in *ateapipb.GetActorTemplateRequest, opts ...grpc.CallOption) (*ateapipb.ActorTemplate, error) { +func (f *fakeControlClient) GetActorTemplate(ctx context.Context, in *ateapi.GetActorTemplateRequest, opts ...grpc.CallOption) (*ateapi.ActorTemplate, error) { f.record(ctx, "GetActorTemplate") - tmpl := &ateapipb.ActorTemplate{} + tmpl := &ateapi.ActorTemplate{} if f.templateMemory != 0 { - tmpl.Resources = &ateapipb.ResourceRequirements{Limits: &ateapipb.Resources{MemoryBytes: f.templateMemory}} + tmpl.Resources = &ateapi.ResourceRequirements{Limits: &ateapi.Resources{MemoryBytes: f.templateMemory}} } return tmpl, nil } -func (f *fakeControlClient) CreateAtespace(ctx context.Context, in *ateapipb.CreateAtespaceRequest, opts ...grpc.CallOption) (*ateapipb.Atespace, error) { +func (f *fakeControlClient) CreateAtespace(ctx context.Context, in *ateapi.CreateAtespaceRequest, opts ...grpc.CallOption) (*ateapi.Atespace, error) { f.record(ctx, "CreateAtespace") - return &ateapipb.Atespace{}, nil + return &ateapi.Atespace{}, nil } -func (f *fakeControlClient) CreateActor(ctx context.Context, in *ateapipb.CreateActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { +func (f *fakeControlClient) CreateActor(ctx context.Context, in *ateapi.CreateActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { f.record(ctx, "CreateActor") if f.createStarted != nil { select { @@ -704,20 +704,20 @@ func (f *fakeControlClient) CreateActor(ctx context.Context, in *ateapipb.Create if f.createGate != nil { <-f.createGate } - return &ateapipb.Actor{}, nil + return &ateapi.Actor{}, nil } -func (f *fakeControlClient) ResumeActor(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { +func (f *fakeControlClient) ResumeActor(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { f.record(ctx, "ResumeActor") f.mu.Lock() defer f.mu.Unlock() if err := nextErr(&f.resumeErrs); err != nil { return nil, err } - return &ateapipb.ResumeActorResponse{}, nil + return &ateapi.ResumeActorResponse{}, nil } -func (f *fakeControlClient) SuspendActor(ctx context.Context, in *ateapipb.SuspendActorRequest, opts ...grpc.CallOption) (*ateapipb.SuspendActorResponse, error) { +func (f *fakeControlClient) SuspendActor(ctx context.Context, in *ateapi.SuspendActorRequest, opts ...grpc.CallOption) (*ateapi.SuspendActorResponse, error) { f.record(ctx, "SuspendActor") f.mu.Lock() defer f.mu.Unlock() @@ -725,10 +725,10 @@ func (f *fakeControlClient) SuspendActor(ctx context.Context, in *ateapipb.Suspe if err := nextErr(&f.suspendErrs); err != nil { return nil, err } - return &ateapipb.SuspendActorResponse{}, nil + return &ateapi.SuspendActorResponse{}, nil } -func (f *fakeControlClient) DeleteActor(ctx context.Context, in *ateapipb.DeleteActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { +func (f *fakeControlClient) DeleteActor(ctx context.Context, in *ateapi.DeleteActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { f.record(ctx, "DeleteActor") n := f.inFlight.Add(1) defer f.inFlight.Add(-1) @@ -741,13 +741,13 @@ func (f *fakeControlClient) DeleteActor(ctx context.Context, in *ateapipb.Delete if f.deleteDelay > 0 { time.Sleep(f.deleteDelay) } - return &ateapipb.Actor{}, nil + return &ateapi.Actor{}, nil } -func (f *fakeControlClient) recordedSuspendReqs() []*ateapipb.SuspendActorRequest { +func (f *fakeControlClient) recordedSuspendReqs() []*ateapi.SuspendActorRequest { f.mu.Lock() defer f.mu.Unlock() - return append([]*ateapipb.SuspendActorRequest(nil), f.suspendReqs...) + return append([]*ateapi.SuspendActorRequest(nil), f.suspendReqs...) } func (f *fakeControlClient) recordedCalls() []string { @@ -822,34 +822,34 @@ func TestRunStep_RetriesStrandedHibernate(t *testing.T) { // A step ends with an async SuspendActor in async LifecycleMode and a sync // one in sync LifecycleMode. func TestRunStep_HibernateMode(t *testing.T) { - ref := &ateapipb.ObjectRef{Atespace: "benchmark", Name: "agent-test"} + ref := &ateapi.ObjectRef{Atespace: "benchmark", Name: "agent-test"} for _, tt := range []struct { name string lifecycleMode string - want *ateapipb.SuspendActorRequest + want *ateapi.SuspendActorRequest }{ { name: "default", lifecycleMode: "", - want: &ateapipb.SuspendActorRequest{ + want: &ateapi.SuspendActorRequest{ Actor: ref, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }, }, { name: "async", lifecycleMode: dynconfig.LifecycleModeAsync, - want: &ateapipb.SuspendActorRequest{ + want: &ateapi.SuspendActorRequest{ Actor: ref, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }, }, { name: "sync", lifecycleMode: dynconfig.LifecycleModeSync, - want: &ateapipb.SuspendActorRequest{ + want: &ateapi.SuspendActorRequest{ Actor: ref, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }, }, } { @@ -1376,9 +1376,9 @@ func TestSnapshotSteps(t *testing.T) { t.Fatalf("step %d failed", i+1) } } - wantSuspend := &ateapipb.SuspendActorRequest{ + wantSuspend := &ateapi.SuspendActorRequest{ Actor: session.ref(), - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, } gotSuspends := ctl.recordedSuspendReqs() if len(gotSuspends) != 2 { diff --git a/internal/benchmarking/boomer/ateenv/lifecycle.go b/internal/benchmarking/boomer/ateenv/lifecycle.go index 873b039e61..3073a51058 100644 --- a/internal/benchmarking/boomer/ateenv/lifecycle.go +++ b/internal/benchmarking/boomer/ateenv/lifecycle.go @@ -32,6 +32,7 @@ import ( "time" "github.com/google/uuid" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateinterceptors" "go.ate.dev/substrate/internal/atenet" "go.ate.dev/substrate/internal/benchmarking/boomer/boomerutil" @@ -39,7 +40,6 @@ import ( bmetrics "go.ate.dev/substrate/internal/benchmarking/boomer/metrics" "go.ate.dev/substrate/internal/benchmarking/boomer/userclass" ateenvv1alpha "go.ate.dev/substrate/internal/proto/ateenv/v1alpha" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "google.golang.org/grpc" @@ -581,15 +581,15 @@ func (u *ateEnvActor) noteSuccess() { u.mu.Unlock() } -func (u *ateEnvActor) ref() *ateapipb.ObjectRef { - return &ateapipb.ObjectRef{Atespace: u.cfg.Atespace, Name: u.actorName} +func (u *ateEnvActor) ref() *ateapi.ObjectRef { + return &ateapi.ObjectRef{Atespace: u.cfg.Atespace, Name: u.actorName} } func (u *ateEnvActor) ensureAtespace(ctx context.Context) error { return u.tracedCall(ctx, "CreateAtespace", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.CreateAtespace(callCtx, &ateapipb.CreateAtespaceRequest{ - Atespace: &ateapipb.Atespace{ - Metadata: &ateapipb.ResourceMetadata{ + _, err := u.cfg.APIStub.CreateAtespace(callCtx, &ateapi.CreateAtespaceRequest{ + Atespace: &ateapi.Atespace{ + Metadata: &ateapi.ResourceMetadata{ Name: u.cfg.Atespace, }, }, @@ -606,10 +606,10 @@ func (u *ateEnvActor) ensureAtespace(ctx context.Context) error { func (u *ateEnvActor) create(ctx context.Context) error { return u.tracedCall(ctx, "CreateActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.CreateActor(callCtx, &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: u.cfg.Atespace, Name: u.actorName}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: templateAtespace, Name: templateName}, + _, err := u.cfg.APIStub.CreateActor(callCtx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: u.cfg.Atespace, Name: u.actorName}, + ActorTemplate: &ateapi.ObjectRef{Atespace: templateAtespace, Name: templateName}, }, }, grpc.Trailer(tr)) return err @@ -626,7 +626,7 @@ func (u *ateEnvActor) resume(ctx context.Context) error { } err := u.tracedCall(ctx, metricName, func(callCtx context.Context, tr *metadata.MD) error { return boomerutil.RetryOnConflict(callCtx, func() error { - _, err := u.cfg.APIStub.ResumeActor(callCtx, &ateapipb.ResumeActorRequest{ + _, err := u.cfg.APIStub.ResumeActor(callCtx, &ateapi.ResumeActorRequest{ Actor: u.ref(), }, grpc.Trailer(tr)) return err @@ -664,9 +664,9 @@ func (u *ateEnvActor) hibernate(ctx context.Context) error { func (u *ateEnvActor) pause(ctx context.Context) error { err := u.tracedCall(ctx, "SuspendActorAsync", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapipb.SuspendActorRequest{ + _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapi.SuspendActorRequest{ Actor: u.ref(), - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }, grpc.Trailer(tr)) return err }) @@ -679,9 +679,9 @@ func (u *ateEnvActor) pause(ctx context.Context) error { func (u *ateEnvActor) suspend(ctx context.Context) error { err := u.tracedCall(ctx, "SuspendActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapipb.SuspendActorRequest{ + _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapi.SuspendActorRequest{ Actor: u.ref(), - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }, grpc.Trailer(tr)) return err }) @@ -694,7 +694,7 @@ func (u *ateEnvActor) suspend(ctx context.Context) error { func (u *ateEnvActor) delete(ctx context.Context) { _ = u.tracedCall(ctx, "DeleteActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.DeleteActor(callCtx, &ateapipb.DeleteActorRequest{ + _, err := u.cfg.APIStub.DeleteActor(callCtx, &ateapi.DeleteActorRequest{ Actor: u.ref(), }, grpc.Trailer(tr)) return err diff --git a/internal/benchmarking/boomer/ateenv/lifecycle_test.go b/internal/benchmarking/boomer/ateenv/lifecycle_test.go index a3923c3c61..f544c42c61 100644 --- a/internal/benchmarking/boomer/ateenv/lifecycle_test.go +++ b/internal/benchmarking/boomer/ateenv/lifecycle_test.go @@ -24,12 +24,12 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/atenet" "go.ate.dev/substrate/internal/benchmarking/boomer/boomerutil" "go.ate.dev/substrate/internal/benchmarking/boomer/dynconfig" "go.ate.dev/substrate/internal/benchmarking/boomer/userclass" ateenvv1alpha "go.ate.dev/substrate/internal/proto/ateenv/v1alpha" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/propagation" sdktrace "go.opentelemetry.io/otel/sdk/trace" @@ -41,12 +41,12 @@ import ( "google.golang.org/grpc/test/bufconn" ) -// fakeControlClient implements ateapipb.ControlClient for testing. +// fakeControlClient implements ateapi.ControlClient for testing. type fakeControlClient struct { - ateapipb.ControlClient + ateapi.ControlClient mu sync.Mutex calls []string - suspendReqs []*ateapipb.SuspendActorRequest + suspendReqs []*ateapi.SuspendActorRequest resumeErrs []error suspendErrs []error } @@ -60,27 +60,27 @@ func nextErr(errs *[]error) error { return err } -func (f *fakeControlClient) CreateAtespace(ctx context.Context, in *ateapipb.CreateAtespaceRequest, opts ...grpc.CallOption) (*ateapipb.Atespace, error) { +func (f *fakeControlClient) CreateAtespace(ctx context.Context, in *ateapi.CreateAtespaceRequest, opts ...grpc.CallOption) (*ateapi.Atespace, error) { if err := ctx.Err(); err != nil { return nil, err } f.mu.Lock() defer f.mu.Unlock() f.calls = append(f.calls, "CreateAtespace") - return &ateapipb.Atespace{}, nil + return &ateapi.Atespace{}, nil } -func (f *fakeControlClient) CreateActor(ctx context.Context, in *ateapipb.CreateActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { +func (f *fakeControlClient) CreateActor(ctx context.Context, in *ateapi.CreateActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { if err := ctx.Err(); err != nil { return nil, err } f.mu.Lock() defer f.mu.Unlock() f.calls = append(f.calls, "CreateActor") - return &ateapipb.Actor{}, nil + return &ateapi.Actor{}, nil } -func (f *fakeControlClient) ResumeActor(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { +func (f *fakeControlClient) ResumeActor(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { if err := ctx.Err(); err != nil { return nil, err } @@ -90,10 +90,10 @@ func (f *fakeControlClient) ResumeActor(ctx context.Context, in *ateapipb.Resume if err := nextErr(&f.resumeErrs); err != nil { return nil, err } - return &ateapipb.ResumeActorResponse{}, nil + return &ateapi.ResumeActorResponse{}, nil } -func (f *fakeControlClient) SuspendActor(ctx context.Context, in *ateapipb.SuspendActorRequest, opts ...grpc.CallOption) (*ateapipb.SuspendActorResponse, error) { +func (f *fakeControlClient) SuspendActor(ctx context.Context, in *ateapi.SuspendActorRequest, opts ...grpc.CallOption) (*ateapi.SuspendActorResponse, error) { if err := ctx.Err(); err != nil { return nil, err } @@ -104,26 +104,26 @@ func (f *fakeControlClient) SuspendActor(ctx context.Context, in *ateapipb.Suspe if err := nextErr(&f.suspendErrs); err != nil { return nil, err } - return &ateapipb.SuspendActorResponse{}, nil + return &ateapi.SuspendActorResponse{}, nil } // suspendCallName is the name a SuspendActor call is recorded under: an // async suspend is told apart from a sync one. -func suspendCallName(in *ateapipb.SuspendActorRequest) string { - if in.GetOptions().GetMode() == ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS { +func suspendCallName(in *ateapi.SuspendActorRequest) string { + if in.GetOptions().GetMode() == ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS { return "SuspendActor(async)" } return "SuspendActor" } -func (f *fakeControlClient) DeleteActor(ctx context.Context, in *ateapipb.DeleteActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { +func (f *fakeControlClient) DeleteActor(ctx context.Context, in *ateapi.DeleteActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { if err := ctx.Err(); err != nil { return nil, err } f.mu.Lock() defer f.mu.Unlock() f.calls = append(f.calls, "DeleteActor") - return &ateapipb.Actor{}, nil + return &ateapi.Actor{}, nil } func (f *fakeControlClient) recordedCalls() []string { @@ -132,10 +132,10 @@ func (f *fakeControlClient) recordedCalls() []string { return append([]string(nil), f.calls...) } -func (f *fakeControlClient) recordedSuspendRequests() []*ateapipb.SuspendActorRequest { +func (f *fakeControlClient) recordedSuspendRequests() []*ateapi.SuspendActorRequest { f.mu.Lock() defer f.mu.Unlock() - return append([]*ateapipb.SuspendActorRequest(nil), f.suspendReqs...) + return append([]*ateapi.SuspendActorRequest(nil), f.suspendReqs...) } // fakeProcessServer implements ateenvv1alpha.ProcessServiceServer for testing. @@ -396,8 +396,8 @@ func TestAteEnvIterate_SuspendMode(t *testing.T) { t.Errorf("did not expect SuspendActor(async) in suspend mode calls, got: %v", calls) } for _, req := range ctrl.recordedSuspendRequests() { - if got := req.GetOptions().GetMode(); got != ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS { - t.Errorf("suspend mode = %v, want %v", got, ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS) + if got := req.GetOptions().GetMode(); got != ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS { + t.Errorf("suspend mode = %v, want %v", got, ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS) } } diff --git a/internal/benchmarking/boomer/boomerutil/client.go b/internal/benchmarking/boomer/boomerutil/client.go index a27e607b6f..70e61a777c 100644 --- a/internal/benchmarking/boomer/boomerutil/client.go +++ b/internal/benchmarking/boomer/boomerutil/client.go @@ -17,9 +17,9 @@ package boomerutil import ( "fmt" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateapiauth" _ "go.ate.dev/substrate/internal/k8sresolver" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "google.golang.org/grpc" "k8s.io/client-go/kubernetes" @@ -45,7 +45,7 @@ const ( // certificate — the same client auth the base install gives ate-controller // and atenet-router. ClientCredBundle re-reads the bundle on every handshake, // so rotations are picked up without a restart. -func DialControl(endpoint string) (*grpc.ClientConn, ateapipb.ControlClient, error) { +func DialControl(endpoint string) (*grpc.ClientConn, ateapi.ControlClient, error) { k8sConfig, err := rest.InClusterConfig() if err != nil { loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() @@ -75,5 +75,5 @@ func DialControl(endpoint string) (*grpc.ClientConn, ateapipb.ControlClient, err if err != nil { return nil, nil, fmt.Errorf("dial %s: %w", endpoint, err) } - return conn, ateapipb.NewControlClient(conn), nil + return conn, ateapi.NewControlClient(conn), nil } diff --git a/internal/benchmarking/boomer/glutton/durdir.go b/internal/benchmarking/boomer/glutton/durdir.go index dd67511518..8b2613f795 100644 --- a/internal/benchmarking/boomer/glutton/durdir.go +++ b/internal/benchmarking/boomer/glutton/durdir.go @@ -28,6 +28,7 @@ import ( "time" "github.com/google/uuid" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateinterceptors" "go.ate.dev/substrate/internal/atenet" "go.ate.dev/substrate/internal/benchmarking/boomer/boomerutil" @@ -35,7 +36,6 @@ import ( bmetrics "go.ate.dev/substrate/internal/benchmarking/boomer/metrics" "go.ate.dev/substrate/internal/benchmarking/boomer/userclass" gluttonpb "go.ate.dev/substrate/internal/proto/glutton" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/propagation" @@ -159,15 +159,15 @@ type durDirUser struct { expectedSize int64 } -func (u *durDirUser) ref() *ateapipb.ObjectRef { - return &ateapipb.ObjectRef{Atespace: u.cfg.Atespace, Name: u.actorName} +func (u *durDirUser) ref() *ateapi.ObjectRef { + return &ateapi.ObjectRef{Atespace: u.cfg.Atespace, Name: u.actorName} } func (u *durDirUser) ensureAtespace(ctx context.Context) error { return u.tracedCall(ctx, "CreateAtespace", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.CreateAtespace(callCtx, &ateapipb.CreateAtespaceRequest{ - Atespace: &ateapipb.Atespace{ - Metadata: &ateapipb.ResourceMetadata{ + _, err := u.cfg.APIStub.CreateAtespace(callCtx, &ateapi.CreateAtespaceRequest{ + Atespace: &ateapi.Atespace{ + Metadata: &ateapi.ResourceMetadata{ Name: u.cfg.Atespace, }, }, @@ -184,10 +184,10 @@ func (u *durDirUser) ensureAtespace(ctx context.Context) error { func (u *durDirUser) create(ctx context.Context) error { return u.tracedCall(ctx, "CreateActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.CreateActor(callCtx, &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: u.cfg.Atespace, Name: u.actorName}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: templateAtespace, Name: u.templateName}, + _, err := u.cfg.APIStub.CreateActor(callCtx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: u.cfg.Atespace, Name: u.actorName}, + ActorTemplate: &ateapi.ObjectRef{Atespace: templateAtespace, Name: u.templateName}, }, }, grpc.Trailer(tr)) return err @@ -200,7 +200,7 @@ func (u *durDirUser) resume(ctx context.Context, mode string) bool { return true } err := u.tracedCall(ctx, "ResumeActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.ResumeActor(callCtx, &ateapipb.ResumeActorRequest{ + _, err := u.cfg.APIStub.ResumeActor(callCtx, &ateapi.ResumeActorRequest{ Actor: u.ref(), }, grpc.Trailer(tr)) return err @@ -210,9 +210,9 @@ func (u *durDirUser) resume(ctx context.Context, mode string) bool { func (u *durDirUser) pause(ctx context.Context) { _ = u.tracedCall(ctx, "SuspendActorAsync", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapipb.SuspendActorRequest{ + _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapi.SuspendActorRequest{ Actor: u.ref(), - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }, grpc.Trailer(tr)) return err }) @@ -220,9 +220,9 @@ func (u *durDirUser) pause(ctx context.Context) { func (u *durDirUser) suspend(ctx context.Context) { _ = u.tracedCall(ctx, "SuspendActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapipb.SuspendActorRequest{ + _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapi.SuspendActorRequest{ Actor: u.ref(), - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }, grpc.Trailer(tr)) return err }) @@ -241,14 +241,14 @@ func (u *durDirUser) hibernate(ctx context.Context, dynCfg durDirKnobs) { // while the delete is metered so true leaks still surface in failures.csv. func (u *durDirUser) hibernateAndDelete(ctx context.Context, dynCfg durDirKnobs) { if dynCfg.LifecycleMode == dynconfig.LifecycleModeSync { - _, _ = u.cfg.APIStub.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ + _, _ = u.cfg.APIStub.SuspendActor(ctx, &ateapi.SuspendActorRequest{ Actor: u.ref(), - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }) } else { - _, _ = u.cfg.APIStub.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ + _, _ = u.cfg.APIStub.SuspendActor(ctx, &ateapi.SuspendActorRequest{ Actor: u.ref(), - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }) } u.delete(ctx) @@ -256,7 +256,7 @@ func (u *durDirUser) hibernateAndDelete(ctx context.Context, dynCfg durDirKnobs) func (u *durDirUser) delete(ctx context.Context) { _ = u.tracedCall(ctx, "DeleteActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.DeleteActor(callCtx, &ateapipb.DeleteActorRequest{ + _, err := u.cfg.APIStub.DeleteActor(callCtx, &ateapi.DeleteActorRequest{ Actor: u.ref(), }, grpc.Trailer(tr)) return err diff --git a/internal/benchmarking/boomer/glutton/durdir_test.go b/internal/benchmarking/boomer/glutton/durdir_test.go index 6b8159b256..3de1760c3d 100644 --- a/internal/benchmarking/boomer/glutton/durdir_test.go +++ b/internal/benchmarking/boomer/glutton/durdir_test.go @@ -24,12 +24,12 @@ import ( "slices" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/benchmarking/boomer/boomerutil" "go.ate.dev/substrate/internal/benchmarking/boomer/dynconfig" "go.ate.dev/substrate/internal/benchmarking/boomer/userclass" "go.ate.dev/substrate/internal/benchmarking/glutton/fake" gluttonpb "go.ate.dev/substrate/internal/proto/glutton" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) func TestDurDirLoopSequence(t *testing.T) { @@ -39,21 +39,21 @@ func TestDurDirLoopSequence(t *testing.T) { lifecycleMode string wantGRPCCall []string wantHTTPCall []string - wantMode ateapipb.DurabilityMode + wantMode ateapi.DurabilityMode }{ { name: "explicit resume mode", resumeMode: dynconfig.ResumeModeExplicit, wantGRPCCall: []string{"SuspendActor(async)", "ResumeActor"}, wantHTTPCall: []string{fake.ReadDiskRoute, fake.ReadDiskRoute, fake.WriteDiskRoute}, - wantMode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, + wantMode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, }, { name: "implicit resume mode", resumeMode: dynconfig.ResumeModeImplicit, wantGRPCCall: []string{"SuspendActor(async)"}, // No ResumeActor RPC! wantHTTPCall: []string{fake.ReadDiskRoute, fake.ReadDiskRoute, fake.WriteDiskRoute}, - wantMode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, + wantMode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, }, { name: "sync lifecycle mode", @@ -61,7 +61,7 @@ func TestDurDirLoopSequence(t *testing.T) { resumeMode: dynconfig.ResumeModeExplicit, wantGRPCCall: []string{"SuspendActor", "ResumeActor"}, wantHTTPCall: []string{fake.ReadDiskRoute, fake.ReadDiskRoute, fake.WriteDiskRoute}, - wantMode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS, + wantMode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS, }, { name: "async lifecycle mode", @@ -69,7 +69,7 @@ func TestDurDirLoopSequence(t *testing.T) { resumeMode: dynconfig.ResumeModeExplicit, wantGRPCCall: []string{"SuspendActor(async)", "ResumeActor"}, wantHTTPCall: []string{fake.ReadDiskRoute, fake.ReadDiskRoute, fake.WriteDiskRoute}, - wantMode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, + wantMode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, }, } @@ -257,7 +257,7 @@ func TestDurDirBootstrapFailureSuspendsBeforeDelete(t *testing.T) { if len(suspends) == 0 { t.Fatalf("got no SuspendActor requests") } - if got, want := suspends[len(suspends)-1].GetOptions().GetMode(), ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS; got != want { + if got, want := suspends[len(suspends)-1].GetOptions().GetMode(), ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS; got != want { t.Errorf("suspend mode = %v, want %v", got, want) } } @@ -267,24 +267,24 @@ func TestDurDirShutdownHibernatesBeforeDelete(t *testing.T) { name string lifecycleMode string wantCalls []string - wantMode ateapipb.DurabilityMode + wantMode ateapi.DurabilityMode }{ { name: "default lifecycle mode", wantCalls: []string{"SuspendActor(async)", "DeleteActor"}, - wantMode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, + wantMode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, }, { name: "sync lifecycle mode", lifecycleMode: dynconfig.LifecycleModeSync, wantCalls: []string{"SuspendActor", "DeleteActor"}, - wantMode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS, + wantMode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS, }, { name: "async lifecycle mode", lifecycleMode: dynconfig.LifecycleModeAsync, wantCalls: []string{"SuspendActor(async)", "DeleteActor"}, - wantMode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, + wantMode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, }, } for _, tc := range tests { diff --git a/internal/benchmarking/boomer/glutton/fixture_test.go b/internal/benchmarking/boomer/glutton/fixture_test.go index 1d08dc1af8..f922eddab0 100644 --- a/internal/benchmarking/boomer/glutton/fixture_test.go +++ b/internal/benchmarking/boomer/glutton/fixture_test.go @@ -19,20 +19,20 @@ import ( "sync" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/benchmarking/boomer/dynconfig" "go.ate.dev/substrate/internal/benchmarking/boomer/userclass" "go.ate.dev/substrate/internal/benchmarking/glutton/fake" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel" "google.golang.org/grpc" ) type fakeControlClient struct { - ateapipb.ControlClient + ateapi.ControlClient mu sync.Mutex calls []string - deleteRequests []*ateapipb.DeleteActorRequest - suspendReqs []*ateapipb.SuspendActorRequest + deleteRequests []*ateapi.DeleteActorRequest + suspendReqs []*ateapi.SuspendActorRequest // resumeErrs is returned by successive ResumeActor calls, in order, until // it is drained; every call after that succeeds. resumeErrs []error @@ -55,14 +55,14 @@ func nextErr(errs *[]error) error { return err } -func (f *fakeControlClient) CreateAtespace(ctx context.Context, in *ateapipb.CreateAtespaceRequest, opts ...grpc.CallOption) (*ateapipb.Atespace, error) { +func (f *fakeControlClient) CreateAtespace(ctx context.Context, in *ateapi.CreateAtespaceRequest, opts ...grpc.CallOption) (*ateapi.Atespace, error) { f.mu.Lock() defer f.mu.Unlock() f.calls = append(f.calls, "CreateAtespace") - return &ateapipb.Atespace{}, nil + return &ateapi.Atespace{}, nil } -func (f *fakeControlClient) CreateActor(ctx context.Context, in *ateapipb.CreateActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { +func (f *fakeControlClient) CreateActor(ctx context.Context, in *ateapi.CreateActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { f.mu.Lock() f.calls = append(f.calls, "CreateActor") fn := f.createActorFn @@ -76,20 +76,20 @@ func (f *fakeControlClient) CreateActor(ctx context.Context, in *ateapipb.Create return nil, err } } - return &ateapipb.Actor{}, nil + return &ateapi.Actor{}, nil } -func (f *fakeControlClient) ResumeActor(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { +func (f *fakeControlClient) ResumeActor(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { f.mu.Lock() defer f.mu.Unlock() f.calls = append(f.calls, "ResumeActor") if err := nextErr(&f.resumeErrs); err != nil { return nil, err } - return &ateapipb.ResumeActorResponse{}, nil + return &ateapi.ResumeActorResponse{}, nil } -func (f *fakeControlClient) SuspendActor(ctx context.Context, in *ateapipb.SuspendActorRequest, opts ...grpc.CallOption) (*ateapipb.SuspendActorResponse, error) { +func (f *fakeControlClient) SuspendActor(ctx context.Context, in *ateapi.SuspendActorRequest, opts ...grpc.CallOption) (*ateapi.SuspendActorResponse, error) { f.mu.Lock() defer f.mu.Unlock() f.calls = append(f.calls, suspendCallName(in)) @@ -97,24 +97,24 @@ func (f *fakeControlClient) SuspendActor(ctx context.Context, in *ateapipb.Suspe if err := nextErr(&f.suspendErrs); err != nil { return nil, err } - return &ateapipb.SuspendActorResponse{}, nil + return &ateapi.SuspendActorResponse{}, nil } // suspendCallName is the name a SuspendActor call is recorded under: an // async suspend is told apart from a sync one. -func suspendCallName(in *ateapipb.SuspendActorRequest) string { - if in.GetOptions().GetMode() == ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS { +func suspendCallName(in *ateapi.SuspendActorRequest) string { + if in.GetOptions().GetMode() == ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS { return "SuspendActor(async)" } return "SuspendActor" } -func (f *fakeControlClient) DeleteActor(ctx context.Context, in *ateapipb.DeleteActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { +func (f *fakeControlClient) DeleteActor(ctx context.Context, in *ateapi.DeleteActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { f.mu.Lock() defer f.mu.Unlock() f.calls = append(f.calls, "DeleteActor") f.deleteRequests = append(f.deleteRequests, in) - return &ateapipb.Actor{}, nil + return &ateapi.Actor{}, nil } func (f *fakeControlClient) recordedCalls() []string { @@ -123,16 +123,16 @@ func (f *fakeControlClient) recordedCalls() []string { return append([]string(nil), f.calls...) } -func (f *fakeControlClient) recordedSuspendRequests() []*ateapipb.SuspendActorRequest { +func (f *fakeControlClient) recordedSuspendRequests() []*ateapi.SuspendActorRequest { f.mu.Lock() defer f.mu.Unlock() - return append([]*ateapipb.SuspendActorRequest(nil), f.suspendReqs...) + return append([]*ateapi.SuspendActorRequest(nil), f.suspendReqs...) } -func (f *fakeControlClient) recordedDeleteRequests() []*ateapipb.DeleteActorRequest { +func (f *fakeControlClient) recordedDeleteRequests() []*ateapi.DeleteActorRequest { f.mu.Lock() defer f.mu.Unlock() - return append([]*ateapipb.DeleteActorRequest(nil), f.deleteRequests...) + return append([]*ateapi.DeleteActorRequest(nil), f.deleteRequests...) } // newTestConfig starts srv, sets HTTPClient and RouterURL, and ensures diff --git a/internal/benchmarking/boomer/glutton/lifecycle.go b/internal/benchmarking/boomer/glutton/lifecycle.go index 812272601a..f1c973c241 100644 --- a/internal/benchmarking/boomer/glutton/lifecycle.go +++ b/internal/benchmarking/boomer/glutton/lifecycle.go @@ -30,6 +30,7 @@ import ( "time" "github.com/google/uuid" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateinterceptors" "go.ate.dev/substrate/internal/atenet" "go.ate.dev/substrate/internal/benchmarking/boomer/boomerutil" @@ -37,7 +38,6 @@ import ( bmetrics "go.ate.dev/substrate/internal/benchmarking/boomer/metrics" "go.ate.dev/substrate/internal/benchmarking/boomer/userclass" gluttonpb "go.ate.dev/substrate/internal/proto/glutton" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/propagation" @@ -377,8 +377,8 @@ func (u *gluttonActor) noteSuccess() { u.consecutiveFailures = 0 } -func (u *gluttonActor) ref() *ateapipb.ObjectRef { - return &ateapipb.ObjectRef{Atespace: u.cfg.Atespace, Name: u.actorName} +func (u *gluttonActor) ref() *ateapi.ObjectRef { + return &ateapi.ObjectRef{Atespace: u.cfg.Atespace, Name: u.actorName} } // ensureAtespace creates the configured atespace, swallowing AlreadyExists @@ -387,9 +387,9 @@ func (u *gluttonActor) ref() *ateapipb.ObjectRef { // other API call. func (u *gluttonActor) ensureAtespace(ctx context.Context) error { return u.tracedCall(ctx, "CreateAtespace", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.CreateAtespace(callCtx, &ateapipb.CreateAtespaceRequest{ - Atespace: &ateapipb.Atespace{ - Metadata: &ateapipb.ResourceMetadata{ + _, err := u.cfg.APIStub.CreateAtespace(callCtx, &ateapi.CreateAtespaceRequest{ + Atespace: &ateapi.Atespace{ + Metadata: &ateapi.ResourceMetadata{ Name: u.cfg.Atespace, }, }, @@ -406,10 +406,10 @@ func (u *gluttonActor) ensureAtespace(ctx context.Context) error { func (u *gluttonActor) create(ctx context.Context) error { return u.tracedCall(ctx, "CreateActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.CreateActor(callCtx, &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: u.cfg.Atespace, Name: u.actorName}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: templateAtespace, Name: templateName}, + _, err := u.cfg.APIStub.CreateActor(callCtx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: u.cfg.Atespace, Name: u.actorName}, + ActorTemplate: &ateapi.ObjectRef{Atespace: templateAtespace, Name: templateName}, }, }, grpc.Trailer(tr)) return err @@ -428,7 +428,7 @@ func (u *gluttonActor) resume(ctx context.Context) error { // reported latency spans every attempt and the span carries the // last attempt's server trailer, same as any other single-shot RPC. return boomerutil.RetryOnConflict(callCtx, func() error { - _, err := u.cfg.APIStub.ResumeActor(callCtx, &ateapipb.ResumeActorRequest{ + _, err := u.cfg.APIStub.ResumeActor(callCtx, &ateapi.ResumeActorRequest{ Actor: u.ref(), }, grpc.Trailer(tr)) return err @@ -470,9 +470,9 @@ func (u *gluttonActor) hibernate(ctx context.Context) error { func (u *gluttonActor) pause(ctx context.Context) error { err := u.tracedCall(ctx, "SuspendActorAsync", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapipb.SuspendActorRequest{ + _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapi.SuspendActorRequest{ Actor: u.ref(), - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }, grpc.Trailer(tr)) return err }) @@ -486,9 +486,9 @@ func (u *gluttonActor) pause(ctx context.Context) error { func (u *gluttonActor) suspend(ctx context.Context) error { err := u.tracedCall(ctx, "SuspendActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapipb.SuspendActorRequest{ + _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapi.SuspendActorRequest{ Actor: u.ref(), - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }, grpc.Trailer(tr)) return err }) @@ -502,7 +502,7 @@ func (u *gluttonActor) suspend(ctx context.Context) error { func (u *gluttonActor) delete(ctx context.Context) { _ = u.tracedCall(ctx, "DeleteActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.DeleteActor(callCtx, &ateapipb.DeleteActorRequest{ + _, err := u.cfg.APIStub.DeleteActor(callCtx, &ateapi.DeleteActorRequest{ Actor: u.ref(), }, grpc.Trailer(tr)) return err diff --git a/internal/benchmarking/boomer/glutton/lifecycle_test.go b/internal/benchmarking/boomer/glutton/lifecycle_test.go index 63df97697c..1842b2a5b9 100644 --- a/internal/benchmarking/boomer/glutton/lifecycle_test.go +++ b/internal/benchmarking/boomer/glutton/lifecycle_test.go @@ -19,11 +19,11 @@ import ( "slices" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/benchmarking/boomer/boomerutil" "go.ate.dev/substrate/internal/benchmarking/boomer/dynconfig" "go.ate.dev/substrate/internal/benchmarking/boomer/userclass" "go.ate.dev/substrate/internal/benchmarking/glutton/fake" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -50,8 +50,8 @@ func TestGluttonIterate_SuspendMode(t *testing.T) { t.Errorf("did not expect SuspendActor(async) in suspend mode calls, got: %v", calls) } for _, req := range fakeCtrl.recordedSuspendRequests() { - if got := req.GetOptions().GetMode(); got != ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS { - t.Errorf("suspend mode = %v, want %v", got, ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS) + if got := req.GetOptions().GetMode(); got != ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS { + t.Errorf("suspend mode = %v, want %v", got, ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS) } } } diff --git a/internal/benchmarking/boomer/glutton/spawn.go b/internal/benchmarking/boomer/glutton/spawn.go index 4ae40c6aee..6df7d1f6c3 100644 --- a/internal/benchmarking/boomer/glutton/spawn.go +++ b/internal/benchmarking/boomer/glutton/spawn.go @@ -28,6 +28,7 @@ import ( "time" "github.com/google/uuid" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateinterceptors" "go.ate.dev/substrate/internal/atenet" "go.ate.dev/substrate/internal/benchmarking/boomer/boomerutil" @@ -35,7 +36,6 @@ import ( bmetrics "go.ate.dev/substrate/internal/benchmarking/boomer/metrics" "go.ate.dev/substrate/internal/benchmarking/boomer/userclass" gluttonpb "go.ate.dev/substrate/internal/proto/glutton" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/propagation" @@ -262,10 +262,10 @@ func (r *spawnRuntime) createActorWithRetry(ctx context.Context, actorName strin } err := r.tracedCall(ctx, "CreateActor", func(callCtx context.Context, tr *metadata.MD) error { - _, callErr := r.cfg.APIStub.CreateActor(callCtx, &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: r.cfg.Atespace, Name: actorName}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: templateAtespace, Name: templateName}, + _, callErr := r.cfg.APIStub.CreateActor(callCtx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: r.cfg.Atespace, Name: actorName}, + ActorTemplate: &ateapi.ObjectRef{Atespace: templateAtespace, Name: templateName}, }, }, grpc.Trailer(tr)) return callErr @@ -299,7 +299,7 @@ func (r *spawnRuntime) createActorWithRetry(ctx context.Context, actorName strin } func (r *spawnRuntime) resumeActorWithRetry(ctx context.Context, actorName string) error { - actorRef := &ateapipb.ObjectRef{Atespace: r.cfg.Atespace, Name: actorName} + actorRef := &ateapi.ObjectRef{Atespace: r.cfg.Atespace, Name: actorName} delay := spawnInitialRetryBackoff for { @@ -309,7 +309,7 @@ func (r *spawnRuntime) resumeActorWithRetry(ctx context.Context, actorName strin err := r.tracedCall(ctx, "ResumeActor", func(callCtx context.Context, tr *metadata.MD) error { return boomerutil.RetryOnConflict(callCtx, func() error { - _, err := r.cfg.APIStub.ResumeActor(callCtx, &ateapipb.ResumeActorRequest{ + _, err := r.cfg.APIStub.ResumeActor(callCtx, &ateapi.ResumeActorRequest{ Actor: actorRef, }, grpc.Trailer(tr)) return err @@ -413,9 +413,9 @@ func (r *spawnRuntime) doOnePing(ctx context.Context, actorName string, body []b func (r *spawnRuntime) ensureAtespace(ctx context.Context) error { return r.tracedCall(ctx, "CreateAtespace", func(callCtx context.Context, tr *metadata.MD) error { - _, err := r.cfg.APIStub.CreateAtespace(callCtx, &ateapipb.CreateAtespaceRequest{ - Atespace: &ateapipb.Atespace{ - Metadata: &ateapipb.ResourceMetadata{ + _, err := r.cfg.APIStub.CreateAtespace(callCtx, &ateapi.CreateAtespaceRequest{ + Atespace: &ateapi.Atespace{ + Metadata: &ateapi.ResourceMetadata{ Name: r.cfg.Atespace, }, }, @@ -478,8 +478,8 @@ func (r *spawnRuntime) deleteAll(ctx context.Context) { func (r *spawnRuntime) deleteActor(ctx context.Context, name string) error { return r.tracedCall(ctx, "DeleteActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := r.cfg.APIStub.DeleteActor(callCtx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{ + _, err := r.cfg.APIStub.DeleteActor(callCtx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{ Atespace: r.cfg.Atespace, Name: name, }, diff --git a/internal/benchmarking/boomer/resumepaused/resumepaused.go b/internal/benchmarking/boomer/resumepaused/resumepaused.go index c317bcd89d..9494d0c6ff 100644 --- a/internal/benchmarking/boomer/resumepaused/resumepaused.go +++ b/internal/benchmarking/boomer/resumepaused/resumepaused.go @@ -36,12 +36,12 @@ import ( "time" "github.com/google/uuid" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateinterceptors" "go.ate.dev/substrate/internal/benchmarking/boomer/boomerutil" "go.ate.dev/substrate/internal/benchmarking/boomer/dynconfig" bmetrics "go.ate.dev/substrate/internal/benchmarking/boomer/metrics" "go.ate.dev/substrate/internal/benchmarking/boomer/userclass" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel" "golang.org/x/time/rate" "google.golang.org/grpc" @@ -220,10 +220,10 @@ const ( // create creates one actor from the template. func (r *runtime) create(ctx context.Context, name string) error { return r.call(ctx, "CreateActor", func(ctx context.Context, trailer grpc.CallOption) error { - _, err := r.cfg.APIStub.CreateActor(ctx, &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: r.cfg.Atespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: templateAtespace, Name: templateName}, + _, err := r.cfg.APIStub.CreateActor(ctx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: r.cfg.Atespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: templateAtespace, Name: templateName}, }, }, trailer) return err @@ -266,9 +266,9 @@ func (r *runtime) cycle(name string) { // actor is cold, which is all recovery wants, so that counts as a success. func (r *runtime) recover(ctx context.Context, name string) { _ = r.call(ctx, "SuspendActorAsyncRecovery", func(ctx context.Context, trailer grpc.CallOption) error { - _, err := r.cfg.APIStub.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ + _, err := r.cfg.APIStub.SuspendActor(ctx, &ateapi.SuspendActorRequest{ Actor: r.ref(name), - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }, trailer) if status.Code(err) == codes.FailedPrecondition { return nil @@ -310,7 +310,7 @@ var errAlreadyRunning = errors.New("actor was already running: not a cold resume // the sample with errAlreadyRunning. func (r *runtime) resume(ctx context.Context, metricName, name string) error { return r.call(ctx, metricName, func(ctx context.Context, trailer grpc.CallOption) error { - resp, err := r.cfg.APIStub.ResumeActor(ctx, &ateapipb.ResumeActorRequest{ + resp, err := r.cfg.APIStub.ResumeActor(ctx, &ateapi.ResumeActorRequest{ Actor: r.ref(name), }, trailer) if err == nil && !resp.GetResumed() { @@ -324,9 +324,9 @@ func (r *runtime) resume(ctx context.Context, metricName, name string) error { // suffix keeps warm-up calls apart from the measured ones. func (r *runtime) pause(ctx context.Context, suffix, name string) error { return r.call(ctx, "SuspendActorAsync"+suffix, func(ctx context.Context, trailer grpc.CallOption) error { - _, err := r.cfg.APIStub.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ + _, err := r.cfg.APIStub.SuspendActor(ctx, &ateapi.SuspendActorRequest{ Actor: r.ref(name), - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }, trailer) return err }) @@ -409,7 +409,7 @@ func (r *runtime) delete(ctx context.Context, name string) error { } } err = r.call(ctx, "DeleteActor", func(ctx context.Context, trailer grpc.CallOption) error { - _, err := r.cfg.APIStub.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ + _, err := r.cfg.APIStub.DeleteActor(ctx, &ateapi.DeleteActorRequest{ Actor: r.ref(name), }, trailer) return err @@ -421,15 +421,15 @@ func (r *runtime) delete(ctx context.Context, name string) error { return err } -func (r *runtime) ref(name string) *ateapipb.ObjectRef { - return &ateapipb.ObjectRef{Atespace: r.cfg.Atespace, Name: name} +func (r *runtime) ref(name string) *ateapi.ObjectRef { + return &ateapi.ObjectRef{Atespace: r.cfg.Atespace, Name: name} } func (r *runtime) ensureAtespace(ctx context.Context) error { return r.call(ctx, "CreateAtespace", func(ctx context.Context, trailer grpc.CallOption) error { - _, err := r.cfg.APIStub.CreateAtespace(ctx, &ateapipb.CreateAtespaceRequest{ - Atespace: &ateapipb.Atespace{ - Metadata: &ateapipb.ResourceMetadata{Name: r.cfg.Atespace}, + _, err := r.cfg.APIStub.CreateAtespace(ctx, &ateapi.CreateAtespaceRequest{ + Atespace: &ateapi.Atespace{ + Metadata: &ateapi.ResourceMetadata{Name: r.cfg.Atespace}, }, }, trailer) if status.Code(err) == codes.AlreadyExists { diff --git a/internal/benchmarking/boomer/resumepaused/resumepaused_test.go b/internal/benchmarking/boomer/resumepaused/resumepaused_test.go index 6fd4342719..d82af4435b 100644 --- a/internal/benchmarking/boomer/resumepaused/resumepaused_test.go +++ b/internal/benchmarking/boomer/resumepaused/resumepaused_test.go @@ -28,10 +28,10 @@ import ( "time" "github.com/prometheus/client_golang/prometheus/promhttp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateinterceptors" "go.ate.dev/substrate/internal/benchmarking/boomer/dynconfig" "go.ate.dev/substrate/internal/benchmarking/boomer/userclass" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -42,10 +42,10 @@ import ( // fakeControlClient keeps each actor's state, so a resume of a running actor // reports Resumed false the way ateapi does. type fakeControlClient struct { - ateapipb.ControlClient + ateapi.ControlClient mu sync.Mutex calls []string // " " - states map[string]ateapipb.ActorState + states map[string]ateapi.ActorState // resumeErr, when set, fails every ResumeActor without changing state. resumeErr error // resumeFailures is how many ResumeActor calls fail with Unavailable, @@ -71,7 +71,7 @@ type fakeControlClient struct { } func newFake() *fakeControlClient { - return &fakeControlClient{states: map[string]ateapipb.ActorState{}} + return &fakeControlClient{states: map[string]ateapi.ActorState{}} } // setTrailer fills the trailer a call asked for, as ate-api-server's @@ -91,29 +91,29 @@ func (f *fakeControlClient) record(rpc, actor string) { f.calls = append(f.calls, rpc+" "+actor) } -func (f *fakeControlClient) setState(name string, s ateapipb.ActorState) { +func (f *fakeControlClient) setState(name string, s ateapi.ActorState) { f.mu.Lock() defer f.mu.Unlock() f.states[name] = s } -func (f *fakeControlClient) state(name string) ateapipb.ActorState { +func (f *fakeControlClient) state(name string) ateapi.ActorState { f.mu.Lock() defer f.mu.Unlock() return f.states[name] } -func (f *fakeControlClient) CreateAtespace(ctx context.Context, in *ateapipb.CreateAtespaceRequest, opts ...grpc.CallOption) (*ateapipb.Atespace, error) { +func (f *fakeControlClient) CreateAtespace(ctx context.Context, in *ateapi.CreateAtespaceRequest, opts ...grpc.CallOption) (*ateapi.Atespace, error) { f.mu.Lock() defer f.mu.Unlock() f.record("CreateAtespace", in.GetAtespace().GetMetadata().GetName()) if f.atespaceErr != nil { return nil, f.atespaceErr } - return &ateapipb.Atespace{}, nil + return &ateapi.Atespace{}, nil } -func (f *fakeControlClient) CreateActor(ctx context.Context, in *ateapipb.CreateActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { +func (f *fakeControlClient) CreateActor(ctx context.Context, in *ateapi.CreateActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { f.mu.Lock() defer f.mu.Unlock() name := in.GetActor().GetMetadata().GetName() @@ -121,11 +121,11 @@ func (f *fakeControlClient) CreateActor(ctx context.Context, in *ateapipb.Create if f.createErr != nil { return nil, f.createErr } - f.states[name] = ateapipb.ActorState_ACTOR_STATE_SUSPENDED - return &ateapipb.Actor{}, nil + f.states[name] = ateapi.ActorState_ACTOR_STATE_SUSPENDED + return &ateapi.Actor{}, nil } -func (f *fakeControlClient) GetActor(ctx context.Context, in *ateapipb.GetActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { +func (f *fakeControlClient) GetActor(ctx context.Context, in *ateapi.GetActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { f.mu.Lock() defer f.mu.Unlock() name := in.GetActor().GetName() @@ -134,10 +134,10 @@ func (f *fakeControlClient) GetActor(ctx context.Context, in *ateapipb.GetActorR if !ok { return nil, status.Error(codes.NotFound, "no such actor") } - return &ateapipb.Actor{Status: &ateapipb.ActorStatus{State: s}}, nil + return &ateapi.Actor{Status: &ateapi.ActorStatus{State: s}}, nil } -func (f *fakeControlClient) ResumeActor(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { +func (f *fakeControlClient) ResumeActor(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { if f.resumeGate != nil { f.resumeEntered <- struct{}{} select { @@ -159,38 +159,38 @@ func (f *fakeControlClient) ResumeActor(ctx context.Context, in *ateapipb.Resume return nil, status.Error(codes.Unavailable, "down") } switch f.states[name] { - case ateapipb.ActorState_ACTOR_STATE_RUNNING: - return &ateapipb.ResumeActorResponse{Resumed: false}, nil - case ateapipb.ActorState_ACTOR_STATE_SUSPENDED: - f.states[name] = ateapipb.ActorState_ACTOR_STATE_RUNNING - return &ateapipb.ResumeActorResponse{Resumed: true}, nil + case ateapi.ActorState_ACTOR_STATE_RUNNING: + return &ateapi.ResumeActorResponse{Resumed: false}, nil + case ateapi.ActorState_ACTOR_STATE_SUSPENDED: + f.states[name] = ateapi.ActorState_ACTOR_STATE_RUNNING + return &ateapi.ResumeActorResponse{Resumed: true}, nil } return nil, status.Error(codes.Aborted, "actor crashed") } // SuspendActor fakes only an async suspend, which is how the user pauses. -func (f *fakeControlClient) SuspendActor(ctx context.Context, in *ateapipb.SuspendActorRequest, opts ...grpc.CallOption) (*ateapipb.SuspendActorResponse, error) { +func (f *fakeControlClient) SuspendActor(ctx context.Context, in *ateapi.SuspendActorRequest, opts ...grpc.CallOption) (*ateapi.SuspendActorResponse, error) { f.mu.Lock() defer f.mu.Unlock() f.setTrailer(opts) name := in.GetActor().GetName() f.record("SuspendActor(async)", name) - if in.GetOptions().GetMode() != ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS { + if in.GetOptions().GetMode() != ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS { return nil, status.Error(codes.Unimplemented, "only async suspend is faked") } if f.pauseErr != nil { return nil, f.pauseErr } - if f.states[name] != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if f.states[name] != ateapi.ActorState_ACTOR_STATE_RUNNING { return nil, status.Error(codes.FailedPrecondition, "not running") } // A paused actor is SUSPENDED holding a node-local snapshot; the fake // tracks only the state. - f.states[name] = ateapipb.ActorState_ACTOR_STATE_SUSPENDED - return &ateapipb.SuspendActorResponse{}, nil + f.states[name] = ateapi.ActorState_ACTOR_STATE_SUSPENDED + return &ateapi.SuspendActorResponse{}, nil } -func (f *fakeControlClient) DeleteActor(ctx context.Context, in *ateapipb.DeleteActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { +func (f *fakeControlClient) DeleteActor(ctx context.Context, in *ateapi.DeleteActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { f.mu.Lock() defer f.mu.Unlock() name := in.GetActor().GetName() @@ -200,7 +200,7 @@ func (f *fakeControlClient) DeleteActor(ctx context.Context, in *ateapipb.Delete return nil, status.Error(codes.Aborted, "lease held") } delete(f.states, name) - return &ateapipb.Actor{}, nil + return &ateapi.Actor{}, nil } // callsTo returns the actors of every recorded call to rpc, in order. @@ -316,7 +316,7 @@ func TestFirstIterationMakesTheUsersActorCold(t *testing.T) { if !slices.Equal(fake.calls, want) { t.Errorf("calls: got %v, want %v", fake.calls, want) } - if got := fake.state(name); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := fake.state(name); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("actor is %v, want paused (SUSPENDED)", got) } if got := trackedActors(r); !slices.Equal(got, actors) { @@ -446,7 +446,7 @@ func TestSetupDeletesAnActorThatDoesNotWarmAndRetries(t *testing.T) { if len(actors) != 1 || actors[0] == created[0] { t.Fatalf("got user actors %v, want a new one", actors) } - if got := fake.state(actors[0]); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := fake.state(actors[0]); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("actor is %v, want paused (SUSPENDED)", got) } } @@ -489,7 +489,7 @@ func TestIterateFailsAResumeOfARunningActor(t *testing.T) { r := newTestRuntime(fake) r.iterate() name := userActors(r)[0] - fake.setState(name, ateapipb.ActorState_ACTOR_STATE_RUNNING) + fake.setState(name, ateapi.ActorState_ACTOR_STATE_RUNNING) fake.resetCalls() before := requestCount(t, "ResumeActorCold", "failure") recoveries := requestCount(t, "SuspendActorAsyncRecovery", "success") @@ -506,7 +506,7 @@ func TestIterateFailsAResumeOfARunningActor(t *testing.T) { if !slices.Equal(fake.calls, want) { t.Errorf("calls: got %v, want %v", fake.calls, want) } - if got := fake.state(name); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := fake.state(name); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("actor is %v, want paused (SUSPENDED)", got) } } @@ -522,7 +522,7 @@ func TestIterateKeepsTheActorAfterAFailedResume(t *testing.T) { if got := userActors(r); !slices.Equal(got, []string{name}) { t.Errorf("user actors: got %v, want [%s]", got, name) } - if got := fake.state(name); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := fake.state(name); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("actor is %v, want paused (SUSPENDED)", got) } } @@ -617,7 +617,7 @@ func TestShutdownRetriesAnAbortedDelete(t *testing.T) { if got := fake.callsTo("DeleteActor"); len(got) != 3 { t.Errorf("DeleteActor calls = %v, want 3 calls", got) } - if _, err := fake.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: r.ref(name)}); status.Code(err) != codes.NotFound { + if _, err := fake.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: r.ref(name)}); status.Code(err) != codes.NotFound { t.Errorf("actor still exists after shutdown: err = %v", err) } } @@ -772,7 +772,7 @@ func TestShutdownCancelsACycleThatOutlastsItsShare(t *testing.T) { if got := fake.callsTo("DeleteActor"); !slices.Equal(got, []string{name}) { t.Errorf("deleted %v, want [%s]", got, name) } - if _, err := fake.GetActor(context.Background(), &ateapipb.GetActorRequest{Actor: r.ref(name)}); status.Code(err) != codes.NotFound { + if _, err := fake.GetActor(context.Background(), &ateapi.GetActorRequest{Actor: r.ref(name)}); status.Code(err) != codes.NotFound { t.Errorf("actor still exists after shutdown: err = %v", err) } } diff --git a/internal/benchmarking/boomer/sweperf/sweperf.go b/internal/benchmarking/boomer/sweperf/sweperf.go index 07b102eed6..f503c34c08 100644 --- a/internal/benchmarking/boomer/sweperf/sweperf.go +++ b/internal/benchmarking/boomer/sweperf/sweperf.go @@ -36,13 +36,13 @@ import ( "time" "github.com/google/uuid" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateinterceptors" "go.ate.dev/substrate/internal/atenet" "go.ate.dev/substrate/internal/benchmarking/boomer/boomerutil" "go.ate.dev/substrate/internal/benchmarking/boomer/dynconfig" bmetrics "go.ate.dev/substrate/internal/benchmarking/boomer/metrics" "go.ate.dev/substrate/internal/benchmarking/boomer/userclass" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/propagation" @@ -551,8 +551,8 @@ type sweperfUser struct { } // ref is the control-plane reference to this user's actor. -func (u *sweperfUser) ref() *ateapipb.ObjectRef { - return &ateapipb.ObjectRef{Atespace: u.cfg.Atespace, Name: u.actorName} +func (u *sweperfUser) ref() *ateapi.ObjectRef { + return &ateapi.ObjectRef{Atespace: u.cfg.Atespace, Name: u.actorName} } // setActorRouting names the actor the atenet router should route this request @@ -566,9 +566,9 @@ func (u *sweperfUser) setActorRouting(req *http.Request) { // success so concurrent users racing the first creation all proceed. func (u *sweperfUser) ensureAtespace(ctx context.Context) error { return u.tracedCall(ctx, "CreateAtespace", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.CreateAtespace(callCtx, &ateapipb.CreateAtespaceRequest{ - Atespace: &ateapipb.Atespace{ - Metadata: &ateapipb.ResourceMetadata{ + _, err := u.cfg.APIStub.CreateAtespace(callCtx, &ateapi.CreateAtespaceRequest{ + Atespace: &ateapi.Atespace{ + Metadata: &ateapi.ResourceMetadata{ Name: u.cfg.Atespace, }, }, @@ -588,10 +588,10 @@ func (u *sweperfUser) ensureAtespace(ctx context.Context) error { // (see pollLiveness). func (u *sweperfUser) create(ctx context.Context) error { return u.tracedCall(ctx, "CreateActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.CreateActor(callCtx, &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: u.cfg.Atespace, Name: u.actorName}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: templateNS, Name: u.templateName}, + _, err := u.cfg.APIStub.CreateActor(callCtx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: u.cfg.Atespace, Name: u.actorName}, + ActorTemplate: &ateapi.ObjectRef{Atespace: templateNS, Name: u.templateName}, }, }, grpc.Trailer(tr)) return err @@ -603,7 +603,7 @@ func (u *sweperfUser) create(ctx context.Context) error { // to abandon the cycle rather than talk to a sandbox that is not running. func (u *sweperfUser) resume(ctx context.Context) (time.Duration, bool) { latency, err := u.tracedCallRecord(ctx, "ResumeActor", !u.awake, func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.ResumeActor(callCtx, &ateapipb.ResumeActorRequest{ + _, err := u.cfg.APIStub.ResumeActor(callCtx, &ateapi.ResumeActorRequest{ Actor: u.ref(), }, grpc.Trailer(tr)) return err @@ -620,14 +620,14 @@ func (u *sweperfUser) resume(ctx context.Context) (time.Duration, bool) { // the suspend is asynchronous and recorded as SuspendActorAsync; in sync // lifecycle mode it is synchronous and recorded as SuspendActor. func (u *sweperfUser) suspend(ctx context.Context) bool { - name, mode := "SuspendActorAsync", ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS + name, mode := "SuspendActorAsync", ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS if dynconfig.Get[knobs](u.cfg.Dyn).LifecycleMode == dynconfig.LifecycleModeSync { - name, mode = "SuspendActor", ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS + name, mode = "SuspendActor", ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS } err := u.tracedCall(ctx, name, func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapipb.SuspendActorRequest{ + _, err := u.cfg.APIStub.SuspendActor(callCtx, &ateapi.SuspendActorRequest{ Actor: u.ref(), - Options: &ateapipb.SuspendOptions{Mode: mode}, + Options: &ateapi.SuspendOptions{Mode: mode}, }, grpc.Trailer(tr)) return err }) @@ -642,7 +642,7 @@ func (u *sweperfUser) suspend(ctx context.Context) bool { // and returned so the caller can retry. func (u *sweperfUser) delete(ctx context.Context) error { return u.tracedCall(ctx, "DeleteActor", func(callCtx context.Context, tr *metadata.MD) error { - _, err := u.cfg.APIStub.DeleteActor(callCtx, &ateapipb.DeleteActorRequest{ + _, err := u.cfg.APIStub.DeleteActor(callCtx, &ateapi.DeleteActorRequest{ Actor: u.ref(), }, grpc.Trailer(tr)) return err diff --git a/internal/benchmarking/boomer/sweperf/sweperf_test.go b/internal/benchmarking/boomer/sweperf/sweperf_test.go index 28e68176e4..dcf72695ad 100644 --- a/internal/benchmarking/boomer/sweperf/sweperf_test.go +++ b/internal/benchmarking/boomer/sweperf/sweperf_test.go @@ -30,12 +30,12 @@ import ( "time" "github.com/prometheus/client_golang/prometheus" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateinterceptors" "go.ate.dev/substrate/internal/atenet" "go.ate.dev/substrate/internal/benchmarking/boomer/boomerutil" "go.ate.dev/substrate/internal/benchmarking/boomer/dynconfig" "go.ate.dev/substrate/internal/benchmarking/boomer/userclass" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -96,7 +96,7 @@ func recordedSince(t *testing.T, before map[statKey]statSample, name, status str } type fakeControlClient struct { - ateapipb.ControlClient + ateapi.ControlClient mu sync.Mutex calls []string createSpaceErr error @@ -104,7 +104,7 @@ type fakeControlClient struct { resumeErr error suspendErr error deleteErr error - suspendReqs []*ateapipb.SuspendActorRequest + suspendReqs []*ateapi.SuspendActorRequest // Make ResumeActor take time and report a smaller server-side elapsed. resumeDelay time.Duration resumeElapsedUs string @@ -112,27 +112,27 @@ type fakeControlClient struct { beforeDelete func() } -func (f *fakeControlClient) CreateAtespace(ctx context.Context, in *ateapipb.CreateAtespaceRequest, opts ...grpc.CallOption) (*ateapipb.Atespace, error) { +func (f *fakeControlClient) CreateAtespace(ctx context.Context, in *ateapi.CreateAtespaceRequest, opts ...grpc.CallOption) (*ateapi.Atespace, error) { f.mu.Lock() defer f.mu.Unlock() f.calls = append(f.calls, "CreateAtespace") if f.createSpaceErr != nil { return nil, f.createSpaceErr } - return &ateapipb.Atespace{}, nil + return &ateapi.Atespace{}, nil } -func (f *fakeControlClient) CreateActor(ctx context.Context, in *ateapipb.CreateActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { +func (f *fakeControlClient) CreateActor(ctx context.Context, in *ateapi.CreateActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { f.mu.Lock() defer f.mu.Unlock() f.calls = append(f.calls, "CreateActor") if f.createActorErr != nil { return nil, f.createActorErr } - return &ateapipb.Actor{}, nil + return &ateapi.Actor{}, nil } -func (f *fakeControlClient) ResumeActor(ctx context.Context, in *ateapipb.ResumeActorRequest, opts ...grpc.CallOption) (*ateapipb.ResumeActorResponse, error) { +func (f *fakeControlClient) ResumeActor(ctx context.Context, in *ateapi.ResumeActorRequest, opts ...grpc.CallOption) (*ateapi.ResumeActorResponse, error) { f.mu.Lock() defer f.mu.Unlock() f.calls = append(f.calls, "ResumeActor") @@ -143,7 +143,7 @@ func (f *fakeControlClient) ResumeActor(ctx context.Context, in *ateapipb.Resume if f.resumeErr != nil { return nil, f.resumeErr } - return &ateapipb.ResumeActorResponse{}, nil + return &ateapi.ResumeActorResponse{}, nil } // setTrailer fills the metadata that grpc.Trailer asked the call to populate. @@ -155,7 +155,7 @@ func setTrailer(opts []grpc.CallOption, md metadata.MD) { } } -func (f *fakeControlClient) SuspendActor(ctx context.Context, in *ateapipb.SuspendActorRequest, opts ...grpc.CallOption) (*ateapipb.SuspendActorResponse, error) { +func (f *fakeControlClient) SuspendActor(ctx context.Context, in *ateapi.SuspendActorRequest, opts ...grpc.CallOption) (*ateapi.SuspendActorResponse, error) { f.mu.Lock() defer f.mu.Unlock() f.calls = append(f.calls, "SuspendActor") @@ -163,10 +163,10 @@ func (f *fakeControlClient) SuspendActor(ctx context.Context, in *ateapipb.Suspe if f.suspendErr != nil { return nil, f.suspendErr } - return &ateapipb.SuspendActorResponse{}, nil + return &ateapi.SuspendActorResponse{}, nil } -func (f *fakeControlClient) DeleteActor(ctx context.Context, in *ateapipb.DeleteActorRequest, opts ...grpc.CallOption) (*ateapipb.Actor, error) { +func (f *fakeControlClient) DeleteActor(ctx context.Context, in *ateapi.DeleteActorRequest, opts ...grpc.CallOption) (*ateapi.Actor, error) { if f.beforeDelete != nil { f.beforeDelete() } @@ -179,7 +179,7 @@ func (f *fakeControlClient) DeleteActor(ctx context.Context, in *ateapipb.Delete if f.deleteErr != nil { return nil, f.deleteErr } - return &ateapipb.Actor{}, nil + return &ateapi.Actor{}, nil } func (f *fakeControlClient) recordedCalls() []string { @@ -407,8 +407,8 @@ func TestSweperfUserCycleSequence(t *testing.T) { suspendReqs := fakeCtrl.suspendReqs fakeCtrl.mu.Unlock() for _, req := range suspendReqs { - if got := req.GetOptions().GetMode(); got != ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS { - t.Errorf("suspend mode = %v, want %v", got, ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS) + if got := req.GetOptions().GetMode(); got != ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS { + t.Errorf("suspend mode = %v, want %v", got, ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS) } } @@ -425,12 +425,12 @@ func TestSweperfUserCycleSequence(t *testing.T) { func TestSuspendLifecycleMode(t *testing.T) { for _, tt := range []struct { mode string - want ateapipb.DurabilityMode + want ateapi.DurabilityMode wantMetric string }{ - {"", ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, "SuspendActorAsync"}, - {dynconfig.LifecycleModeSync, ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS, "SuspendActor"}, - {dynconfig.LifecycleModeAsync, ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, "SuspendActorAsync"}, + {"", ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, "SuspendActorAsync"}, + {dynconfig.LifecycleModeSync, ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS, "SuspendActor"}, + {dynconfig.LifecycleModeAsync, ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS, "SuspendActorAsync"}, } { t.Run("mode="+tt.mode, func(t *testing.T) { cfg, _, fakeCtrl := newTestConfig(t, http.NotFoundHandler()) diff --git a/internal/benchmarking/boomer/userclass/config.go b/internal/benchmarking/boomer/userclass/config.go index 9eef062ba4..692a967ba0 100644 --- a/internal/benchmarking/boomer/userclass/config.go +++ b/internal/benchmarking/boomer/userclass/config.go @@ -18,8 +18,8 @@ import ( "net/http" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/benchmarking/boomer/dynconfig" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.opentelemetry.io/otel/trace" ) @@ -27,7 +27,7 @@ import ( // and passed to the entry's Init func. type Config struct { // APIStub is the shared gRPC client to ateapi (one connection, all goroutines). - APIStub ateapipb.ControlClient + APIStub ateapi.ControlClient // HTTPClient is the shared HTTP client for atenet pings. HTTPClient *http.Client // RouterURL is the base URL of the atenet router (no trailing slash). diff --git a/internal/benchmarking/glutton/script_test.go b/internal/benchmarking/glutton/script_test.go index 22ac88d51b..d273783d06 100644 --- a/internal/benchmarking/glutton/script_test.go +++ b/internal/benchmarking/glutton/script_test.go @@ -22,6 +22,7 @@ import ( "net/http/httptest" "strings" "testing" + "testing/synctest" "time" "google.golang.org/grpc/codes" @@ -122,58 +123,72 @@ func TestRunScriptRunsStepsInOrderAndSumsStats(t *testing.T) { } } -// Requests in one operation overlap: two sleeps of 100ms take about 100ms, +// The timing tests run on a synctest bubble. Its clock advances only when +// every goroutine is blocked on a timer, and then by exactly the timer's +// duration, so a pass costs its sleep and nothing else, and the pass +// counts and elapsed times are exact instead of depending on how fast the +// machine runs the disk writes between sleeps. + +// Requests in one operation overlap: three sleeps of 100ms take 100ms, // and the operation's elapsed is its longest request, not their sum. func TestRunScriptOperationRunsRequestsTogether(t *testing.T) { - svc := newTestService(t) - start := time.Now() - result := run(t, svc, script(op(sleepFor(100), sleepFor(100), sleepFor(100)))) - if elapsed := time.Since(start); elapsed > 250*time.Millisecond { - t.Errorf("three parallel 100ms sleeps took %v", elapsed) - } - stats := result.GetChildren()[0].GetStats() - if stats.GetSleptMs() < 300 || stats.GetElapsedMs() > 250 { - t.Errorf("operation slept_ms=%d elapsed_ms=%d, want ~300 summed and ~100 wall", stats.GetSleptMs(), stats.GetElapsedMs()) - } + synctest.Test(t, func(t *testing.T) { + svc := newTestService(t) + start := time.Now() + result := run(t, svc, script(op(sleepFor(100), sleepFor(100), sleepFor(100)))) + if elapsed := time.Since(start); elapsed != 100*time.Millisecond { + t.Errorf("three parallel 100ms sleeps took %v", elapsed) + } + stats := result.GetChildren()[0].GetStats() + if stats.GetSleptMs() != 300 || stats.GetElapsedMs() != 100 { + t.Errorf("operation slept_ms=%d elapsed_ms=%d, want 300 summed and 100 wall", stats.GetSleptMs(), stats.GetElapsedMs()) + } + }) } // A looped block cycles until its budget and finishes the pass it is in: -// every pass is whole, the loop overruns by at most one pass, and the -// stats count every pass. +// every pass is whole, the loop overruns its budget by at most one pass, +// and the stats count every pass. Three 30ms passes end at 90ms, inside +// the 100ms budget, so a fourth runs and the loop ends at 120ms. func TestRunScriptLoopsUntilTheBudget(t *testing.T) { - svc := newTestService(t) - start := time.Now() - result := run(t, svc, script(loop(100, op(sleepFor(30)), op(writeDisk("churn", 16))))) - elapsed := time.Since(start) - if elapsed < 100*time.Millisecond || elapsed > 300*time.Millisecond { - t.Errorf("a 100ms loop returned after %v", elapsed) - } - looped := result.GetChildren()[0].GetStats() - if looped.GetPasses() < 4 || looped.GetPasses() > 5 { - t.Errorf("passes = %d, want 4 whole 30ms passes to cover 100ms", looped.GetPasses()) - } - // Whole passes: as many writes as sleeps, and the sleeps complete. - if looped.GetDiskBytesWritten() != 16*looped.GetPasses() || looped.GetSleptMs() < 30*(looped.GetPasses()-1) { - t.Errorf("loop stats = %v, want %d whole passes", looped, looped.GetPasses()) - } - if root := result.GetStats(); root.GetPasses() != 1 || root.GetDiskBytesWritten() != looped.GetDiskBytesWritten() { - t.Errorf("root = %v, want one pass and the loop's totals", root) - } + synctest.Test(t, func(t *testing.T) { + svc := newTestService(t) + start := time.Now() + result := run(t, svc, script(loop(100, op(sleepFor(30)), op(writeDisk("churn", 16))))) + if elapsed := time.Since(start); elapsed != 120*time.Millisecond { + t.Errorf("a 100ms loop of 30ms passes returned after %v, want 120ms", elapsed) + } + looped := result.GetChildren()[0].GetStats() + if looped.GetPasses() != 4 { + t.Errorf("passes = %d, want 4", looped.GetPasses()) + } + // Whole passes: as many writes as sleeps, and the sleeps complete. + if looped.GetDiskBytesWritten() != 16*4 || looped.GetSleptMs() != 30*4 || looped.GetElapsedMs() != 120 { + t.Errorf("loop stats = %v, want 4 whole passes", looped) + } + if root := result.GetStats(); root.GetPasses() != 1 || root.GetDiskBytesWritten() != looped.GetDiskBytesWritten() { + t.Errorf("root = %v, want one pass and the loop's totals", root) + } + }) } // An inner loop stops cycling once the outer one's budget has elapsed, -// finishing its pass; that is not an error. +// finishing its pass; that is not an error. Five 20ms passes reach the +// outer 100ms budget exactly, so neither loop starts a sixth. func TestRunScriptNestedLoopsShareTheBudget(t *testing.T) { - svc := newTestService(t) - start := time.Now() - result := run(t, svc, script(loop(100, loop(5000, op(sleepFor(20)))))) - if elapsed := time.Since(start); elapsed > 300*time.Millisecond { - t.Errorf("a 5s loop inside a 100ms loop ran for %v", elapsed) - } - inner := result.GetChildren()[0].GetChildren()[0].GetStats() - if inner.GetPasses() < 5 || inner.GetSleptMs() < 20*inner.GetPasses() { - t.Errorf("inner loop = %v, want ~5 whole 20ms passes", inner) - } + synctest.Test(t, func(t *testing.T) { + svc := newTestService(t) + start := time.Now() + result := run(t, svc, script(loop(100, loop(5000, op(sleepFor(20)))))) + if elapsed := time.Since(start); elapsed != 100*time.Millisecond { + t.Errorf("a 5s loop inside a 100ms loop ran for %v", elapsed) + } + outer := result.GetChildren()[0].GetStats() + inner := result.GetChildren()[0].GetChildren()[0].GetStats() + if outer.GetPasses() != 1 || inner.GetPasses() != 5 || inner.GetSleptMs() != 100 { + t.Errorf("outer = %v inner = %v, want one outer pass and 5 whole 20ms inner passes", outer, inner) + } + }) } // Shape problems are rejected before any step runs, with the node named. diff --git a/internal/contextlogging/contextlogging_test.go b/internal/contextlogging/contextlogging_test.go index 72c031e7bf..3935e8a679 100644 --- a/internal/contextlogging/contextlogging_test.go +++ b/internal/contextlogging/contextlogging_test.go @@ -26,9 +26,9 @@ import ( "go.opentelemetry.io/otel/trace" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/protoredact" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/protobuf/reflect/protoreflect" ) @@ -143,17 +143,17 @@ func TestHandleUngroupedKeepsTraceFieldsTopLevel(t *testing.T) { // tokenValuer stands in for a type that implements slog.LogValuer and // resolves to a proto; the handler must resolve it before deciding. type tokenValuer struct { - m *ateapipb.MintActorJwtResponse + m *ateapi.MintActorJwtResponse } func (v tokenValuer) LogValue() slog.Value { return slog.AnyValue(v.m) } func TestHandleRedactsProtoAttrsAnywhereInTheRecord(t *testing.T) { const token = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhY3RvciJ9.c2lnbmF0dXJl" - resp := &ateapipb.MintActorJwtResponse{ActorJwt: token} - ref := &ateapipb.ObjectRef{Atespace: "ate-demo-sandbox", Name: "agent"} - tpl := &ateapipb.ActorTemplate{Containers: []*ateapipb.Container{{ - Name: "c", Env: []*ateapipb.EnvVar{{Name: "API_KEY", Value: "sk-secret"}}, + resp := &ateapi.MintActorJwtResponse{ActorJwt: token} + ref := &ateapi.ObjectRef{Atespace: "ate-demo-sandbox", Name: "agent"} + tpl := &ateapi.ActorTemplate{Containers: []*ateapi.Container{{ + Name: "c", Env: []*ateapi.EnvVar{{Name: "API_KEY", Value: "sk-secret"}}, }}} var buf bytes.Buffer @@ -202,7 +202,7 @@ func (stringValuer) LogValue() slog.Value { return slog.StringValue("resolved") // groupValuer resolves to a group that holds a proto, the shape a typed // reference with a nested message would take. type groupValuer struct { - m *ateapipb.MintActorJwtResponse + m *ateapi.MintActorJwtResponse } func (g groupValuer) LogValue() slog.Value { @@ -215,8 +215,8 @@ type countingValuer struct{ n *int } func (c countingValuer) LogValue() slog.Value { *c.n++; return slog.StringValue("once") } func TestRedactValueReportsWhatItChanges(t *testing.T) { - sensitive := &ateapipb.MintActorJwtResponse{ActorJwt: "token"} - envless := &ateapipb.ActorTemplate{Containers: []*ateapipb.Container{{Name: "c"}}} + sensitive := &ateapi.MintActorJwtResponse{ActorJwt: "token"} + envless := &ateapi.ActorTemplate{Containers: []*ateapi.Container{{Name: "c"}}} for _, tc := range []struct { name string in slog.Value @@ -226,10 +226,10 @@ func TestRedactValueReportsWhatItChanges(t *testing.T) { {"int", slog.IntValue(1), false}, {"non-proto any", slog.AnyValue(struct{ X int }{1}), false}, {"nil any", slog.AnyValue(nil), false}, - {"clean type", slog.AnyValue(&ateapipb.ObjectRef{Name: "n"}), false}, + {"clean type", slog.AnyValue(&ateapi.ObjectRef{Name: "n"}), false}, {"labeled type, nothing set", slog.AnyValue(envless), false}, - {"typed nil labeled type", slog.AnyValue((*ateapipb.MintActorJwtResponse)(nil)), false}, - {"group of plain values", slog.GroupValue(slog.String("a", "b"), slog.Any("ref", &ateapipb.ObjectRef{})), false}, + {"typed nil labeled type", slog.AnyValue((*ateapi.MintActorJwtResponse)(nil)), false}, + {"group of plain values", slog.GroupValue(slog.String("a", "b"), slog.Any("ref", &ateapi.ObjectRef{})), false}, {"empty group", slog.GroupValue(), false}, {"sensitive", slog.AnyValue(sensitive), true}, {"group holding sensitive", slog.GroupValue(slog.String("a", "b"), slog.Group("in", slog.Any("r", sensitive))), true}, @@ -256,28 +256,28 @@ func TestRedactValueReportsWhatItChanges(t *testing.T) { } func TestRedactAttrsReturnsTheInputWhenNothingChanges(t *testing.T) { - in := []slog.Attr{slog.String("a", "b"), slog.Any("ref", &ateapipb.ObjectRef{Name: "n"}), slog.Group("g", slog.Int("n", 1))} + in := []slog.Attr{slog.String("a", "b"), slog.Any("ref", &ateapi.ObjectRef{Name: "n"}), slog.Group("g", slog.Int("n", 1))} out := redactAttrs(in) if len(out) != len(in) || &out[0] != &in[0] { t.Fatal("redactAttrs copied a slice with nothing to change") } - sensitive := &ateapipb.MintActorJwtResponse{ActorJwt: "token"} + sensitive := &ateapi.MintActorJwtResponse{ActorJwt: "token"} in = append(in, slog.Group("g2", slog.Any("r", sensitive))) out = redactAttrs(in) if &out[0] == &in[0] { t.Fatal("redactAttrs returned the input although an attribute changed") } - if in[3].Value.Group()[0].Value.Any().(*ateapipb.MintActorJwtResponse).GetActorJwt() != "token" { + if in[3].Value.Group()[0].Value.Any().(*ateapi.MintActorJwtResponse).GetActorJwt() != "token" { t.Fatal("redactAttrs modified the input slice") } - if out[3].Value.Group()[0].Value.Any().(*ateapipb.MintActorJwtResponse).GetActorJwt() != protoredact.Placeholder { + if out[3].Value.Group()[0].Value.Any().(*ateapi.MintActorJwtResponse).GetActorJwt() != protoredact.Placeholder { t.Fatal("redactAttrs did not mask the group member") } } func TestHandleCoversGroupsBoundAttrsAndNilsTogether(t *testing.T) { const token = "eyJhbGciOiJSUzI1NiJ9.token" - sensitive := &ateapipb.MintActorJwtResponse{ActorJwt: token} + sensitive := &ateapi.MintActorJwtResponse{ActorJwt: token} var buf bytes.Buffer base := slog.New(NewHandler(slog.NewJSONHandler(&buf, &slog.HandlerOptions{ReplaceAttr: dropTime}))) @@ -288,7 +288,7 @@ func TestHandleCoversGroupsBoundAttrsAndNilsTogether(t *testing.T) { With(slog.Group("bound", slog.Any("resp", sensitive))). WithGroup("inner"). Info("x", - slog.Any("nilresp", (*ateapipb.MintActorJwtResponse)(nil)), + slog.Any("nilresp", (*ateapi.MintActorJwtResponse)(nil)), slog.Any("valuer", groupValuer{sensitive}), slog.String("plain", "keep"), ) @@ -313,7 +313,7 @@ func TestHandleResolvesLogValuersOnce(t *testing.T) { calls := 0 attrs := []slog.Attr{slog.Any("v", countingValuer{&calls}), slog.String("a", "b")} if withProto { - attrs = append(attrs, slog.Any("resp", &ateapipb.MintActorJwtResponse{ActorJwt: "t"})) + attrs = append(attrs, slog.Any("resp", &ateapi.MintActorJwtResponse{ActorJwt: "t"})) } slog.New(NewHandler(slog.NewJSONHandler(io.Discard, nil))).LogAttrs(context.Background(), slog.LevelInfo, "x", attrs...) if calls != 1 { @@ -326,12 +326,12 @@ func TestHandleRebuildsOnlyWhenAnAttributeChanges(t *testing.T) { // Same record through the bare JSON handler and through ours must match // byte for byte when it carries only values redactValue leaves alone, // including a proto of a labeled type with nothing set. - envless := &ateapipb.ActorTemplate{Containers: []*ateapipb.Container{{Name: "c", Image: "img"}}} + envless := &ateapi.ActorTemplate{Containers: []*ateapi.Container{{Name: "c", Image: "img"}}} var plainBuf, oursBuf bytes.Buffer plain := slog.New(slog.NewJSONHandler(&plainBuf, &slog.HandlerOptions{ReplaceAttr: dropTime})) ours := slog.New(NewHandler(slog.NewJSONHandler(&oursBuf, &slog.HandlerOptions{ReplaceAttr: dropTime}))) for _, l := range []*slog.Logger{plain, ours} { - l.Info("x", slog.Any("tpl", envless), slog.Any("ref", &ateapipb.ObjectRef{Name: "n"}), slog.Int("n", 1), slog.String("a", "b"), slog.Bool("c", true), slog.Float64("f", 1.5), slog.Duration("d", time.Second)) + l.Info("x", slog.Any("tpl", envless), slog.Any("ref", &ateapi.ObjectRef{Name: "n"}), slog.Int("n", 1), slog.String("a", "b"), slog.Bool("c", true), slog.Float64("f", 1.5), slog.Duration("d", time.Second)) } if plainBuf.String() != oursBuf.String() { t.Fatalf("records differ:\n plain: %s\n ours: %s", plainBuf.String(), oursBuf.String()) @@ -340,8 +340,8 @@ func TestHandleRebuildsOnlyWhenAnAttributeChanges(t *testing.T) { // allocating, whatever its size. for _, attrs := range [][]slog.Attr{ {slog.Int("n", 1), slog.String("a", "b"), slog.Bool("c", true)}, - {slog.Any("ref", &ateapipb.ObjectRef{Name: "n"}), slog.Any("resp", &ateapipb.ListActorsResponse{}), slog.Int("n", 1)}, - {slog.Int("n", 1), slog.String("a", "b"), slog.Bool("c", true), slog.Float64("f", 1.5), slog.Duration("d", time.Second), slog.Any("ref", &ateapipb.ObjectRef{Name: "n"}), slog.Group("g", slog.String("k", "v"))}, + {slog.Any("ref", &ateapi.ObjectRef{Name: "n"}), slog.Any("resp", &ateapi.ListActorsResponse{}), slog.Int("n", 1)}, + {slog.Int("n", 1), slog.String("a", "b"), slog.Bool("c", true), slog.Float64("f", 1.5), slog.Duration("d", time.Second), slog.Any("ref", &ateapi.ObjectRef{Name: "n"}), slog.Group("g", slog.String("k", "v"))}, } { rec := slog.NewRecord(time.Now(), slog.LevelInfo, "x", 0) rec.AddAttrs(attrs...) @@ -358,7 +358,7 @@ func TestHandleLeavesRecordsWithoutProtosAlone(t *testing.T) { plain := slog.New(slog.NewJSONHandler(&plainBuf, &slog.HandlerOptions{ReplaceAttr: dropTime})) ours := slog.New(NewHandler(slog.NewJSONHandler(&oursBuf, &slog.HandlerOptions{ReplaceAttr: dropTime}))) for _, l := range []*slog.Logger{plain, ours} { - l.Info("x", slog.String("a", "b"), slog.Int("n", 1), slog.Any("nilproto", (*ateapipb.ObjectRef)(nil)), slog.Any("m", map[string]int{"k": 1})) + l.Info("x", slog.String("a", "b"), slog.Int("n", 1), slog.Any("nilproto", (*ateapi.ObjectRef)(nil)), slog.Any("m", map[string]int{"k": 1})) } if plainBuf.String() != oursBuf.String() { t.Fatalf("records differ:\n plain: %s\n ours: %s", plainBuf.String(), oursBuf.String()) @@ -376,23 +376,23 @@ func dropTime(_ []string, a slog.Attr) slog.Attr { // the three shapes that matter: no proto at all, a proto whose type has no // debug_redact field (returned without a copy), and one that has. func BenchmarkHandle(b *testing.B) { - listResp := &ateapipb.ListActorsResponse{} + listResp := &ateapi.ListActorsResponse{} for i := 0; i < 50; i++ { - listResp.Actors = append(listResp.Actors, &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: "s", Name: "agent", Uid: "86fae7b8-c9b4-479c-b7c8-6ef3ede0ab0b", Version: 1}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: "s", Name: "tpl"}, + listResp.Actors = append(listResp.Actors, &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: "s", Name: "agent", Uid: "86fae7b8-c9b4-479c-b7c8-6ef3ede0ab0b", Version: 1}, + ActorTemplate: &ateapi.ObjectRef{Atespace: "s", Name: "tpl"}, }) } - tpl := &ateapipb.ActorTemplate{Containers: []*ateapipb.Container{{Name: "c"}}} + tpl := &ateapi.ActorTemplate{Containers: []*ateapi.Container{{Name: "c"}}} for i := 0; i < 32; i++ { - tpl.Containers[0].Env = append(tpl.Containers[0].Env, &ateapipb.EnvVar{Name: "VAR", Value: "some-fairly-long-value-1234567890"}) + tpl.Containers[0].Env = append(tpl.Containers[0].Env, &ateapi.EnvVar{Name: "VAR", Value: "some-fairly-long-value-1234567890"}) } cases := []struct { name string attrs []slog.Attr }{ {"no_proto", []slog.Attr{slog.String("host", "example.com"), slog.String("leg", "mitm"), slog.Int("n", 3)}}, - {"clean_objectref", []slog.Attr{slog.Any("actor", &ateapipb.ObjectRef{Atespace: "s", Name: "agent"})}}, + {"clean_objectref", []slog.Attr{slog.Any("actor", &ateapi.ObjectRef{Atespace: "s", Name: "agent"})}}, {"clean_listactors_50", []slog.Attr{slog.Any("resp", listResp)}}, {"sensitive_template_32env", []slog.Attr{slog.Any("resp", tpl)}}, } @@ -419,7 +419,7 @@ func BenchmarkHandle(b *testing.B) { // with ==: a value receiver and a slice field. Comparing two of them as // interfaces panics at run time. type uncomparableMsg struct { - *ateapipb.MintActorJwtResponse + *ateapi.MintActorJwtResponse _ []int } @@ -435,8 +435,8 @@ func TestHandleToleratesUncomparableMessageTypes(t *testing.T) { msg uncomparableMsg want string }{ - {"nothing to mask", uncomparableMsg{MintActorJwtResponse: &ateapipb.MintActorJwtResponse{}}, `"v":{}`}, - {"secret set", uncomparableMsg{MintActorJwtResponse: &ateapipb.MintActorJwtResponse{ActorJwt: "token"}}, protoredact.Placeholder}, + {"nothing to mask", uncomparableMsg{MintActorJwtResponse: &ateapi.MintActorJwtResponse{}}, `"v":{}`}, + {"secret set", uncomparableMsg{MintActorJwtResponse: &ateapi.MintActorJwtResponse{ActorJwt: "token"}}, protoredact.Placeholder}, } { t.Run(tc.name, func(t *testing.T) { var buf bytes.Buffer diff --git a/internal/e2e/egresspolicy.go b/internal/e2e/egresspolicy.go index dc8c98048b..f18e299f3b 100644 --- a/internal/e2e/egresspolicy.go +++ b/internal/e2e/egresspolicy.go @@ -21,8 +21,8 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // TODO(yufan-su): Move these constructors into an internal/e2e/egresspolicy package. @@ -32,44 +32,44 @@ import ( // and address, as cleartext HTTP on any port and as intercepted HTTPS on 443. // TLS forwarded unread is not decided by the gateway yet, and a passthrough // rule on every port would tie with the http rule, which the API rejects. -func EgressAllowAll() []*ateapipb.EgressRule { - return []*ateapipb.EgressRule{ - {Http: &ateapipb.HttpRule{Hostnames: []string{"*"}, Ports: &ateapipb.Ports{All: &ateapipb.AllPorts{}}}}, - {Https: &ateapipb.HttpsRule{Hostnames: []string{"*"}}}, +func EgressAllowAll() []*ateapi.EgressRule { + return []*ateapi.EgressRule{ + {Http: &ateapi.HttpRule{Hostnames: []string{"*"}, Ports: &ateapi.Ports{All: &ateapi.AllPorts{}}}}, + {Https: &ateapi.HttpsRule{Hostnames: []string{"*"}}}, } } // EgressAllowHTTP is a rule that lets an actor send cleartext HTTP to the // hosts matching patterns (exact names, or "*." plus a name for one leftmost // label) on port 80. -func EgressAllowHTTP(patterns ...string) *ateapipb.EgressRule { - return &ateapipb.EgressRule{Http: &ateapipb.HttpRule{Hostnames: patterns}} +func EgressAllowHTTP(patterns ...string) *ateapi.EgressRule { + return &ateapi.EgressRule{Http: &ateapi.HttpRule{Hostnames: patterns}} } // EgressAllowHTTPS is a rule that lets an actor send HTTPS, intercepted by the // gateway, to the hosts matching patterns on port 443. -func EgressAllowHTTPS(patterns ...string) *ateapipb.EgressRule { - return &ateapipb.EgressRule{Https: &ateapipb.HttpsRule{Hostnames: patterns}} +func EgressAllowHTTPS(patterns ...string) *ateapi.EgressRule { + return &ateapi.EgressRule{Https: &ateapi.HttpsRule{Hostnames: patterns}} } // EgressAllowPassthrough is a rule that lets an actor send TLS to the hosts // matching patterns on any port, relayed by the gateway without decryption. -func EgressAllowPassthrough(patterns ...string) *ateapipb.EgressRule { - return &ateapipb.EgressRule{ - TlsPassthrough: &ateapipb.TlsPassthroughRule{ +func EgressAllowPassthrough(patterns ...string) *ateapi.EgressRule { + return &ateapi.EgressRule{ + TlsPassthrough: &ateapi.TlsPassthroughRule{ Hostnames: patterns, - Ports: &ateapipb.Ports{All: &ateapipb.AllPorts{}}, + Ports: &ateapi.Ports{All: &ateapi.AllPorts{}}, }, } } // EgressAllowPassthroughOnPorts is EgressAllowPassthrough confined to the // given ports. -func EgressAllowPassthroughOnPorts(ports []int32, patterns ...string) *ateapipb.EgressRule { - return &ateapipb.EgressRule{ - TlsPassthrough: &ateapipb.TlsPassthroughRule{ +func EgressAllowPassthroughOnPorts(ports []int32, patterns ...string) *ateapi.EgressRule { + return &ateapi.EgressRule{ + TlsPassthrough: &ateapi.TlsPassthroughRule{ Hostnames: patterns, - Ports: &ateapipb.Ports{Numbers: ports}, + Ports: &ateapi.Ports{Numbers: ports}, }, } } @@ -78,7 +78,7 @@ func EgressAllowPassthroughOnPorts(ports []int32, patterns ...string) *ateapipb. // a replace_headers effect: on a match, the gateway resolves credentialURI // through its credential provider and replaces header with prefix plus the // credential. -func EgressInjectHeader(header, prefix, credentialURI string, patterns ...string) *ateapipb.EgressRule { +func EgressInjectHeader(header, prefix, credentialURI string, patterns ...string) *ateapi.EgressRule { rule := EgressAllowHTTPS(patterns...) rule.Https.Effects = replaceHeaderEffects(header, prefix, credentialURI) return rule @@ -86,15 +86,15 @@ func EgressInjectHeader(header, prefix, credentialURI string, patterns ...string // EgressInjectHeaderHTTP is an http rule (see EgressAllowHTTP) carrying the // same credential replacement effect as EgressInjectHeader. -func EgressInjectHeaderHTTP(header, prefix, credentialURI string, patterns ...string) *ateapipb.EgressRule { +func EgressInjectHeaderHTTP(header, prefix, credentialURI string, patterns ...string) *ateapi.EgressRule { rule := EgressAllowHTTP(patterns...) rule.Http.Effects = replaceHeaderEffects(header, prefix, credentialURI) return rule } -func replaceHeaderEffects(header, prefix, credentialURI string) *ateapipb.HttpRuleEffects { - return &ateapipb.HttpRuleEffects{ - ReplaceHeaders: []*ateapipb.CredentialHeader{{ +func replaceHeaderEffects(header, prefix, credentialURI string) *ateapi.HttpRuleEffects { + return &ateapi.HttpRuleEffects{ + ReplaceHeaders: []*ateapi.CredentialHeader{{ Header: header, Prefix: prefix, CredentialUri: credentialURI, @@ -104,13 +104,13 @@ func replaceHeaderEffects(header, prefix, credentialURI string) *ateapipb.HttpRu // EnsureEgressPolicy gives actor an EgressPolicy with exactly rules, replacing // any it had. Deleting the actor deletes the policy, so there is no cleanup. -func EnsureEgressPolicy(t *testing.T, ctx context.Context, clients *Clients, actor *ateapipb.ObjectRef, rules ...*ateapipb.EgressRule) { +func EnsureEgressPolicy(t *testing.T, ctx context.Context, clients *Clients, actor *ateapi.ObjectRef, rules ...*ateapi.EgressRule) { t.Helper() - policy := &ateapipb.EgressPolicy{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actor.GetAtespace(), Name: resources.SingletonName}, + policy := &ateapi.EgressPolicy{ + Metadata: &ateapi.ResourceMetadata{Atespace: actor.GetAtespace(), Name: resources.SingletonName}, Rules: rules, } - _, err := clients.SubstrateAPI.CreateActorEgressPolicy(ctx, &ateapipb.CreateActorEgressPolicyRequest{ + _, err := clients.SubstrateAPI.CreateActorEgressPolicy(ctx, &ateapi.CreateActorEgressPolicyRequest{ Actor: actor, EgressPolicy: policy, }) @@ -120,12 +120,12 @@ func EnsureEgressPolicy(t *testing.T, ctx context.Context, clients *Clients, act } return } - existing, err := clients.SubstrateAPI.GetActorEgressPolicy(ctx, &ateapipb.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) + existing, err := clients.SubstrateAPI.GetActorEgressPolicy(ctx, &ateapi.GetActorEgressPolicyRequest{Actor: actor, Name: resources.SingletonName}) if err != nil { t.Fatalf("GetActorEgressPolicy for %s/%s: %v", actor.GetAtespace(), actor.GetName(), err) } policy.Metadata = existing.GetMetadata() - if _, err := clients.SubstrateAPI.UpdateActorEgressPolicy(ctx, &ateapipb.UpdateActorEgressPolicyRequest{ + if _, err := clients.SubstrateAPI.UpdateActorEgressPolicy(ctx, &ateapi.UpdateActorEgressPolicyRequest{ Actor: actor, EgressPolicy: policy, }); err != nil { diff --git a/internal/e2e/fixture.go b/internal/e2e/fixture.go index daeb254af5..434dabac68 100644 --- a/internal/e2e/fixture.go +++ b/internal/e2e/fixture.go @@ -16,11 +16,12 @@ package e2e import ( "context" + "maps" "strings" "testing" "time" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/encoding/protojson" @@ -64,9 +65,9 @@ func substrateTemplateSubstitutions(bucket, name string, trustBundles []string) // placeholder landing at the wrong depth or a misspelled field fails here // rather than applying cleanly and doing nothing — the same contract // `kubectl ate create actor-template` enforces. -func decodeSubstrateTemplates(t *testing.T, rendered []byte) []*ateapipb.ActorTemplate { +func decodeSubstrateTemplates(t *testing.T, rendered []byte) []*ateapi.ActorTemplate { t.Helper() - var templates []*ateapipb.ActorTemplate + var templates []*ateapi.ActorTemplate for doc := range strings.SplitSeq(string(rendered), "\n---") { jsonData, err := yaml.YAMLToJSON([]byte(doc)) if err != nil { @@ -75,7 +76,7 @@ func decodeSubstrateTemplates(t *testing.T, rendered []byte) []*ateapipb.ActorTe if string(jsonData) == "null" { continue } - tmpl := &ateapipb.ActorTemplate{} + tmpl := &ateapi.ActorTemplate{} if err := protojson.Unmarshal(jsonData, tmpl); err != nil { t.Fatalf("decoding protojson ActorTemplate: %v", err) } @@ -87,6 +88,24 @@ func decodeSubstrateTemplates(t *testing.T, rendered []byte) []*ateapipb.ActorTe return templates } +// FixtureOption adjusts what DeploySubstrateFixture installs. +type FixtureOption func(*fixtureConfig) + +type fixtureConfig struct { + templateValues map[string]string +} + +// WithTemplateValue replaces the inline placeholder ${name} in the fixture's +// ActorTemplate manifest with value. +func WithTemplateValue(name, value string) FixtureOption { + return func(c *fixtureConfig) { + if c.templateValues == nil { + c.templateValues = map[string]string{} + } + c.templateValues["${"+name+"}"] = value + } +} + // SubstrateFixtureManifests names the two manifest templates a substrate // fixture is built from (both repo-relative, under internal/e2e/fixtures). type SubstrateFixtureManifests struct { @@ -115,9 +134,14 @@ type SubstrateFixtureManifests struct { // // Returns the fixture's atespace (the same string that names the k8s // namespace holding the pool) and the created templates. -func DeploySubstrateFixture(t *testing.T, ctx context.Context, clients *Clients, manifests SubstrateFixtureManifests, bucket, name string, trustBundles []string) (string, []*ateapipb.ActorTemplate) { +func DeploySubstrateFixture(t *testing.T, ctx context.Context, clients *Clients, manifests SubstrateFixtureManifests, bucket, name string, trustBundles []string, opts ...FixtureOption) (string, []*ateapi.ActorTemplate) { t.Helper() + var cfg fixtureConfig + for _, opt := range opts { + opt(&cfg) + } + // The pool manifest also carries the namespace. Its cleanup is registered // first so it runs last (t.Cleanup is LIFO), after the templates that // select the pool's workers are gone. @@ -133,6 +157,7 @@ func DeploySubstrateFixture(t *testing.T, ctx context.Context, clients *Clients, }) tmplInline, tmplBlocks := substrateTemplateSubstitutions(bucket, name, trustBundles) + maps.Copy(tmplInline, cfg.templateValues) rendered := koResolve(t, renderManifest(t, manifests.Template, tmplInline, tmplBlocks)) templates := decodeSubstrateTemplates(t, rendered) @@ -153,7 +178,7 @@ func DeploySubstrateFixture(t *testing.T, ctx context.Context, clients *Clients, RunCmd(t, "kubectl", delArgs...) }) - if _, err := clients.SubstrateAPI.CreateAtespace(ctx, &ateapipb.CreateAtespaceRequest{Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: atespace}}}); err != nil && status.Code(err) != codes.AlreadyExists { + if _, err := clients.SubstrateAPI.CreateAtespace(ctx, &ateapi.CreateAtespaceRequest{Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: atespace}}}); err != nil && status.Code(err) != codes.AlreadyExists { t.Fatalf("failed to create atespace %q: %v", atespace, err) } t.Cleanup(func() { @@ -161,18 +186,18 @@ func DeploySubstrateFixture(t *testing.T, ctx context.Context, clients *Clients, // next run tolerates AlreadyExists anyway. cleanupCtx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - if _, err := clients.SubstrateAPI.DeleteAtespace(cleanupCtx, &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: atespace}}); err != nil && status.Code(err) != codes.NotFound { + if _, err := clients.SubstrateAPI.DeleteAtespace(cleanupCtx, &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: atespace}}); err != nil && status.Code(err) != codes.NotFound { t.Logf("failed to delete atespace %q: %v", atespace, err) } }) - created := make([]*ateapipb.ActorTemplate, 0, len(templates)) + created := make([]*ateapi.ActorTemplate, 0, len(templates)) for _, tmpl := range templates { - ref := &ateapipb.ObjectRef{Atespace: atespace, Name: tmpl.GetMetadata().GetName()} - if _, err := clients.SubstrateAPI.DeleteActorTemplate(ctx, &ateapipb.DeleteActorTemplateRequest{ActorTemplate: ref}); err != nil && status.Code(err) != codes.NotFound { + ref := &ateapi.ObjectRef{Atespace: atespace, Name: tmpl.GetMetadata().GetName()} + if _, err := clients.SubstrateAPI.DeleteActorTemplate(ctx, &ateapi.DeleteActorTemplateRequest{ActorTemplate: ref}); err != nil && status.Code(err) != codes.NotFound { t.Fatalf("failed to clear leaked ActorTemplate %s/%s: %v", atespace, ref.GetName(), err) } - c, err := clients.SubstrateAPI.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ActorTemplate: tmpl}) + c, err := clients.SubstrateAPI.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ActorTemplate: tmpl}) if err != nil { t.Fatalf("failed to create ActorTemplate %s/%s: %v", atespace, tmpl.GetMetadata().GetName(), err) } @@ -181,7 +206,7 @@ func DeploySubstrateFixture(t *testing.T, ctx context.Context, clients *Clients, t.Cleanup(func() { cleanupCtx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - if _, err := clients.SubstrateAPI.DeleteActorTemplate(cleanupCtx, &ateapipb.DeleteActorTemplateRequest{ActorTemplate: ref}); err != nil && status.Code(err) != codes.NotFound { + if _, err := clients.SubstrateAPI.DeleteActorTemplate(cleanupCtx, &ateapi.DeleteActorTemplateRequest{ActorTemplate: ref}); err != nil && status.Code(err) != codes.NotFound { t.Logf("failed to delete ActorTemplate %s/%s: %v", atespace, ref.GetName(), err) } }) diff --git a/internal/e2e/fixtures/capabilities/capabilities-templates.yaml.tmpl b/internal/e2e/fixtures/capabilities/capabilities-templates.yaml.tmpl index 9f895b1b86..50058605f2 100644 --- a/internal/e2e/fixtures/capabilities/capabilities-templates.yaml.tmpl +++ b/internal/e2e/fixtures/capabilities/capabilities-templates.yaml.tmpl @@ -13,7 +13,7 @@ # limitations under the License. # The capabilities fixture's ActorTemplates: protojson-shaped -# ateapipb.ActorTemplate documents (NOT the ate.dev/v1alpha1 CRD), created +# ateapi.ActorTemplate documents (NOT the ate.dev/v1 CRD), created # through the ate API by e2e.DeploySubstrateFixture. Two templates run the # same probe image and differ only in securityContext.capabilities, so the # suite can compare what the kernel reports inside the sandbox against what diff --git a/internal/e2e/fixtures/capabilities/capabilities.yaml.tmpl b/internal/e2e/fixtures/capabilities/capabilities.yaml.tmpl index a983c78490..d98f432bf0 100644 --- a/internal/e2e/fixtures/capabilities/capabilities.yaml.tmpl +++ b/internal/e2e/fixtures/capabilities/capabilities.yaml.tmpl @@ -27,7 +27,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: caps diff --git a/internal/e2e/fixtures/probe/main.go b/internal/e2e/fixtures/probe/main.go index 7a732bb4e2..2d0cc90888 100644 --- a/internal/e2e/fixtures/probe/main.go +++ b/internal/e2e/fixtures/probe/main.go @@ -35,6 +35,7 @@ import ( "runtime" "strconv" "strings" + "sync" "time" ) @@ -472,7 +473,120 @@ func writeJSON(w http.ResponseWriter, v any) { } } +// bootFetchURLEnv names a URL the probe must fetch, through the egress gateway +// and with the projected trust bundle, before it listens. A probe that cannot +// fetch it exits and never answers its wakeup probe, so a golden snapshot of +// it proves the actor had egress while it booted. +const bootFetchURLEnv = "PROBE_BOOT_FETCH_URL" + +// bootFetchTimeout bounds the boot fetch, inside the template's wakeupProbe +// timeout. +const bootFetchTimeout = 30 * time.Second + +// bootFetch GETs url once, trusting only trustBundle, and fails unless it +// answers 200. It does not retry: the actor's EgressPolicy exists before the +// actor resumes, so a failure is the finding. +func bootFetch(ctx context.Context, url, trustBundle string) error { + b, err := os.ReadFile(trustBundle) + if err != nil { + return fmt.Errorf("reading trust bundle: %w", err) + } + pool := x509.NewCertPool() + if !pool.AppendCertsFromPEM(b) { + return fmt.Errorf("no certificates parsed from %s", trustBundle) + } + client := &http.Client{ + Timeout: bootFetchTimeout, + Transport: &http.Transport{TLSClientConfig: &tls.Config{RootCAs: pool}}, + } + defer client.CloseIdleConnections() + if err := fetchOnce(ctx, client, url); err != nil { + return fmt.Errorf("boot fetch of %s: %w", url, err) + } + return nil +} + +// restoreFetch answers the wakeup probe once the actor named in its identity +// file has fetched url. A restore from the golden snapshot resumes past main's +// boot fetch with the restored actor's identity, so its wakeup probe passes +// only if the restored actor reaches url too. The prober times out each request +// after wakeupprobe.RequestTimeout, so the fetch runs in the background while +// /healthz answers 503. +type restoreFetch struct { + url, identityFile, trustBundle string + + mu sync.Mutex + fetched string + fetching string +} + +func (f *restoreFetch) healthz(w http.ResponseWriter, _ *http.Request) { + b, err := os.ReadFile(f.identityFile) + if err != nil { + http.Error(w, err.Error(), http.StatusServiceUnavailable) + return + } + id := string(b) + f.mu.Lock() + defer f.mu.Unlock() + if id == f.fetched { + w.WriteHeader(http.StatusOK) + return + } + if f.fetching != id { + f.fetching = id + go f.fetch(id) + } + http.Error(w, "fetching "+f.url+" as "+id, http.StatusServiceUnavailable) +} + +func (f *restoreFetch) fetch(id string) { + err := bootFetch(context.Background(), f.url, f.trustBundle) + f.mu.Lock() + defer f.mu.Unlock() + if f.fetching == id { + f.fetching = "" + } + if err != nil { + log.Printf("probe: restore fetch as %s: %v", id, err) + return + } + log.Printf("probe: restore fetch of %s as %s succeeded", f.url, id) + f.fetched = id +} + +func fetchOnce(ctx context.Context, client *http.Client, url string) error { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return err + } + res, err := client.Do(req) + if err != nil { + return err + } + defer res.Body.Close() + _, _ = io.Copy(io.Discard, io.LimitReader(res.Body, maxFetchBody)) + if res.StatusCode != http.StatusOK { + return fmt.Errorf("status %d", res.StatusCode) + } + return nil +} + func main() { + healthz := func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) } + if url := os.Getenv(bootFetchURLEnv); url != "" { + booted, err := os.ReadFile(identityFile) + if err != nil { + log.Fatalf("probe: reading %s: %v", identityFile, err) + } + if err := bootFetch(context.Background(), url, trustFile); err != nil { + log.Fatalf("probe: %v", err) + } + log.Printf("probe: boot fetch of %s succeeded", url) + f := &restoreFetch{url: url, identityFile: identityFile, trustBundle: trustFile, fetched: string(booted)} + healthz = f.healthz + } + // Hold the identity file open before serving: every snapshot of this actor // then contains an open guest handle on a system-info file (see // heldIdentity). @@ -490,7 +604,7 @@ func main() { mux.HandleFunc("/lookup", lookup) mux.HandleFunc("/resources", resources) mux.HandleFunc("/capabilities", capabilities) - mux.HandleFunc("/healthz", func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) }) + mux.HandleFunc("/healthz", healthz) const addr = ":80" log.Printf("probe listening on %s", addr) diff --git a/internal/e2e/fixtures/probe/main_test.go b/internal/e2e/fixtures/probe/main_test.go index 94fff20588..99ac3bb6a7 100644 --- a/internal/e2e/fixtures/probe/main_test.go +++ b/internal/e2e/fixtures/probe/main_test.go @@ -21,9 +21,13 @@ import ( "net/http" "net/http/httptest" "net/url" + "os" + "path/filepath" "slices" "strings" + "sync/atomic" "testing" + "time" "github.com/google/go-cmp/cmp" @@ -363,3 +367,122 @@ func TestCapabilityNamesTable(t *testing.T) { } } } + +// writeServerTrustBundle writes the TLS test server's certificate as the only +// anchor of a trust bundle and returns its path. +func writeServerTrustBundle(t *testing.T, server *httptest.Server) string { + t.Helper() + path := filepath.Join(t.TempDir(), "trust-bundle.pem") + block := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: server.Certificate().Raw}) + if err := os.WriteFile(path, block, 0o600); err != nil { + t.Fatal(err) + } + return path +} + +// The actor's EgressPolicy exists before it resumes, so the boot fetch makes +// one request and reports its failure. +func TestBootFetch(t *testing.T) { + tests := []struct { + name string + status int + wantErr string + }{ + {name: "origin answers 200", status: http.StatusOK}, + {name: "origin denies", status: http.StatusForbidden, wantErr: "status 403"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var calls atomic.Int32 + origin := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + calls.Add(1) + w.WriteHeader(tt.status) + })) + defer origin.Close() + + err := bootFetch(t.Context(), origin.URL, writeServerTrustBundle(t, origin)) + if tt.wantErr == "" && err != nil { + t.Fatalf("bootFetch() error = %v, want nil", err) + } + if tt.wantErr != "" && (err == nil || !strings.Contains(err.Error(), tt.wantErr)) { + t.Fatalf("bootFetch() error = %v, want %q", err, tt.wantErr) + } + if got := calls.Load(); got != 1 { + t.Errorf("origin saw %d requests, want 1", got) + } + }) + } +} + +// A restored actor resumes past the boot fetch with its own identity, so its +// wakeup probe fails until that identity has fetched. +func TestRestoreFetchGatesHealthzOnIdentity(t *testing.T) { + origin := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusOK) + })) + defer origin.Close() + identity := filepath.Join(t.TempDir(), "actor-id") + writeIdentity := func(id string) { + t.Helper() + if err := os.WriteFile(identity, []byte(id), 0o600); err != nil { + t.Fatal(err) + } + } + f := &restoreFetch{url: origin.URL, identityFile: identity, trustBundle: writeServerTrustBundle(t, origin), fetched: "golden"} + healthz := func() int { + rec := httptest.NewRecorder() + f.healthz(rec, httptest.NewRequest(http.MethodGet, "/healthz", nil)) + return rec.Code + } + + writeIdentity("golden") + if got := healthz(); got != http.StatusOK { + t.Fatalf("healthz as the actor that booted = %d, want 200", got) + } + writeIdentity("restored") + if got := healthz(); got != http.StatusServiceUnavailable { + t.Fatalf("healthz as a restored actor before it fetched = %d, want 503", got) + } + f.fetch("restored") + if got := healthz(); got != http.StatusOK { + t.Fatalf("healthz as a restored actor after it fetched = %d, want 200", got) + } +} + +// A failed restore fetch leaves healthz at 503, and the next wakeup probe +// starts another fetch. +func TestRestoreFetchRetriesOnNextProbe(t *testing.T) { + var deny atomic.Bool + deny.Store(true) + origin := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + if deny.Load() { + w.WriteHeader(http.StatusForbidden) + return + } + w.WriteHeader(http.StatusOK) + })) + defer origin.Close() + identity := filepath.Join(t.TempDir(), "actor-id") + if err := os.WriteFile(identity, []byte("restored"), 0o600); err != nil { + t.Fatal(err) + } + f := &restoreFetch{url: origin.URL, identityFile: identity, trustBundle: writeServerTrustBundle(t, origin), fetched: "golden"} + healthz := func() int { + rec := httptest.NewRecorder() + f.healthz(rec, httptest.NewRequest(http.MethodGet, "/healthz", nil)) + return rec.Code + } + + f.fetch("restored") + if got := healthz(); got != http.StatusServiceUnavailable { + t.Fatalf("healthz after a failed fetch = %d, want 503", got) + } + deny.Store(false) + deadline := time.Now().Add(10 * time.Second) + for healthz() != http.StatusOK { + if time.Now().After(deadline) { + t.Fatal("healthz did not answer 200 after the origin allowed the fetch") + } + time.Sleep(50 * time.Millisecond) + } +} diff --git a/internal/e2e/fixtures/probe/probe-bootfetch-template.yaml.tmpl b/internal/e2e/fixtures/probe/probe-bootfetch-template.yaml.tmpl new file mode 100644 index 0000000000..576976fe96 --- /dev/null +++ b/internal/e2e/fixtures/probe/probe-bootfetch-template.yaml.tmpl @@ -0,0 +1,67 @@ +# Copyright 2026 Google LLC +# +# 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. + +# Boot-fetch variant of the probe template: a protojson-shaped +# ateapi.ActorTemplate whose probe fetches the suite's BOOT_FETCH_URL through the +# egress gateway before it listens, so its golden snapshot exists only if the +# actor had egress while it booted. Selects the probe pool of probe.yaml.tmpl; +# goldenEgressPolicy (preview gate GoldenEgressPolicy) allows the golden actor +# to reach BOOT_FETCH_HOST; the suite gives the template the trust bundle and +# BOOT_FETCH_HOST and BOOT_FETCH_URL (see e2e.WithTemplateValue). + +metadata: + atespace: ate-e2e-probe${FIXTURE_SUFFIX} + name: probe-bootfetch +workerSelector: + matchLabels: + workload: probe${FIXTURE_SUFFIX} +containers: +- name: probe + image: ko://go.ate.dev/substrate/internal/e2e/fixtures/probe + command: ["/ko-app/probe"] + env: + - name: PROBE_BOOT_FETCH_URL + value: ${BOOT_FETCH_URL} + volumeMounts: + - name: system-info + mountPath: /run/ate + # Longer than the probe's boot fetch timeout, so a failed fetch is the + # probe's logged error rather than a probe timeout. + wakeupProbe: + httpGet: + path: /healthz + port: 80 + timeoutSeconds: 60 +volumes: +- name: system-info + systemInfo: + dataSources: + - actorMetadata: + items: + - field: ACTOR_METADATA_FIELD_NAME + path: actor-id +${TEMPLATE_TRUST_BUNDLE} +# The actor resolves BOOT_FETCH_HOST through its search path, and the DNS relay +# answers only names the policy lists, so the policy also lists the name the +# search path expands it to. +goldenEgressPolicy: + rules: + - https: + hostnames: ["${BOOT_FETCH_HOST}", "${BOOT_FETCH_HOST}.cluster.local"] +resources: + limits: + cpuMillicores: 1000 + memoryBytes: 536870912 # 512Mi +snapshotConfig: + storageLocation: gs://${BUCKET_NAME}/ate-e2e-probe-bootfetch${FIXTURE_SUFFIX}/ diff --git a/internal/e2e/fixtures/probe/probe-multiactor.yaml.tmpl b/internal/e2e/fixtures/probe/probe-multiactor.yaml.tmpl index 2d07d62b05..98ea98d593 100644 --- a/internal/e2e/fixtures/probe/probe-multiactor.yaml.tmpl +++ b/internal/e2e/fixtures/probe/probe-multiactor.yaml.tmpl @@ -21,7 +21,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: probe-multiactor diff --git a/internal/e2e/fixtures/probe/probe-parking-template.yaml.tmpl b/internal/e2e/fixtures/probe/probe-parking-template.yaml.tmpl index 9260f41647..8b4270db98 100644 --- a/internal/e2e/fixtures/probe/probe-parking-template.yaml.tmpl +++ b/internal/e2e/fixtures/probe/probe-parking-template.yaml.tmpl @@ -13,7 +13,7 @@ # limitations under the License. # Parking variant of the probe template: a protojson-shaped -# ateapipb.ActorTemplate whose limits are one whole worker's worth, so two of +# ateapi.ActorTemplate whose limits are one whole worker's worth, so two of # its actors cannot share the fixture's single worker. Reuses the probe image # (it serves /whoami, which names the actor that answered). diff --git a/internal/e2e/fixtures/probe/probe-parking.yaml.tmpl b/internal/e2e/fixtures/probe/probe-parking.yaml.tmpl index 4dcfc54cce..b136ab0235 100644 --- a/internal/e2e/fixtures/probe/probe-parking.yaml.tmpl +++ b/internal/e2e/fixtures/probe/probe-parking.yaml.tmpl @@ -25,7 +25,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: probe-parking diff --git a/internal/e2e/fixtures/probe/probe-sized-template.yaml.tmpl b/internal/e2e/fixtures/probe/probe-sized-template.yaml.tmpl index 4341b99270..3fb12d26c3 100644 --- a/internal/e2e/fixtures/probe/probe-sized-template.yaml.tmpl +++ b/internal/e2e/fixtures/probe/probe-sized-template.yaml.tmpl @@ -13,7 +13,7 @@ # limitations under the License. # Sized variant of the probe template: a protojson-shaped -# ateapipb.ActorTemplate declaring its own resources.limits, so the sizing e2e +# ateapi.ActorTemplate declaring its own resources.limits, so the sizing e2e # suite can assert the actor's sandbox is shaped to those limits. Reuses the # probe image (it serves the /resources endpoint). diff --git a/internal/e2e/fixtures/probe/probe-sized.yaml.tmpl b/internal/e2e/fixtures/probe/probe-sized.yaml.tmpl index 1528d71383..6a5ee4019b 100644 --- a/internal/e2e/fixtures/probe/probe-sized.yaml.tmpl +++ b/internal/e2e/fixtures/probe/probe-sized.yaml.tmpl @@ -26,7 +26,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: probe-sized diff --git a/internal/e2e/fixtures/probe/probe-template.yaml.tmpl b/internal/e2e/fixtures/probe/probe-template.yaml.tmpl index c2521de3f4..6d7c432c6b 100644 --- a/internal/e2e/fixtures/probe/probe-template.yaml.tmpl +++ b/internal/e2e/fixtures/probe/probe-template.yaml.tmpl @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# The probe fixture's ActorTemplate: a protojson-shaped ateapipb.ActorTemplate -# (NOT the ate.dev/v1alpha1 CRD), created through the ate API by +# The probe fixture's ActorTemplate: a protojson-shaped ateapi.ActorTemplate +# (NOT the ate.dev/v1 CRD), created through the ate API by # e2e.DeploySubstrateFixture after ko resolve pins the probe image. The # ate-e2e-probe${FIXTURE_SUFFIX} atespace doubles as the pool's k8s namespace # name in probe.yaml.tmpl. diff --git a/internal/e2e/fixtures/probe/probe.yaml.tmpl b/internal/e2e/fixtures/probe/probe.yaml.tmpl index 984925b566..0688a9ce56 100644 --- a/internal/e2e/fixtures/probe/probe.yaml.tmpl +++ b/internal/e2e/fixtures/probe/probe.yaml.tmpl @@ -32,7 +32,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: probe diff --git a/internal/e2e/fixtures/security/atespace-a-pool.yaml.tmpl b/internal/e2e/fixtures/security/atespace-a-pool.yaml.tmpl index 8b38267899..780d190677 100644 --- a/internal/e2e/fixtures/security/atespace-a-pool.yaml.tmpl +++ b/internal/e2e/fixtures/security/atespace-a-pool.yaml.tmpl @@ -37,7 +37,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: shared diff --git a/internal/e2e/fixtures/security/atespace-template.yaml.tmpl b/internal/e2e/fixtures/security/atespace-template.yaml.tmpl index 5dd69b2cd7..d6d6464605 100644 --- a/internal/e2e/fixtures/security/atespace-template.yaml.tmpl +++ b/internal/e2e/fixtures/security/atespace-template.yaml.tmpl @@ -13,7 +13,7 @@ # limitations under the License. # The ActorTemplate of the cross-atespace security fixture: a -# protojson-shaped ateapipb.ActorTemplate created through the ate API by +# protojson-shaped ateapi.ActorTemplate created through the ate API by # e2e.DeploySubstrateFixture. # # BOTH atespaces deploy this same file. They differ only in the ${FIXTURE_SUFFIX} diff --git a/internal/e2e/fixtures/testserver/grpcecho-template.yaml.tmpl b/internal/e2e/fixtures/testserver/grpcecho-template.yaml.tmpl index 4d6e94e1cb..717868e298 100644 --- a/internal/e2e/fixtures/testserver/grpcecho-template.yaml.tmpl +++ b/internal/e2e/fixtures/testserver/grpcecho-template.yaml.tmpl @@ -17,7 +17,7 @@ # One binary for both directions, so what counts as a working RPC cannot differ # between them. # -# A protojson-shaped ateapipb.ActorTemplate (NOT the ate.dev/v1alpha1 CRD), +# A protojson-shaped ateapi.ActorTemplate (NOT the ate.dev/v1 CRD), # created through the ate API by e2e.DeploySubstrateFixture. metadata: diff --git a/internal/e2e/fixtures/testserver/grpcecho.yaml.tmpl b/internal/e2e/fixtures/testserver/grpcecho.yaml.tmpl index 18b5de884e..68deb4e46f 100644 --- a/internal/e2e/fixtures/testserver/grpcecho.yaml.tmpl +++ b/internal/e2e/fixtures/testserver/grpcecho.yaml.tmpl @@ -28,7 +28,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: grpcecho diff --git a/internal/e2e/fixtures/testserver/websocket-template.yaml.tmpl b/internal/e2e/fixtures/testserver/websocket-template.yaml.tmpl index 2f0cd18b60..9663ed2f37 100644 --- a/internal/e2e/fixtures/testserver/websocket-template.yaml.tmpl +++ b/internal/e2e/fixtures/testserver/websocket-template.yaml.tmpl @@ -13,7 +13,7 @@ # limitations under the License. # The websocket fixture's ActorTemplate: a protojson-shaped -# ateapipb.ActorTemplate (NOT the ate.dev/v1alpha1 CRD), created through the +# ateapi.ActorTemplate (NOT the ate.dev/v1 CRD), created through the # ate API by e2e.DeploySubstrateFixture. metadata: diff --git a/internal/e2e/fixtures/testserver/websocket.yaml.tmpl b/internal/e2e/fixtures/testserver/websocket.yaml.tmpl index b5a716b983..7bf89ba7cd 100644 --- a/internal/e2e/fixtures/testserver/websocket.yaml.tmpl +++ b/internal/e2e/fixtures/testserver/websocket.yaml.tmpl @@ -23,7 +23,7 @@ metadata: --- -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: WorkerPool metadata: name: websocket diff --git a/internal/e2e/preflight.go b/internal/e2e/preflight.go index a3559eb2a7..62f7d04e21 100644 --- a/internal/e2e/preflight.go +++ b/internal/e2e/preflight.go @@ -21,7 +21,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) // PreflightChecks checks that the test environment is ready for the test suite. @@ -56,7 +56,7 @@ func PreflightChecks() error { listCtx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() - _, err = clients.SubstrateAPI.ListActors(listCtx, &ateapipb.ListActorsRequest{}) + _, err = clients.SubstrateAPI.ListActors(listCtx, &ateapi.ListActorsRequest{}) if err != nil { return fmt.Errorf("ListActors RPC failed: %v", err) } @@ -67,7 +67,7 @@ func PreflightChecks() error { // and any issues are to be reported at runtime. Which device a sandbox class // requires should not be checked here to prevent drift between platforms. if IsMicroVM() { - if _, err := clients.SubstrateK8s.ApiV1alpha1().SandboxConfigs().Get(ctx, SandboxClassMicroVM, metav1.GetOptions{}); err != nil { + if _, err := clients.SubstrateK8s.AteV1().SandboxConfigs().Get(ctx, SandboxClassMicroVM, metav1.GetOptions{}); err != nil { return fmt.Errorf("E2E_SANDBOX_CLASS=%s but SandboxConfig/%s is missing (see docs/dev/microvm-local.md for cluster setup): %w", SandboxClassMicroVM, SandboxClassMicroVM, err) } diff --git a/internal/e2e/probe.go b/internal/e2e/probe.go index fbd99e339a..256ba0ff7a 100644 --- a/internal/e2e/probe.go +++ b/internal/e2e/probe.go @@ -19,7 +19,7 @@ import ( "slices" "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) // ProbeName is the name of the probe fixture's WorkerPool and ActorTemplate, @@ -40,7 +40,7 @@ type probeConfig struct{ trustBundles []string } // The allowlisted names atelet resolves trust bundles by. const ( - egressTrustBundleName = "egress-mitm.ate.dev" + EgressTrustBundleName = "egress-mitm.ate.dev" systemRootsBundleName = "system-roots.ate.dev" ) @@ -51,7 +51,7 @@ const ( // includes the bundle won't start if the bundle is missing, so a suite that // just needs a probe shouldn't depend on it. func WithTrustBundle() ProbeOption { - return func(c *probeConfig) { c.trustBundles = append(c.trustBundles, egressTrustBundleName) } + return func(c *probeConfig) { c.trustBundles = append(c.trustBundles, EgressTrustBundleName) } } // WithSystemRoots adds the WebPKI roots atelet ships to the probe's projected @@ -68,14 +68,14 @@ func WithSystemRoots() ProbeOption { // out from under another running concurrently. It returns the fixture's // atespace (which also names the k8s namespace holding the pool) and the // created ActorTemplate, already golden-snapshotted. -func DeployProbe(t *testing.T, bucket, name string, opts ...ProbeOption) (string, *ateapipb.ActorTemplate) { +func DeployProbe(t *testing.T, bucket, name string, opts ...ProbeOption) (string, *ateapi.ActorTemplate) { t.Helper() var cfg probeConfig for _, opt := range opts { opt(&cfg) } - if slices.Contains(cfg.trustBundles, egressTrustBundleName) { + if slices.Contains(cfg.trustBundles, EgressTrustBundleName) { // Every actor from this template — the fixture's golden boot included — // fails closed while the bundle is missing, so it has to exist first. EnsureEgressTrustBundle(t, context.Background(), GetClients()) diff --git a/internal/e2e/probe_test.go b/internal/e2e/probe_test.go index 66468bcf2d..a610e1f37e 100644 --- a/internal/e2e/probe_test.go +++ b/internal/e2e/probe_test.go @@ -20,7 +20,7 @@ import ( "strings" "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) // TestProbeTemplate_TrustBundle checks that the probe template projects @@ -55,7 +55,7 @@ func TestProbeTemplate_TrustBundle(t *testing.T) { t.Fatalf("probe template manifest yields %d documents, want 1", len(templates)) } - var sources []*ateapipb.TrustBundleDataSource + var sources []*ateapi.TrustBundleDataSource for _, vol := range templates[0].GetVolumes() { for _, ds := range vol.GetSystemInfo().GetDataSources() { if ds.GetTrustBundle() != nil { @@ -82,7 +82,7 @@ func TestProbeTemplate_TrustBundle(t *testing.T) { } // The egress name must select the bundle atecontroller publishes, or // actors fail closed on a name atelet rejects. - if !strings.HasPrefix(EgressTrustBundleObjectName, egressTrustBundleName+":") { - t.Errorf("egress trust bundle name %q does not select %q", egressTrustBundleName, EgressTrustBundleObjectName) + if !strings.HasPrefix(EgressTrustBundleObjectName, EgressTrustBundleName+":") { + t.Errorf("egress trust bundle name %q does not select %q", EgressTrustBundleName, EgressTrustBundleObjectName) } } diff --git a/internal/e2e/resume.go b/internal/e2e/resume.go index c753e4b830..dadd1b1ad9 100644 --- a/internal/e2e/resume.go +++ b/internal/e2e/resume.go @@ -19,7 +19,7 @@ import ( "testing" "time" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -45,7 +45,7 @@ const resumeCapacityWait = 90 * time.Second // constants under cmd/*/internal with different names, plus literals in three // binaries. This label should be unified under internal/ first, rather than // adding another copy here. -func ResumeActorAwaitCapacity(t *testing.T, ctx context.Context, clients *Clients, req *ateapipb.ResumeActorRequest) (*ateapipb.ResumeActorResponse, error) { +func ResumeActorAwaitCapacity(t *testing.T, ctx context.Context, clients *Clients, req *ateapi.ResumeActorRequest) (*ateapi.ResumeActorResponse, error) { t.Helper() deadline := time.Now().Add(resumeCapacityWait) for { diff --git a/internal/e2e/router_client.go b/internal/e2e/router_client.go index 8afba84cc1..460db84990 100644 --- a/internal/e2e/router_client.go +++ b/internal/e2e/router_client.go @@ -26,7 +26,6 @@ import ( "net/url" "strconv" "strings" - "sync" "testing" "time" @@ -61,16 +60,10 @@ type RouterClient struct { stop func() tlsConfig *tls.Config - // config/clientset are retained to lazily open a second port-forward, to - // routerConnectTLSServicePort, only if Connect is ever called -- most - // callers never CONNECT, so the HTTPS one from NewRouterClient covers them. + // config/clientset are retained to open a port-forward to + // routerConnectTLSServicePort per Connect. config *rest.Config clientset kubernetes.Interface - - connectOnce sync.Once - connectAddr string - connectStop func() - connectErr error } // NewRouterClient establishes a port-forward to the ingress atenet-router. Call Close @@ -111,12 +104,9 @@ func NewRouterClient(t *testing.T, ctx context.Context) (*RouterClient, error) { }, nil } -// Close stops the port-forward tunnel(s). +// Close stops the port-forward. func (c *RouterClient) Close() { c.stop() - if c.connectStop != nil { - c.connectStop() - } } // BaseURL returns the local router port-forward address as an https:// URL. @@ -130,14 +120,15 @@ func (c *RouterClient) Address() string { return c.address } -// ConnectAddress returns the host:port of the local port-forward to the -// router's CONNECT listener, opening it on first use, for a caller that has to -// control the protocol it speaks to the router itself. -func (c *RouterClient) ConnectAddress(ctx context.Context) (string, error) { - if err := c.ensureConnectPortForward(ctx); err != nil { - return "", err +// ConnectPortForward opens a new port-forward to the router's CONNECT listener +// and returns its local host:port, for a caller that has to control the +// protocol it speaks to the router itself. The caller must call stop. +func (c *RouterClient) ConnectPortForward(ctx context.Context) (addr string, stop func(), err error) { + localPort, stop, err := portforward.ServicePortForward(ctx, c.config, c.clientset, SystemNamespace(), ResourceName("atenet-router"), routerConnectTLSServicePort) + if err != nil { + return "", nil, fmt.Errorf("port-forwarding to the router's CONNECT listener: %w", err) } - return c.connectAddr, nil + return fmt.Sprintf("127.0.0.1:%d", localPort), stop, nil } // TLSConfig returns a copy of the TLS config the client dials the router @@ -186,7 +177,7 @@ func (c *RouterClient) DoReq(req *http.Request) (*http.Response, error) { // non-2xx response the returned error carries the status and body, mirroring // egress.Client.DialContext's handling of the same failure mode on the // egress side. The caller owns the returned connection and must Close it; -// the underlying port-forward is torn down by RouterClient.Close. +// closing it also tears down its port-forward. func (c *RouterClient) Connect(ctx context.Context, actorRef resources.ActorRef, port int) (net.Conn, error) { return c.ConnectWithHeaders(ctx, actorRef, port, http.Header{ atenet.TargetActorHeader: []string{actorRef.String()}, @@ -196,11 +187,23 @@ func (c *RouterClient) Connect(ctx context.Context, actorRef resources.ActorRef, // ConnectWithHeaders is like Connect but allows specifying custom headers on // the outer CONNECT request (e.g. testing repeated or missing headers). func (c *RouterClient) ConnectWithHeaders(ctx context.Context, actorRef resources.ActorRef, port int, header http.Header) (net.Conn, error) { - if err := c.ensureConnectPortForward(ctx); err != nil { + // client-go tears down a whole port-forward when any one of its + // connections errors, so each tunnel gets its own + addr, stop, err := c.ConnectPortForward(ctx) + if err != nil { return nil, err } + conn, err := c.connect(ctx, addr, actorRef, port, header) + if err != nil { + stop() + return nil, err + } + conn.stop = stop + return conn, nil +} - tcpConn, err := (&net.Dialer{}).DialContext(ctx, "tcp", c.connectAddr) +func (c *RouterClient) connect(ctx context.Context, addr string, actorRef resources.ActorRef, port int, header http.Header) (*bufferedConn, error) { + tcpConn, err := (&net.Dialer{}).DialContext(ctx, "tcp", addr) if err != nil { return nil, fmt.Errorf("connecting to router's CONNECT listener: %w", err) } @@ -245,30 +248,24 @@ func (c *RouterClient) ConnectWithHeaders(ctx context.Context, actorRef resource return &bufferedConn{Conn: rawConn, reader: reader}, nil } -// ensureConnectPortForward opens the CONNECT-listener port-forward on first -// use, memoizing the result (including any error) so repeated Connect calls -// in one test don't each pay for a fresh port-forward. -func (c *RouterClient) ensureConnectPortForward(ctx context.Context) error { - c.connectOnce.Do(func() { - localPort, stop, err := portforward.ServicePortForward(ctx, c.config, c.clientset, SystemNamespace(), ResourceName("atenet-router"), routerConnectTLSServicePort) - if err != nil { - c.connectErr = fmt.Errorf("port-forwarding to the router's CONNECT listener: %w", err) - return - } - c.connectAddr = fmt.Sprintf("127.0.0.1:%d", localPort) - c.connectStop = stop - }) - return c.connectErr -} - // bufferedConn recovers bytes http.ReadResponse buffered past the header // boundary, mirroring internal/atunnel/egress/client.go's identical need on the // egress CONNECT client. type bufferedConn struct { net.Conn reader *bufio.Reader + stop func() } func (c *bufferedConn) Read(p []byte) (int, error) { return c.reader.Read(p) } + +func (c *bufferedConn) Close() error { + err := c.Conn.Close() + if c.stop != nil { + c.stop() + c.stop = nil + } + return err +} diff --git a/internal/e2e/router_client_test.go b/internal/e2e/router_client_test.go index 0341cac06f..c8c8753759 100644 --- a/internal/e2e/router_client_test.go +++ b/internal/e2e/router_client_test.go @@ -122,16 +122,17 @@ func TestRouterClientConnectTLS(t *testing.T) { ServerName: "example.com", } tlsConfig.RootCAs.AddCert(server.Certificate()) - client := &RouterClient{tlsConfig: tlsConfig, connectAddr: server.Listener.Addr().String()} - client.connectOnce.Do(func() {}) + client := &RouterClient{tlsConfig: tlsConfig} - conn, err := client.Connect(context.Background(), resources.ActorRef{Atespace: "demo", Name: "fetcher"}, 9090) + conn, err := client.connect(context.Background(), server.Listener.Addr().String(), resources.ActorRef{Atespace: "demo", Name: "fetcher"}, 9090, http.Header{ + atenet.TargetActorHeader: []string{"demo/fetcher"}, + }) if err != nil { - t.Fatalf("Connect: %v", err) + t.Fatalf("connect: %v", err) } defer conn.Close() - if _, ok := conn.(*bufferedConn).Conn.(*tls.Conn); !ok { - t.Errorf("Connect returned a %T tunnel, want one over TLS", conn.(*bufferedConn).Conn) + if _, ok := conn.Conn.(*tls.Conn); !ok { + t.Errorf("connect returned a %T tunnel, want one over TLS", conn.Conn) } got, err := io.ReadAll(conn) if err != nil { diff --git a/internal/e2e/sandbox_test.go b/internal/e2e/sandbox_test.go index 862d6a4ce2..423c4618e4 100644 --- a/internal/e2e/sandbox_test.go +++ b/internal/e2e/sandbox_test.go @@ -15,47 +15,58 @@ package e2e import ( + "bytes" + "maps" "os" "strings" "testing" - "go.ate.dev/substrate/pkg/api/v1alpha1" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "sigs.k8s.io/yaml" ) // substrateFixtures are every fixture DeploySubstrateFixture is asked to // deploy: the pool half rendered by RenderFixtureManifest and the substrate // ActorTemplate half rendered with substrateTemplateSubstitutions, plus how -// many template documents the latter must yield. +// many template documents the latter must yield. values fills the template's +// own placeholders, as the suite deploying it does through WithTemplateValue. var substrateFixtures = []struct { manifests SubstrateFixtureManifests templates int + values map[string]string }{ {SubstrateFixtureManifests{ Pool: "internal/e2e/fixtures/probe/probe.yaml.tmpl", Template: "internal/e2e/fixtures/probe/probe-template.yaml.tmpl", - }, 1}, + }, 1, nil}, + {SubstrateFixtureManifests{ + Pool: "internal/e2e/fixtures/probe/probe.yaml.tmpl", + Template: "internal/e2e/fixtures/probe/probe-bootfetch-template.yaml.tmpl", + }, 1, map[string]string{ + "${BOOT_FETCH_HOST}": "origin.example", + "${BOOT_FETCH_URL}": "https://origin.example/healthz", + }}, {SubstrateFixtureManifests{ Pool: "internal/e2e/fixtures/probe/probe-sized.yaml.tmpl", Template: "internal/e2e/fixtures/probe/probe-sized-template.yaml.tmpl", - }, 1}, + }, 1, nil}, {SubstrateFixtureManifests{ Pool: "internal/e2e/fixtures/security/atespace-a-pool.yaml.tmpl", Template: "internal/e2e/fixtures/security/atespace-template.yaml.tmpl", - }, 1}, + }, 1, nil}, {SubstrateFixtureManifests{ Pool: "internal/e2e/fixtures/capabilities/capabilities.yaml.tmpl", Template: "internal/e2e/fixtures/capabilities/capabilities-templates.yaml.tmpl", - }, 2}, + }, 2, nil}, {SubstrateFixtureManifests{ Pool: "internal/e2e/fixtures/testserver/websocket.yaml.tmpl", Template: "internal/e2e/fixtures/testserver/websocket-template.yaml.tmpl", - }, 1}, + }, 1, nil}, {SubstrateFixtureManifests{ Pool: "internal/e2e/fixtures/testserver/grpcecho.yaml.tmpl", Template: "internal/e2e/fixtures/testserver/grpcecho-template.yaml.tmpl", - }, 1}, + }, 1, nil}, } // renderPool renders a fixture's pool manifest and strict-decodes its @@ -66,14 +77,14 @@ var substrateFixtures = []struct { // depth yields YAML that still parses but hangs the field off the wrong parent // — which strict mode reports as an unknown field instead of silently applying // a WorkerPool that never gets a micro-VM worker. -func renderPool(t *testing.T, relPath string) *v1alpha1.WorkerPool { +func renderPool(t *testing.T, relPath string) *atev1.WorkerPool { t.Helper() raw, err := os.ReadFile(RenderFixtureManifest(t, relPath, "test-bucket", "render")) if err != nil { t.Fatalf("reading the rendered %s: %v", relPath, err) } - pool := &v1alpha1.WorkerPool{} + pool := &atev1.WorkerPool{} for doc := range strings.SplitSeq(string(raw), "\n---\n") { if strings.TrimSpace(doc) == "" { continue @@ -99,14 +110,21 @@ func renderPool(t *testing.T, relPath string) *v1alpha1.WorkerPool { // renderTemplates renders a fixture's substrate template manifest and // strict-decodes its ActorTemplate documents; the protojson decode plays the -// same misplaced-placeholder tripwire renderPool's strict mode does. -func renderTemplates(t *testing.T, relPath string) []*ateapipb.ActorTemplate { +// same misplaced-placeholder tripwire renderPool's strict mode does. A +// placeholder that values does not fill fails the test, since it would reach +// the cluster as literal text. +func renderTemplates(t *testing.T, relPath string, values map[string]string) []*ateapi.ActorTemplate { t.Helper() inline, blocks := substrateTemplateSubstitutions("test-bucket", "render", nil) + maps.Copy(inline, values) rendered, err := os.ReadFile(renderManifest(t, relPath, inline, blocks)) if err != nil { t.Fatalf("reading the rendered %s: %v", relPath, err) } + if i := bytes.Index(rendered, []byte("${")); i >= 0 { + end := min(len(rendered), i+40) + t.Fatalf("rendered %s keeps a placeholder: %q", relPath, rendered[i:end]) + } return decodeSubstrateTemplates(t, rendered) } @@ -121,11 +139,11 @@ func TestRenderSubstrateFixtures_GVisor(t *testing.T) { if !strings.HasSuffix(pool.Spec.WorkerImage, "/cmd/ateworker-gvisor") { t.Errorf("WorkerPool workerImage = %q, want the gVisor worker", pool.Spec.WorkerImage) } - if pool.Spec.DefaultSandboxClass() != v1alpha1.SandboxClassGvisor { + if pool.Spec.DefaultSandboxClass() != atev1.SandboxClassGvisor { t.Errorf("WorkerPool runtime = class %q, want gvisor", pool.Spec.DefaultSandboxClass()) } - templates := renderTemplates(t, fixture.manifests.Template) + templates := renderTemplates(t, fixture.manifests.Template, fixture.values) if len(templates) != fixture.templates { t.Fatalf("rendered %s yields %d templates, want %d", fixture.manifests.Template, len(templates), fixture.templates) } @@ -165,7 +183,7 @@ func TestRenderSubstrateFixtures_MicroVM(t *testing.T) { t.Errorf("WorkerPool runtime = class %q, want microvm", pool.Spec.DefaultSandboxClass()) } - templates := renderTemplates(t, fixture.manifests.Template) + templates := renderTemplates(t, fixture.manifests.Template, fixture.values) if len(templates) != fixture.templates { t.Fatalf("rendered %s yields %d templates, want %d", fixture.manifests.Template, len(templates), fixture.templates) } diff --git a/internal/e2e/suites/authz/flow_test.go b/internal/e2e/suites/authz/flow_test.go index 891879abb1..11dc1d10ec 100644 --- a/internal/e2e/suites/authz/flow_test.go +++ b/internal/e2e/suites/authz/flow_test.go @@ -18,8 +18,8 @@ import ( "context" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/e2e" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // testBasicFlow runs an actor's whole lifecycle as users granted access @@ -41,20 +41,20 @@ func testBasicFlow(t *testing.T, ctx context.Context, f *fixture) { return } - actor := &ateapipb.ObjectRef{Atespace: f.atespace, Name: "flow-actor"} - if _, err := alice.api.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actor.GetAtespace(), Name: actor.GetName()}, + actor := &ateapi.ObjectRef{Atespace: f.atespace, Name: "flow-actor"} + if _, err := alice.api.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actor.GetAtespace(), Name: actor.GetName()}, ActorTemplate: f.template, }}); err != nil { t.Fatalf("CreateActor as alice: %v", err) } t.Cleanup(func() { // Best effort, in case a step below failed partway. - _, _ = f.clients.SubstrateAPI.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: actor}) - _, _ = f.clients.SubstrateAPI.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{Actor: actor}) + _, _ = f.clients.SubstrateAPI.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: actor}) + _, _ = f.clients.SubstrateAPI.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{Actor: actor}) }) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, &e2e.Clients{SubstrateAPI: alice.api}, &ateapipb.ResumeActorRequest{Actor: actor}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, &e2e.Clients{SubstrateAPI: alice.api}, &ateapi.ResumeActorRequest{Actor: actor}); err != nil { t.Fatalf("ResumeActor as alice: %v", err) } @@ -68,11 +68,11 @@ func testBasicFlow(t *testing.T, ctx context.Context, f *fixture) { return } - if _, err := alice.api.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actor}); err != nil { + if _, err := alice.api.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actor}); err != nil { t.Fatalf("SuspendActor as alice: %v", err) } - waitForActorState(t, ctx, f.clients, actor, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) - if _, err := alice.api.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: actor}); err != nil { + waitForActorState(t, ctx, f.clients, actor, ateapi.ActorState_ACTOR_STATE_SUSPENDED) + if _, err := alice.api.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: actor}); err != nil { t.Fatalf("DeleteActor as alice: %v", err) } } diff --git a/internal/e2e/suites/authz/helpers_test.go b/internal/e2e/suites/authz/helpers_test.go index cad437f5a0..f7d3137d28 100644 --- a/internal/e2e/suites/authz/helpers_test.go +++ b/internal/e2e/suites/authz/helpers_test.go @@ -29,11 +29,11 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateclient" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/installdefaults" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const ( @@ -49,8 +49,8 @@ type fixture struct { clients *e2e.Clients bootstrap *principal atespace string - template *ateapipb.ObjectRef - actor *ateapipb.ObjectRef + template *ateapi.ObjectRef + actor *ateapi.ObjectRef } // outcome is the set of status codes a call may return to pass. @@ -199,8 +199,8 @@ func serviceAccountExists(t *testing.T, ctx context.Context, clients *e2e.Client return true } -func binding(role string, ps ...*principal) *ateapipb.Binding { - b := &ateapipb.Binding{Role: role} +func binding(role string, ps ...*principal) *ateapi.Binding { + b := &ateapi.Binding{Role: role} for _, p := range ps { b.Members = append(b.Members, p.member) } @@ -210,17 +210,17 @@ func binding(role string, ps ...*principal) *ateapipb.Binding { // setAtespacePolicy replaces atespace's AccessPolicy bindings, creating the // policy if it doesn't exist yet. The caller deletes it, with // cleanupAtespacePolicy at the scope the policy must last for. -func setAtespacePolicy(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace string, bindings ...*ateapipb.Binding) { +func setAtespacePolicy(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace string, bindings ...*ateapi.Binding) { t.Helper() - ref := &ateapipb.ObjectRef{Name: atespace} - policy := &ateapipb.AccessPolicy{Metadata: &ateapipb.ResourceMetadata{Name: resources.SingletonName}, Bindings: bindings} - current, err := clients.SubstrateAPI.GetAtespaceAccessPolicy(ctx, &ateapipb.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) + ref := &ateapi.ObjectRef{Name: atespace} + policy := &ateapi.AccessPolicy{Metadata: &ateapi.ResourceMetadata{Name: resources.SingletonName}, Bindings: bindings} + current, err := clients.SubstrateAPI.GetAtespaceAccessPolicy(ctx, &ateapi.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) switch { case status.Code(err) == codes.NotFound: - _, err = clients.SubstrateAPI.CreateAtespaceAccessPolicy(ctx, &ateapipb.CreateAtespaceAccessPolicyRequest{Atespace: ref, AccessPolicy: policy}) + _, err = clients.SubstrateAPI.CreateAtespaceAccessPolicy(ctx, &ateapi.CreateAtespaceAccessPolicyRequest{Atespace: ref, AccessPolicy: policy}) case err == nil: policy.Metadata = current.GetMetadata() - _, err = clients.SubstrateAPI.UpdateAtespaceAccessPolicy(ctx, &ateapipb.UpdateAtespaceAccessPolicyRequest{Atespace: ref, AccessPolicy: policy}) + _, err = clients.SubstrateAPI.UpdateAtespaceAccessPolicy(ctx, &ateapi.UpdateAtespaceAccessPolicyRequest{Atespace: ref, AccessPolicy: policy}) } if err != nil { t.Fatalf("setting the AccessPolicy of atespace %q: %v", atespace, err) @@ -239,8 +239,8 @@ func cleanupAtespacePolicy(t *testing.T, clients *e2e.Clients, atespace string) // deleteAtespacePolicy deletes atespace's AccessPolicy; one already gone is // not an error. func deleteAtespacePolicy(ctx context.Context, clients *e2e.Clients, atespace string) error { - _, err := clients.SubstrateAPI.DeleteAtespaceAccessPolicy(ctx, &ateapipb.DeleteAtespaceAccessPolicyRequest{ - Atespace: &ateapipb.ObjectRef{Name: atespace}, + _, err := clients.SubstrateAPI.DeleteAtespaceAccessPolicy(ctx, &ateapi.DeleteAtespaceAccessPolicyRequest{ + Atespace: &ateapi.ObjectRef{Name: atespace}, Name: resources.SingletonName, }) if status.Code(err) == codes.NotFound { @@ -253,8 +253,8 @@ func deleteAtespacePolicy(ctx context.Context, clients *e2e.Clients, atespace st // it when t ends. Deleting it also deletes its AccessPolicy. func createAtespace(t *testing.T, ctx context.Context, clients *e2e.Clients, name string) { t.Helper() - if _, err := clients.SubstrateAPI.CreateAtespace(ctx, &ateapipb.CreateAtespaceRequest{ - Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: name}}, + if _, err := clients.SubstrateAPI.CreateAtespace(ctx, &ateapi.CreateAtespaceRequest{ + Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: name}}, }); err != nil { t.Fatalf("CreateAtespace %q: %v", name, err) } @@ -267,7 +267,7 @@ func createAtespace(t *testing.T, ctx context.Context, clients *e2e.Clients, nam // deleteAtespace deletes an atespace; one already gone is not an error. func deleteAtespace(ctx context.Context, clients *e2e.Clients, name string) error { - _, err := clients.SubstrateAPI.DeleteAtespace(ctx, &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: name}}) + _, err := clients.SubstrateAPI.DeleteAtespace(ctx, &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: name}}) if status.Code(err) == codes.NotFound { return nil } @@ -281,16 +281,16 @@ func deployFixture(t *testing.T, ctx context.Context, bucket string) *fixture { t.Helper() clients := e2e.GetClients() atespace, _ := e2e.DeployProbe(t, bucket, "authz") - actor := &ateapipb.ObjectRef{Atespace: atespace, Name: actorName} - template := &ateapipb.ObjectRef{Atespace: atespace, Name: e2e.ProbeName} - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: actorName}, + actor := &ateapi.ObjectRef{Atespace: atespace, Name: actorName} + template := &ateapi.ObjectRef{Atespace: atespace, Name: e2e.ProbeName} + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: actorName}, ActorTemplate: template, }}); err != nil { t.Fatalf("CreateActor %s/%s: %v", atespace, actorName, err) } t.Cleanup(func() { - if _, err := clients.SubstrateAPI.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{Actor: actor}); err != nil { + if _, err := clients.SubstrateAPI.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{Actor: actor}); err != nil { t.Logf("cleanup: DeleteActor %s/%s: %v", atespace, actorName, err) } }) @@ -304,11 +304,11 @@ func deployFixture(t *testing.T, ctx context.Context, bucket string) *fixture { } // waitForActorState polls actor, as the bootstrap owner, until it is in want. -func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, actor *ateapipb.ObjectRef, want ateapipb.ActorState) { +func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, actor *ateapi.ObjectRef, want ateapi.ActorState) { t.Helper() deadline := time.Now().Add(60 * time.Second) for time.Now().Before(deadline) { - resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actor}) + resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{Actor: actor}) if err == nil && resp.GetStatus().GetState() == want { return } @@ -322,28 +322,28 @@ func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, func getAtespace(name string) rpc { return func(ctx context.Context, api *ateclient.Client) error { - _, err := api.GetAtespace(ctx, &ateapipb.GetAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: name}}) + _, err := api.GetAtespace(ctx, &ateapi.GetAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: name}}) return err } } -func getActor(ref *ateapipb.ObjectRef) rpc { +func getActor(ref *ateapi.ObjectRef) rpc { return func(ctx context.Context, api *ateclient.Client) error { - _, err := api.GetActor(ctx, &ateapipb.GetActorRequest{Actor: ref}) + _, err := api.GetActor(ctx, &ateapi.GetActorRequest{Actor: ref}) return err } } func listActors(atespace string) rpc { return func(ctx context.Context, api *ateclient.Client) error { - _, err := api.ListActors(ctx, &ateapipb.ListActorsRequest{Atespace: atespace}) + _, err := api.ListActors(ctx, &ateapi.ListActorsRequest{Atespace: atespace}) return err } } -func suspendActor(ref *ateapipb.ObjectRef) rpc { +func suspendActor(ref *ateapi.ObjectRef) rpc { return func(ctx context.Context, api *ateclient.Client) error { - _, err := api.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: ref}) + _, err := api.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref}) return err } } @@ -351,10 +351,10 @@ func suspendActor(ref *ateapipb.ObjectRef) rpc { // createActorUnnamed asks for an actor with no name: the check reads only // its atespace and template, and validation then rejects it, so nothing is // created. -func createActorUnnamed(atespace string, template *ateapipb.ObjectRef) rpc { +func createActorUnnamed(atespace string, template *ateapi.ObjectRef) rpc { return func(ctx context.Context, api *ateclient.Client) error { - _, err := api.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace}, + _, err := api.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace}, ActorTemplate: template, }}) return err diff --git a/internal/e2e/suites/authz/security_regression_test.go b/internal/e2e/suites/authz/security_regression_test.go index 31b0e420ee..633ae5b8a6 100644 --- a/internal/e2e/suites/authz/security_regression_test.go +++ b/internal/e2e/suites/authz/security_regression_test.go @@ -21,11 +21,11 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateclient" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/installdefaults" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // testSecurityRegression checks one case per threat, each in a subtest @@ -86,23 +86,23 @@ func testTenantCrossing(t *testing.T, ctx context.Context, f *fixture) { func testPrivilegeEscalation(t *testing.T, ctx context.Context, f *fixture) { owner := newPrincipal(t, ctx, f.clients, f.atespace, "escalate-owner") editor := newPrincipal(t, ctx, f.clients, f.atespace, "escalate-editor") - current := []*ateapipb.Binding{binding("owner", owner), binding("editor", editor)} + current := []*ateapi.Binding{binding("owner", owner), binding("editor", editor)} setAtespacePolicy(t, ctx, f.clients, f.atespace, current...) cleanupAtespacePolicy(t, f.clients, f.atespace) // updatePolicy rewrites the policy's bindings, guarded by the uid and // version the bootstrap owner reads just before, so the update is // otherwise valid. - ref := &ateapipb.ObjectRef{Name: f.atespace} - updatePolicy := func(bindings ...*ateapipb.Binding) rpc { + ref := &ateapi.ObjectRef{Name: f.atespace} + updatePolicy := func(bindings ...*ateapi.Binding) rpc { return func(ctx context.Context, api *ateclient.Client) error { - cur, err := f.clients.SubstrateAPI.GetAtespaceAccessPolicy(ctx, &ateapipb.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) + cur, err := f.clients.SubstrateAPI.GetAtespaceAccessPolicy(ctx, &ateapi.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) if err != nil { return err } - _, err = api.UpdateAtespaceAccessPolicy(ctx, &ateapipb.UpdateAtespaceAccessPolicyRequest{ + _, err = api.UpdateAtespaceAccessPolicy(ctx, &ateapi.UpdateAtespaceAccessPolicyRequest{ Atespace: ref, - AccessPolicy: &ateapipb.AccessPolicy{Metadata: cur.GetMetadata(), Bindings: bindings}, + AccessPolicy: &ateapi.AccessPolicy{Metadata: cur.GetMetadata(), Bindings: bindings}, }) return err } @@ -230,17 +230,17 @@ func testAccessPolicyRecreated(t *testing.T, ctx context.Context, f *fixture) { return } - ref := &ateapipb.ObjectRef{Name: f.atespace} - old, err := f.clients.SubstrateAPI.GetAtespaceAccessPolicy(ctx, &ateapipb.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) + ref := &ateapi.ObjectRef{Name: f.atespace} + old, err := f.clients.SubstrateAPI.GetAtespaceAccessPolicy(ctx, &ateapi.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) if err != nil { t.Fatalf("GetAtespaceAccessPolicy: %v", err) } if err := deleteAtespacePolicy(ctx, f.clients, f.atespace); err != nil { t.Fatalf("DeleteAtespaceAccessPolicy: %v", err) } - if _, err := f.clients.SubstrateAPI.CreateAtespaceAccessPolicy(ctx, &ateapipb.CreateAtespaceAccessPolicyRequest{ + if _, err := f.clients.SubstrateAPI.CreateAtespaceAccessPolicy(ctx, &ateapi.CreateAtespaceAccessPolicyRequest{ Atespace: ref, - AccessPolicy: &ateapipb.AccessPolicy{Metadata: &ateapipb.ResourceMetadata{Name: resources.SingletonName}}, + AccessPolicy: &ateapi.AccessPolicy{Metadata: &ateapi.ResourceMetadata{Name: resources.SingletonName}}, }); err != nil { t.Fatalf("CreateAtespaceAccessPolicy: %v", err) } @@ -250,14 +250,14 @@ func testAccessPolicyRecreated(t *testing.T, ctx context.Context, f *fixture) { // An update guarded by the old policy's uid and version must not apply // to the new one. - _, err = f.clients.SubstrateAPI.UpdateAtespaceAccessPolicy(ctx, &ateapipb.UpdateAtespaceAccessPolicyRequest{ + _, err = f.clients.SubstrateAPI.UpdateAtespaceAccessPolicy(ctx, &ateapi.UpdateAtespaceAccessPolicyRequest{ Atespace: ref, - AccessPolicy: &ateapipb.AccessPolicy{Metadata: old.GetMetadata(), Bindings: []*ateapipb.Binding{binding("owner", gina)}}, + AccessPolicy: &ateapi.AccessPolicy{Metadata: old.GetMetadata(), Bindings: []*ateapi.Binding{binding("owner", gina)}}, }) if status.Code(err) != codes.Aborted { t.Errorf("UpdateAtespaceAccessPolicy with the deleted policy's uid: got %v, want %v", err, codes.Aborted) } - cur, err := f.clients.SubstrateAPI.GetAtespaceAccessPolicy(ctx, &ateapipb.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) + cur, err := f.clients.SubstrateAPI.GetAtespaceAccessPolicy(ctx, &ateapi.GetAtespaceAccessPolicyRequest{Atespace: ref, Name: resources.SingletonName}) if err != nil { t.Fatalf("GetAtespaceAccessPolicy: %v", err) } @@ -283,20 +283,20 @@ func testWorkerServiceRequiresAtelet(t *testing.T, ctx context.Context, f *fixtu // The worker named is never created: a handler that let the caller // through would answer NotFound, not reject it. - worker := &ateapipb.ObjectRef{Name: "authz-missing"} + worker := &ateapi.ObjectRef{Name: "authz-missing"} registerWorker := func(ctx context.Context, api *ateclient.Client) error { - _, err := api.WorkerService().RegisterWorker(ctx, &ateapipb.RegisterWorkerRequest{Worker: worker}) + _, err := api.WorkerService().RegisterWorker(ctx, &ateapi.RegisterWorkerRequest{Worker: worker}) return err } requestSuspend := func(ctx context.Context, api *ateclient.Client) error { - _, err := api.WorkerService().RequestActorSuspend(ctx, &ateapipb.RequestActorSuspendRequest{Worker: worker, Actor: f.actor}) + _, err := api.WorkerService().RequestActorSuspend(ctx, &ateapi.RequestActorSuspendRequest{Worker: worker, Actor: f.actor}) return err } // This handler validates the request before authenticating the caller, // so the request must be valid. The CSR is parsed only after // authentication, so it needn't be a real one. mintWorkerCert := func(ctx context.Context, api *ateclient.Client) error { - _, err := api.WorkerService().MintWorkerActorCertificate(ctx, &ateapipb.MintWorkerActorCertificateRequest{ + _, err := api.WorkerService().MintWorkerActorCertificate(ctx, &ateapi.MintWorkerActorCertificateRequest{ Worker: worker, Actor: f.actor, ActorUid: "00000000-0000-4000-8000-000000000000", @@ -307,7 +307,7 @@ func testWorkerServiceRequiresAtelet(t *testing.T, ctx context.Context, f *fixtu // This handler also validates the request before authenticating the // caller, so the request must be valid. mintWorkerJWT := func(ctx context.Context, api *ateclient.Client) error { - _, err := api.WorkerService().MintWorkerActorJwt(ctx, &ateapipb.MintWorkerActorJwtRequest{ + _, err := api.WorkerService().MintWorkerActorJwt(ctx, &ateapi.MintWorkerActorJwtRequest{ Actor: f.actor, ActorUid: "00000000-0000-4000-8000-000000000000", Audiences: []string{"authz-e2e"}, @@ -315,10 +315,10 @@ func testWorkerServiceRequiresAtelet(t *testing.T, ctx context.Context, f *fixtu return err } reportSnapshotState := func(ctx context.Context, api *ateclient.Client) error { - _, err := api.WorkerService().ReportActorSnapshotState(ctx, &ateapipb.ReportActorSnapshotStateRequest{ + _, err := api.WorkerService().ReportActorSnapshotState(ctx, &ateapi.ReportActorSnapshotStateRequest{ Actor: f.actor, ActorUid: "00000000-0000-4000-8000-000000000000", - State: &ateapipb.ActorSnapshotState{}, + State: &ateapi.ActorSnapshotState{}, }) return err } diff --git a/internal/e2e/suites/capabilities/capabilities_test.go b/internal/e2e/suites/capabilities/capabilities_test.go index 525e734de5..11b32bcbd6 100644 --- a/internal/e2e/suites/capabilities/capabilities_test.go +++ b/internal/e2e/suites/capabilities/capabilities_test.go @@ -22,9 +22,9 @@ import ( "slices" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // defaultCapabilities mirrors atelet's default set (cmd/atelet/oci.go). It is @@ -144,20 +144,20 @@ func deployFixture(t *testing.T, ctx context.Context, clients *e2e.Clients, buck func createAndResumeActor(t *testing.T, ctx context.Context, clients *e2e.Clients, namespace, template, id string) { t.Helper() - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: namespace, Name: id}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: namespace, Name: template}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: namespace, Name: id}, + ActorTemplate: &ateapi.ObjectRef{Atespace: namespace, Name: template}, }}); err != nil { t.Fatalf("CreateActor %q: %v", id, err) } t.Cleanup(func() { // DeleteActor requires the actor to be suspended. - _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: &ateapipb.ObjectRef{Atespace: namespace, Name: id}}) - _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: &ateapipb.ObjectRef{Atespace: namespace, Name: id}}) + _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: &ateapi.ObjectRef{Atespace: namespace, Name: id}}) + _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: &ateapi.ObjectRef{Atespace: namespace, Name: id}}) }) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: namespace, Name: id}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: namespace, Name: id}, }); err != nil { t.Fatalf("ResumeActor %q: %v", id, err) } diff --git a/internal/e2e/suites/combinedvolumes/combinedvolumes_test.go b/internal/e2e/suites/combinedvolumes/combinedvolumes_test.go index 07ba9bb5dc..3c37ea65e5 100644 --- a/internal/e2e/suites/combinedvolumes/combinedvolumes_test.go +++ b/internal/e2e/suites/combinedvolumes/combinedvolumes_test.go @@ -37,10 +37,10 @@ import ( "github.com/google/go-containerregistry/pkg/v1/mutate" "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/google/go-containerregistry/pkg/v1/tarball" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -179,7 +179,7 @@ func storageClassOrEmpty(ctx context.Context, t *testing.T, clients *e2e.Clients // The template's name is suffixed per test run: it lives in the suite's // shared atespace, which outlives the per-test k8s namespace. A non-empty // storageClass adds the external volume. -func createTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients, ns *e2e.Namespace, fixtureImage, storageClass string) *ateapipb.ActorTemplate { +func createTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients, ns *e2e.Namespace, fixtureImage, storageClass string) *ateapi.ActorTemplate { t.Helper() env, err := e2e.CheckEnv("BUCKET_NAME") @@ -205,36 +205,36 @@ func createTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients, ns // The pool is labeled uniquely to this namespace so the cluster-wide // scheduler cannot hand its workers to another suite's actors. Labels: map[string]string{"combinedvolumes": ns.Name}, - SnapshotConfig: &ateapipb.SnapshotConfig{ + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: fmt.Sprintf("gs://%s/%s/", env["BUCKET_NAME"], ns.Name), }, - Modify: func(tmpl *ateapipb.ActorTemplate) { + Modify: func(tmpl *ateapi.ActorTemplate) { // Every volume is mounted at two paths, covering the read-only // (image), writable (durable-dir) and per-actor provisioned // (external) multi-path cases. tmpl.Containers[0].VolumeMounts = append(tmpl.Containers[0].VolumeMounts, - &ateapipb.VolumeMount{Name: "fixture", MountPath: mountPath}, - &ateapipb.VolumeMount{Name: "fixture", MountPath: mountPathAlias}, - &ateapipb.VolumeMount{Name: "scratch", MountPath: scratchPathA}, - &ateapipb.VolumeMount{Name: "scratch", MountPath: scratchPathB}) + &ateapi.VolumeMount{Name: "fixture", MountPath: mountPath}, + &ateapi.VolumeMount{Name: "fixture", MountPath: mountPathAlias}, + &ateapi.VolumeMount{Name: "scratch", MountPath: scratchPathA}, + &ateapi.VolumeMount{Name: "scratch", MountPath: scratchPathB}) tmpl.Volumes = append(tmpl.Volumes, - &ateapipb.Volume{ + &ateapi.Volume{ Name: "fixture", - Image: &ateapipb.ImageVolumeSource{Reference: fixtureImage}, + Image: &ateapi.ImageVolumeSource{Reference: fixtureImage}, }, - &ateapipb.Volume{ + &ateapi.Volume{ Name: "scratch", - DurableDir: &ateapipb.DurableDirVolumeSource{}, + DurableDir: &ateapi.DurableDirVolumeSource{}, }) if storageClass == "" { return } tmpl.Containers[0].VolumeMounts = append(tmpl.Containers[0].VolumeMounts, - &ateapipb.VolumeMount{Name: extVolume, MountPath: extPathA}, - &ateapipb.VolumeMount{Name: extVolume, MountPath: extPathB}) - tmpl.Volumes = append(tmpl.Volumes, &ateapipb.Volume{ + &ateapi.VolumeMount{Name: extVolume, MountPath: extPathA}, + &ateapi.VolumeMount{Name: extVolume, MountPath: extPathB}) + tmpl.Volumes = append(tmpl.Volumes, &ateapi.Volume{ Name: extVolume, - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ CapacityBytes: extCapacity, StorageClassName: storageClass, }}, @@ -326,7 +326,7 @@ func requireSharedWrite(ctx context.Context, t *testing.T, router *e2e.RouterCli // requireAssignedNode fails unless the actor's status records want as its // assigned_node. An empty want means no node is recorded. -func requireAssignedNode(t *testing.T, actor *ateapipb.Actor, want string) { +func requireAssignedNode(t *testing.T, actor *ateapi.Actor, want string) { t.Helper() if got := actor.GetStatus().GetAssignedNode(); got != want { @@ -339,7 +339,7 @@ func requireAssignedNode(t *testing.T, actor *ateapipb.Actor, want string) { func requireAssignedToWorkerNode(ctx context.Context, t *testing.T, clients *e2e.Clients, actorRef resources.ActorRef) string { t.Helper() - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actorRef.ToObjectRef()}) + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{Actor: actorRef.ToObjectRef()}) if err != nil { t.Fatalf("GetActor: %v", err) } @@ -367,9 +367,9 @@ func TestCombinedVolumes(t *testing.T) { tmpl := createTemplate(ctx, t, clients, ns, fixtureImage, storageClass) actorRef := resources.ActorRef{Atespace: atespace, Name: "cv-" + ns.Name} - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, ActorTemplate: e2e.TemplateRef(tmpl), }, }); err != nil { @@ -377,11 +377,11 @@ func TestCombinedVolumes(t *testing.T) { } t.Cleanup(func() { cleanupCtx := context.Background() - _, _ = clients.SubstrateAPI.SuspendActor(cleanupCtx, &ateapipb.SuspendActorRequest{Actor: actorRef.ToObjectRef()}) - _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapipb.DeleteActorRequest{Actor: actorRef.ToObjectRef()}) + _, _ = clients.SubstrateAPI.SuspendActor(cleanupCtx, &ateapi.SuspendActorRequest{Actor: actorRef.ToObjectRef()}) + _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapi.DeleteActorRequest{Actor: actorRef.ToObjectRef()}) }) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef.ToObjectRef()}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: actorRef.ToObjectRef()}); err != nil { t.Fatalf("ResumeActor: %v", err) } requireAssignedToWorkerNode(ctx, t, clients, actorRef) @@ -433,7 +433,7 @@ func TestCombinedVolumes(t *testing.T) { t.Run("SurvivesSuspendResume", func(t *testing.T) { runningNode := requireAssignedToWorkerNode(ctx, t, clients, actorRef) - suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef.ToObjectRef(), Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef.ToObjectRef(), Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatalf("SuspendActor: %v", err) } @@ -446,7 +446,7 @@ func TestCombinedVolumes(t *testing.T) { // plane before checking the mounts and their shared writes. resumeCtx, cancel := context.WithTimeout(ctx, 2*time.Minute) defer cancel() - if _, err := e2e.ResumeActorAwaitCapacity(t, resumeCtx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef.ToObjectRef()}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, resumeCtx, clients, &ateapi.ResumeActorRequest{Actor: actorRef.ToObjectRef()}); err != nil { t.Fatalf("ResumeActor after suspend: %v", err) } requireContentAtBoth(resumeCtx, t, router, actorRef, payloadPath, mountPathAlias+"/"+payloadName, payloadContent) @@ -470,18 +470,18 @@ func TestCombinedVolumes(t *testing.T) { requireWrite(ctx, t, router, actorRef, extPathA+"/"+postSnapshotName) } - reverted, err := clients.SubstrateAPI.RevertActor(ctx, &ateapipb.RevertActorRequest{Actor: actorRef.ToObjectRef()}) + reverted, err := clients.SubstrateAPI.RevertActor(ctx, &ateapi.RevertActorRequest{Actor: actorRef.ToObjectRef()}) if err != nil { t.Fatalf("RevertActor: %v", err) } - if got := reverted.GetActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := reverted.GetActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("state after revert = %v, want SUSPENDED", got) } requireAssignedNode(t, reverted.GetActor(), "") resumeCtx, cancel := context.WithTimeout(ctx, 2*time.Minute) defer cancel() - if _, err := e2e.ResumeActorAwaitCapacity(t, resumeCtx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef.ToObjectRef()}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, resumeCtx, clients, &ateapi.ResumeActorRequest{Actor: actorRef.ToObjectRef()}); err != nil { t.Fatalf("ResumeActor after revert: %v", err) } diff --git a/internal/e2e/suites/credentials/credentials_test.go b/internal/e2e/suites/credentials/credentials_test.go index 086d8a5b70..7087518e32 100644 --- a/internal/e2e/suites/credentials/credentials_test.go +++ b/internal/e2e/suites/credentials/credentials_test.go @@ -29,9 +29,9 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // TestKubernetesCredentialInjection uses the Helm values in values.yaml, real @@ -93,12 +93,12 @@ func TestKubernetesCredentialInjection(t *testing.T) { atespace, actorTemplate = deniedAtespace, deniedTemplate actorName = "allowed" } - actor := &ateapipb.ObjectRef{Atespace: atespace, Name: actorName} - _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actor}) - _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: actor}) - _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: actorName}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: atespace, Name: actorTemplate.GetMetadata().GetName()}, + actor := &ateapi.ObjectRef{Atespace: atespace, Name: actorName} + _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actor}) + _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: actor}) + _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: actorName}, + ActorTemplate: &ateapi.ObjectRef{Atespace: atespace, Name: actorTemplate.GetMetadata().GetName()}, }}) require.NoError(t, err) cleanupTest := t @@ -108,21 +108,21 @@ func TestKubernetesCredentialInjection(t *testing.T) { cleanupTest.Cleanup(func() { cleanupCtx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - _, _ = clients.SubstrateAPI.SuspendActor(cleanupCtx, &ateapipb.SuspendActorRequest{Actor: actor}) - _, err := clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapipb.DeleteActorRequest{Actor: actor}) + _, _ = clients.SubstrateAPI.SuspendActor(cleanupCtx, &ateapi.SuspendActorRequest{Actor: actor}) + _, err := clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapi.DeleteActorRequest{Actor: actor}) if err != nil { cleanupTest.Errorf("delete actor %s/%s: %v", atespace, actorName, err) } }) rule := e2e.EgressAllowHTTP(host) if tc.secret != "" { - rule.Http.Effects = &ateapipb.HttpRuleEffects{ReplaceHeaders: []*ateapipb.CredentialHeader{{ + rule.Http.Effects = &ateapi.HttpRuleEffects{ReplaceHeaders: []*ateapi.CredentialHeader{{ Header: "authorization", Prefix: "Bearer ", CredentialUri: fmt.Sprintf("ate-secret://k8s.io/default/%s/%s/token", tc.secretNamespace, tc.secret), }}} } e2e.EnsureEgressPolicy(t, ctx, clients, actor, rule) - _, err = clients.SubstrateAPI.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: actor}) + _, err = clients.SubstrateAPI.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actor}) require.NoError(t, err) path := "/fetch?roots=system&url=" + url.QueryEscape("http://"+host+"/credential") if tc.authorization != "" { diff --git a/internal/e2e/suites/demo/demo_test.go b/internal/e2e/suites/demo/demo_test.go index cf62eba10e..d308fa9317 100644 --- a/internal/e2e/suites/demo/demo_test.go +++ b/internal/e2e/suites/demo/demo_test.go @@ -27,12 +27,12 @@ import ( "time" "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/hardware" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/testing/protocmp" @@ -50,14 +50,14 @@ func TestActorLifecycle(t *testing.T) { clients := e2e.GetClients() // Create actor template. - at, err := createActorTemplate(ctx, t, clients, nsObj, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY) + at, err := createActorTemplate(ctx, t, clients, nsObj, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY) if err != nil { t.Fatalf("failed to initialize ActorTemplate: %v", err) } tests := []struct { name string - f func(ctx context.Context, t *testing.T, clients *e2e.Clients, ns *e2e.Namespace, at *ateapipb.ActorTemplate) error + f func(ctx context.Context, t *testing.T, clients *e2e.Clients, ns *e2e.Namespace, at *ateapi.ActorTemplate) error }{ { name: "CreateActor", @@ -101,15 +101,15 @@ func TestActorSnapshotLifecycle(t *testing.T) { clients := e2e.GetClients() nsObj := e2e.CreateNamespace(t) - at, err := createActorTemplate(ctx, t, clients, nsObj, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY) + at, err := createActorTemplate(ctx, t, clients, nsObj, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY) if err != nil { t.Fatalf("failed to initialize ActorTemplate: %v", err) } goldenStamp := goldenSnapshotRuntime(t, ctx, clients, at) - wantClass := string(atev1alpha1.SandboxClassGvisor) + wantClass := string(atev1.SandboxClassGvisor) if e2e.IsMicroVM() { - wantClass = string(atev1alpha1.SandboxClassMicroVM) + wantClass = string(atev1.SandboxClassMicroVM) } if got := goldenStamp.GetSandboxClass(); got != wantClass { t.Errorf("golden snapshot sandbox_class = %q, want %q", got, wantClass) @@ -127,13 +127,13 @@ func TestActorSnapshotLifecycle(t *testing.T) { t.Cleanup(func() { cleanupCtx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() - _, _ = clients.SubstrateAPI.SuspendActor(cleanupCtx, &ateapipb.SuspendActorRequest{Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: name}}) - _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapipb.DeleteActorRequest{Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: name}}) + _, _ = clients.SubstrateAPI.SuspendActor(cleanupCtx, &ateapi.SuspendActorRequest{Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: name}}) + _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapi.DeleteActorRequest{Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: name}}) }) } - sourceCreated, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: sourceName}, + sourceCreated, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: sourceName}, ActorTemplate: e2e.TemplateRef(at), }}) if err != nil { @@ -142,13 +142,13 @@ func TestActorSnapshotLifecycle(t *testing.T) { if diff := cmp.Diff(goldenStamp, durableSnapshot(sourceCreated.GetStatus()).GetSandboxRuntime(), protocmp.Transform()); diff != "" { t.Fatalf("golden snapshot stamp mismatch (-golden +actor):\n%s", diff) } - sourceResumed, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: sourceName}}) + sourceResumed, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: sourceName}}) if err != nil { t.Fatalf("failed to resume source Actor: %v", err) } - waitForActorState(ctx, t, clients, sourceName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, sourceName, ateapi.ActorState_ACTOR_STATE_RUNNING) assignment := sourceResumed.GetActor().GetStatus().GetWorkerAssignment() - worker, err := clients.SubstrateAPI.GetWorker(ctx, &ateapipb.GetWorkerRequest{Worker: assignment.GetWorker()}) + worker, err := clients.SubstrateAPI.GetWorker(ctx, &ateapi.GetWorkerRequest{Worker: assignment.GetWorker()}) if err != nil { t.Fatalf("failed to get assigned Worker %s: %v", assignment.GetWorker().GetName(), err) } @@ -164,13 +164,13 @@ func TestActorSnapshotLifecycle(t *testing.T) { } validateCounterResponse(t, response, "source", 1, 1) - tagRef := &ateapipb.ObjectRef{Atespace: demoAtespace, Name: "e2e-" + nsObj.Name} + tagRef := &ateapi.ObjectRef{Atespace: demoAtespace, Name: "e2e-" + nsObj.Name} t.Cleanup(func() { - _, _ = clients.SubstrateAPI.DeleteTag(context.Background(), &ateapipb.DeleteTagRequest{Tag: tagRef}) + _, _ = clients.SubstrateAPI.DeleteTag(context.Background(), &ateapi.DeleteTagRequest{Tag: tagRef}) }) - suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: sourceName}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: sourceName}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }) if err != nil { t.Fatalf("failed to suspend source Actor: %v", err) @@ -186,11 +186,11 @@ func TestActorSnapshotLifecycle(t *testing.T) { assertSnapshotUnderLocation(t, snapshotURI, wantSnapshotLocation(t, at)) // The tag is given its own copy of the snapshot the suspend just wrote, so // it survives the Actor being suspended again or deleted. - tagToUpdate, err := clients.SubstrateAPI.CreateTag(ctx, &ateapipb.CreateTagRequest{ - Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: tagRef.GetName()}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - SourceActor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: sourceName}, + tagToUpdate, err := clients.SubstrateAPI.CreateTag(ctx, &ateapi.CreateTagRequest{ + Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: tagRef.GetName()}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + SourceActor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: sourceName}, }, }) if err != nil { @@ -206,7 +206,7 @@ func TestActorSnapshotLifecycle(t *testing.T) { t.Fatalf("tag snapshot stamp mismatch (-actor snapshot +tag):\n%s", diff) } assertSnapshotUnderLocation(t, tagSnapshotURI(tagToUpdate), wantSnapshotLocation(t, at)) - listed, err := clients.SubstrateAPI.ListTags(ctx, &ateapipb.ListTagsRequest{Atespace: demoAtespace}) + listed, err := clients.SubstrateAPI.ListTags(ctx, &ateapi.ListTagsRequest{Atespace: demoAtespace}) if err != nil { t.Fatalf("failed to list Tags: %v", err) } @@ -221,16 +221,16 @@ func TestActorSnapshotLifecycle(t *testing.T) { t.Fatalf("tag %q missing from ListTags", tagRef.GetName()) } - tagToUpdate.Scope = ateapipb.TagScope_TAG_SCOPE_PUBLISHED - if _, err := clients.SubstrateAPI.UpdateTag(ctx, &ateapipb.UpdateTagRequest{ + tagToUpdate.Scope = ateapi.TagScope_TAG_SCOPE_PUBLISHED + if _, err := clients.SubstrateAPI.UpdateTag(ctx, &ateapi.UpdateTagRequest{ Tag: tagToUpdate, }); err != nil { t.Fatalf("failed to publish Tag: %v", err) } - cloned, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: cloneName}, + cloned, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: cloneName}, ActorTemplate: e2e.TemplateRef(at), SourceTag: tagRef, }, @@ -241,21 +241,21 @@ func TestActorSnapshotLifecycle(t *testing.T) { if diff := cmp.Diff(snapshotStamp, durableSnapshot(cloned.GetStatus()).GetSandboxRuntime(), protocmp.Transform()); diff != "" { t.Fatalf("cloned actor snapshot stamp mismatch (-tag +clone):\n%s", diff) } - cloneResumed, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: cloneName}}) + cloneResumed, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: cloneName}}) if err != nil { t.Fatalf("failed to resume cloned Actor: %v", err) } if diff := cmp.Diff(snapshotStamp, cloneResumed.GetActor().GetStatus().GetWorkerAssignment().GetSandboxRuntime(), protocmp.Transform()); diff != "" { t.Errorf("cloned actor assignment stamp mismatch (-tag +assignment):\n%s", diff) } - waitForActorState(ctx, t, clients, cloneName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, cloneName, ateapi.ActorState_ACTOR_STATE_RUNNING) response, err = callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: cloneName}) if err != nil { t.Fatalf("failed to call cloned Actor: %v", err) } validateCounterResponse(t, response, "clone", 2, 2) - if _, err := clients.SubstrateAPI.DeleteTag(ctx, &ateapipb.DeleteTagRequest{Tag: tagRef}); err != nil { + if _, err := clients.SubstrateAPI.DeleteTag(ctx, &ateapi.DeleteTagRequest{Tag: tagRef}); err != nil { t.Fatalf("failed to delete Tag: %v", err) } } @@ -269,7 +269,7 @@ func TestDurableDirLifecycle(t *testing.T) { { name: "preferredFidelity:MEMORY", tc: actorLifecycleTestCase{ - fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, wantMemoryAfterPause: 2, wantFileAfterPause: 2, wantRootfsAfterPause: 2, @@ -283,7 +283,7 @@ func TestDurableDirLifecycle(t *testing.T) { // so memory and rootfs writes cold-boot on every resume. name: "preferredFidelity:VOLUMES", tc: actorLifecycleTestCase{ - fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, + fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, wantMemoryAfterPause: 1, wantFileAfterPause: 2, wantRootfsAfterPause: 1, @@ -297,7 +297,7 @@ func TestDurableDirLifecycle(t *testing.T) { // counter restarts while the rootfs counter continues. name: "preferredFidelity:ROOTFS", tc: actorLifecycleTestCase{ - fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, + fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, wantMemoryAfterPause: 1, wantFileAfterPause: 2, wantRootfsAfterPause: 2, @@ -327,7 +327,7 @@ func TestMultipleDurableDirLifecycle(t *testing.T) { { name: "preferredFidelity:MEMORY", tc: actorLifecycleTestCase{ - fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, wantMemoryAfterPause: 2, wantFileAfterPause: 2, wantMemoryAfterSuspend: 3, @@ -338,7 +338,7 @@ func TestMultipleDurableDirLifecycle(t *testing.T) { { name: "preferredFidelity:VOLUMES", tc: actorLifecycleTestCase{ - fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, + fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, wantMemoryAfterPause: 1, wantFileAfterPause: 2, wantMemoryAfterSuspend: 1, @@ -349,7 +349,7 @@ func TestMultipleDurableDirLifecycle(t *testing.T) { { name: "preferredFidelity:ROOTFS", tc: actorLifecycleTestCase{ - fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, + fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, wantMemoryAfterPause: 1, wantFileAfterPause: 2, wantRootfsAfterPause: 2, @@ -380,7 +380,7 @@ func TestExternalVolumeLifecycle(t *testing.T) { { name: "preferredFidelity:VOLUMES", tc: actorLifecycleTestCase{ - fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, + fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, wantMemoryAfterPause: 1, wantFileAfterPause: 2, wantMemoryAfterSuspend: 1, @@ -404,7 +404,7 @@ func TestDeleteRunningActorWithExternalVolume(t *testing.T) { clients := e2e.GetClients() nsObj := e2e.CreateNamespace(t) - at, err := createActorTemplateWithExternalVolume(ctx, t, clients, nsObj, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES) + at, err := createActorTemplateWithExternalVolume(ctx, t, clients, nsObj, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES) if err != nil { t.Fatalf("failed to initialize ActorTemplate: %v", err) } @@ -412,25 +412,25 @@ func TestDeleteRunningActorWithExternalVolume(t *testing.T) { actorName := "delete-running-extvol-" + nsObj.Name t.Logf("Creating Actor %q...", actorName) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, ActorTemplate: e2e.TemplateRef(at), }}); err != nil { t.Fatalf("failed to create Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) t.Logf("Resuming Actor %q...", actorName) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to resume Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) // Verify volume exists in actor (it should be provisioned) - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }) if err != nil { t.Fatalf("failed to get actor: %v", err) @@ -446,15 +446,15 @@ func TestDeleteRunningActorWithExternalVolume(t *testing.T) { // Delete the running actor t.Logf("Deleting running Actor %q...", actorName) - if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to delete Actor: %v", err) } // Verify deletion in store - if _, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); status.Code(err) != codes.NotFound { t.Fatalf("expected actor %q to be NotFound after delete, got err: %v", actorName, err) } @@ -471,7 +471,7 @@ func TestExternalVolume_NodeMigration(t *testing.T) { clients := e2e.GetClients() nsObj := e2e.CreateNamespace(t) - at, err := createActorTemplateWithExternalVolume(ctx, t, clients, nsObj, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES) + at, err := createActorTemplateWithExternalVolume(ctx, t, clients, nsObj, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES) if err != nil { t.Fatalf("failed to initialize ActorTemplate: %v", err) } @@ -479,21 +479,21 @@ func TestExternalVolume_NodeMigration(t *testing.T) { actorName := "extvol-migration-" + nsObj.Name t.Logf("Creating Actor %q...", actorName) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, ActorTemplate: e2e.TemplateRef(at), }}); err != nil { t.Fatalf("failed to create Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) t.Logf("Resuming Actor %q...", actorName) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to resume Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) resp, err := callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}) if err != nil { @@ -501,8 +501,8 @@ func TestExternalVolume_NodeMigration(t *testing.T) { } validateCounterResponse(t, resp, "initial run", 1, 1) - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }) if err != nil { t.Fatalf("failed to get actor: %v", err) @@ -511,13 +511,13 @@ func TestExternalVolume_NodeMigration(t *testing.T) { initialWorkerNS := actor.GetStatus().GetWorkerAssignment().GetWorkerNamespace() t.Logf("Suspending Actor %q...", actorName) - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }); err != nil { t.Fatalf("failed to suspend Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) // Delete initial worker pod to force migration onto another worker upon resume if initialWorkerPod != "" && initialWorkerNS != "" { @@ -528,12 +528,12 @@ func TestExternalVolume_NodeMigration(t *testing.T) { time.Sleep(5 * time.Second) t.Logf("Resuming Actor %q after worker pod eviction...", actorName) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to resume Actor after migration: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) resp, err = callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}) if err != nil { @@ -543,8 +543,8 @@ func TestExternalVolume_NodeMigration(t *testing.T) { // Clean up by deleting the actor t.Logf("Deleting Actor %q...", actorName) - if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to delete Actor: %v", err) } @@ -559,7 +559,7 @@ func TestExternalVolume_NodeMigration(t *testing.T) { // 5. Sync Suspend & Resume actor. // 6. Call to actor and validate memory and file counters. type actorLifecycleTestCase struct { - fidelity ateapipb.SnapshotFidelity + fidelity ateapi.SnapshotFidelity wantMemoryAfterPause int wantFileAfterPause int wantMemoryAfterSuspend int @@ -579,10 +579,10 @@ type actorLifecycleTestCase struct { // wantSnapshotFidelity, when set, asserts the content scope recorded // on the ActorSnapshot the suspend produced. - wantSnapshotFidelity ateapipb.SnapshotFidelity + wantSnapshotFidelity ateapi.SnapshotFidelity } -func runActorLifecycleTestCase(t *testing.T, prefix string, createTemplate func(context.Context, *testing.T, *e2e.Clients, *e2e.Namespace, ateapipb.SnapshotFidelity) (*ateapipb.ActorTemplate, error), tc actorLifecycleTestCase) { +func runActorLifecycleTestCase(t *testing.T, prefix string, createTemplate func(context.Context, *testing.T, *e2e.Clients, *e2e.Namespace, ateapi.SnapshotFidelity) (*ateapi.ActorTemplate, error), tc actorLifecycleTestCase) { // Create namespace nsObj := e2e.CreateNamespace(t) @@ -601,8 +601,8 @@ func runActorLifecycleTestCase(t *testing.T, prefix string, createTemplate func( actorID := prefix + "-" + nsObj.Name t.Logf("Creating Actor %q using Substrate API...", actorID) - createResp, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorID}, + createResp, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorID}, ActorTemplate: e2e.TemplateRef(at), }}) if err != nil { @@ -610,20 +610,20 @@ func runActorLifecycleTestCase(t *testing.T, prefix string, createTemplate func( } t.Logf("Successfully created Actor: %s", createResp.GetMetadata().GetName()) defer func() { - clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) }() // Resuming the actor t.Logf("Resuming Actor %q...", actorID) - resumed1, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + resumed1, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) if err != nil { t.Fatalf("failed to resume Actor: %v", err) } - waitForActorState(ctx, t, clients, actorID, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorID, ateapi.ActorState_ACTOR_STATE_RUNNING) assignedRuntime := resumed1.GetActor().GetStatus().GetWorkerAssignment().GetSandboxRuntime() if assignedRuntime == nil { t.Fatalf("resumed Actor %q has nil WorkerAssignment.SandboxRuntime", actorID) @@ -645,9 +645,9 @@ func runActorLifecycleTestCase(t *testing.T, prefix string, createTemplate func( // Pausing the actor // t.Logf("Pausing Actor %q...", actorID) - paused, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + paused, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }) if err != nil { t.Fatalf("failed to pause Actor: %v", err) @@ -659,13 +659,13 @@ func runActorLifecycleTestCase(t *testing.T, prefix string, createTemplate func( // Resuming the actor t.Logf("Resuming Actor %q again...", actorID) - resumed2, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + resumed2, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) if err != nil { t.Fatalf("failed to resume Actor again: %v", err) } - waitForActorState(ctx, t, clients, actorID, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorID, ateapi.ActorState_ACTOR_STATE_RUNNING) assignedRuntime2 := resumed2.GetActor().GetStatus().GetWorkerAssignment().GetSandboxRuntime() if diff := cmp.Diff(assignedRuntime, assignedRuntime2, protocmp.Transform()); diff != "" { t.Errorf("resume-from-paused assignment stamp mismatch (-first +second):\n%s", diff) @@ -687,30 +687,30 @@ func runActorLifecycleTestCase(t *testing.T, prefix string, createTemplate func( // Suspending the actor // t.Logf("Suspending Actor %q...", actorID) - suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }) if err != nil { t.Fatalf("failed to suspend Actor: %v", err) } - waitForActorState(ctx, t, clients, actorID, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorID, ateapi.ActorState_ACTOR_STATE_SUSPENDED) if diff := cmp.Diff(assignedRuntime2, durableSnapshot(suspended.GetActor().GetStatus()).GetSandboxRuntime(), protocmp.Transform()); diff != "" { t.Errorf("durable snapshot stamp after suspend mismatch (-assignment +snapshot):\n%s", diff) } - if tc.wantSnapshotFidelity != ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED { + if tc.wantSnapshotFidelity != ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_UNSPECIFIED { validateSnapshotFidelity(ctx, t, clients, actorID, tc.wantSnapshotFidelity) } // Resuming the actor t.Logf("Resuming Actor %q again...", actorID) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }); err != nil { t.Fatalf("failed to resume Actor again: %v", err) } - waitForActorState(ctx, t, clients, actorID, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorID, ateapi.ActorState_ACTOR_STATE_RUNNING) resp, err = callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorID}) if err != nil { @@ -727,10 +727,10 @@ func runActorLifecycleTestCase(t *testing.T, prefix string, createTemplate func( // validateSnapshotFidelity asserts the content scope recorded on the // suspended actor's external snapshot. -func validateSnapshotFidelity(ctx context.Context, t *testing.T, clients *e2e.Clients, actorID string, want ateapipb.SnapshotFidelity) { +func validateSnapshotFidelity(ctx context.Context, t *testing.T, clients *e2e.Clients, actorID string, want ateapi.SnapshotFidelity) { t.Helper() - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) if err != nil { t.Fatalf("failed to get suspended Actor: %v", err) @@ -743,11 +743,11 @@ func validateSnapshotFidelity(ctx context.Context, t *testing.T, clients *e2e.Cl } } -func durableSnapshot(status *ateapipb.ActorStatus) *ateapipb.Snapshot { - var best *ateapipb.Snapshot +func durableSnapshot(status *ateapi.ActorStatus) *ateapi.Snapshot { + var best *ateapi.Snapshot for _, snap := range status.GetSnapshots() { st := snap.GetDurableSnapshot() - if st.GetStatus() == ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED && + if st.GetStatus() == ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED && st.GetObject().GetSnapshotUri() != "" { if best == nil || snap.GetGeneration() > best.GetGeneration() { best = snap @@ -757,16 +757,16 @@ func durableSnapshot(status *ateapipb.ActorStatus) *ateapipb.Snapshot { return best } -func durableSnapshotStorage(status *ateapipb.ActorStatus) *ateapipb.SnapshotStorage { +func durableSnapshotStorage(status *ateapi.ActorStatus) *ateapi.SnapshotStorage { return durableSnapshot(status).GetDurableSnapshot() } -func durableSnapshotURI(status *ateapipb.ActorStatus) string { +func durableSnapshotURI(status *ateapi.ActorStatus) string { return durableSnapshotStorage(status).GetObject().GetSnapshotUri() } -func localSnapshot(status *ateapipb.ActorStatus) *ateapipb.Snapshot { - var best *ateapipb.Snapshot +func localSnapshot(status *ateapi.ActorStatus) *ateapi.Snapshot { + var best *ateapi.Snapshot for _, snap := range status.GetSnapshots() { if snap.GetLocality() != "" && snap.GetUuid() != "" { if best == nil || snap.GetGeneration() > best.GetGeneration() { @@ -777,13 +777,13 @@ func localSnapshot(status *ateapipb.ActorStatus) *ateapipb.Snapshot { return best } -func hasLocalSnapshot(status *ateapipb.ActorStatus) bool { +func hasLocalSnapshot(status *ateapi.ActorStatus) bool { return localSnapshot(status) != nil } -func goldenSnapshotRuntime(t *testing.T, ctx context.Context, clients *e2e.Clients, at *ateapipb.ActorTemplate) *ateapipb.ActorSandboxRuntime { +func goldenSnapshotRuntime(t *testing.T, ctx context.Context, clients *e2e.Clients, at *ateapi.ActorTemplate) *ateapi.ActorSandboxRuntime { t.Helper() - current, err := clients.SubstrateAPI.GetActorTemplate(ctx, &ateapipb.GetActorTemplateRequest{ActorTemplate: e2e.TemplateRef(at)}) + current, err := clients.SubstrateAPI.GetActorTemplate(ctx, &ateapi.GetActorTemplateRequest{ActorTemplate: e2e.TemplateRef(at)}) if err != nil { t.Fatalf("GetActorTemplate: %v", err) } @@ -791,7 +791,7 @@ func goldenSnapshotRuntime(t *testing.T, ctx context.Context, clients *e2e.Clien if goldenTag.GetName() == "" { t.Fatalf("ActorTemplate %s has no golden tag", e2e.TemplateRef(at)) } - tag, err := clients.SubstrateAPI.GetTag(ctx, &ateapipb.GetTagRequest{Tag: goldenTag}) + tag, err := clients.SubstrateAPI.GetTag(ctx, &ateapi.GetTagRequest{Tag: goldenTag}) if err != nil { t.Fatalf("GetTag(golden %s/%s): %v", goldenTag.GetAtespace(), goldenTag.GetName(), err) } @@ -802,7 +802,7 @@ func goldenSnapshotRuntime(t *testing.T, ctx context.Context, clients *e2e.Clien return stamp } -func runtimeAttribute(rt *ateapipb.ActorSandboxRuntime, key string) string { +func runtimeAttribute(rt *ateapi.ActorSandboxRuntime, key string) string { for _, attr := range rt.GetVersion().GetAttributes() { if attr.GetKey() == key { return attr.GetValue() @@ -815,7 +815,7 @@ func runtimeAttribute(rt *ateapipb.ActorSandboxRuntime, key string) string { // template's storageLocation with the PerTemplateSnapshotLocation preview gate, // otherwise $SNAPSHOT_LOCATION, the --snapshot-location ate-setup installs it // with. -func wantSnapshotLocation(t *testing.T, tmpl *ateapipb.ActorTemplate) string { +func wantSnapshotLocation(t *testing.T, tmpl *ateapi.ActorTemplate) string { t.Helper() if location := tmpl.GetSnapshotConfig().GetStorageLocation(); location != "" && preview.IsEnabled(preview.GatePerTemplateSnapshotLocation) { return location @@ -846,7 +846,7 @@ func assertSnapshotUnderLocation(t *testing.T, snapshotURI, location string) { } } -func tagSnapshotURI(tag *ateapipb.Tag) string { +func tagSnapshotURI(tag *ateapi.Tag) string { return tag.GetStatus().GetSnapshot().GetDurableSnapshot().GetObject().GetSnapshotUri() } @@ -881,13 +881,13 @@ func validateCounterResponse(t *testing.T, resp string, stage string, wantMemory } } -func createActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, at *ateapipb.ActorTemplate) error { +func createActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, at *ateapi.ActorTemplate) error { // Create an Actor using the ATE API. actorName := "demo-actor-1-" + nsObj.Name t.Logf("Creating Actor %q using Substrate API...", actorName) - createResp, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, + createResp, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, ActorTemplate: e2e.TemplateRef(at), }}) if err != nil { @@ -895,13 +895,13 @@ func createActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj } t.Logf("Successfully created Actor: %s", createResp.GetMetadata().GetName()) defer func() { - clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }) }() - getResp, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + getResp, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }) if err != nil { t.Fatalf("GetActor RPC failed: %v", err) @@ -914,7 +914,7 @@ func createActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj if actor.GetActorTemplate().GetName() != at.GetMetadata().GetName() { t.Errorf("expected actor template name %s, got %s", at.GetMetadata().GetName(), actor.GetActorTemplate().GetName()) } - if actor.Status.State != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if actor.Status.State != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("expected actor state to be SUSPENDED, got %v", actor.Status.State) } @@ -923,27 +923,27 @@ func createActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj return nil } -func pauseActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, at *ateapipb.ActorTemplate) error { +func pauseActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, at *ateapi.ActorTemplate) error { actorName := "pause-actor-" + nsObj.Name // Creating an actor t.Logf("Creating Actor %q...", actorName) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, ActorTemplate: e2e.TemplateRef(at), }}); err != nil { t.Fatalf("failed to create Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) // Resuming the actor t.Logf("Resuming Actor %q...", actorName) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to resume Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) resp := callActorUntilCountAtLeast(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}, 1) if isMicroVMEnvironment() { @@ -954,9 +954,9 @@ func pauseActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj * // Pausing the actor t.Logf("Pausing Actor %q...", actorName) - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }); err != nil { t.Fatalf("failed to pause Actor: %v", err) } @@ -964,12 +964,12 @@ func pauseActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj * // Resuming the actor again t.Logf("Resuming Actor %q again...", actorName) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to resume Actor again: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) resp = callActorUntilCountAtLeast(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}, 2) if isMicroVMEnvironment() { @@ -980,24 +980,24 @@ func pauseActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj * // Suspending the actor before deletion t.Logf("Suspending Actor %q before deletion...", actorName) - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }); err != nil { t.Fatalf("failed to suspend Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) // Deleting the actor t.Logf("Deleting Actor %q...", actorName) - if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to delete Actor: %v", err) } // Verify deletion - if _, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err == nil { t.Fatalf("expected actor %q to be deleted, but it still exists", actorName) } @@ -1005,27 +1005,27 @@ func pauseActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj * return nil } -func suspendActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, at *ateapipb.ActorTemplate) error { +func suspendActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, at *ateapi.ActorTemplate) error { actorName := "suspend-actor-" + nsObj.Name // Creating an actor t.Logf("Creating Actor %q...", actorName) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, ActorTemplate: e2e.TemplateRef(at), }}); err != nil { t.Fatalf("failed to create Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) // Resuming the actor t.Logf("Resuming Actor %q...", actorName) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to resume Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) resp := callActorUntilCountAtLeast(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}, 1) if isMicroVMEnvironment() { @@ -1036,22 +1036,22 @@ func suspendActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj // Suspending the actor t.Logf("Suspending Actor %q...", actorName) - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }); err != nil { t.Fatalf("failed to suspend Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) // Resuming the actor again t.Logf("Resuming Actor %q again...", actorName) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to resume Actor again: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) resp = callActorUntilCountAtLeast(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}, 2) if isMicroVMEnvironment() { @@ -1062,24 +1062,24 @@ func suspendActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj // Suspending the actor before deletion t.Logf("Suspending Actor %q before deletion...", actorName) - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }); err != nil { t.Fatalf("failed to suspend Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) // Deleting the actor t.Logf("Deleting Actor %q...", actorName) - if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to delete Actor: %v", err) } // Verify deletion - if _, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err == nil { t.Fatalf("expected actor %q to be deleted, but it still exists", actorName) } @@ -1087,27 +1087,27 @@ func suspendActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj return nil } -func revertActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, at *ateapipb.ActorTemplate) error { +func revertActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, at *ateapi.ActorTemplate) error { actorName := "revert-actor-" + nsObj.Name - actorRef := &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName} + actorRef := &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName} t.Cleanup(func() { cleanupCtx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() - _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapipb.DeleteActorRequest{Actor: actorRef}) + _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapi.DeleteActorRequest{Actor: actorRef}) }) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, ActorTemplate: e2e.TemplateRef(at), }}); err != nil { t.Fatalf("failed to create Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("failed to resume Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) resp, err := callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}) if err != nil { @@ -1115,7 +1115,7 @@ func revertActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj } validateCounterResponse(t, resp, "before snapshot", 1, 1) - suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatalf("failed to suspend Actor: %v", err) } @@ -1126,10 +1126,10 @@ func revertActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj // Mutate guest state after the snapshot, then revert from RUNNING: the // increment to 2 must be discarded and the snapshot left untouched. - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("failed to resume Actor after suspend: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) resp, err = callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}) if err != nil { @@ -1137,11 +1137,11 @@ func revertActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj } validateCounterResponse(t, resp, "before revert from RUNNING", 2, 2) - reverted, err := clients.SubstrateAPI.RevertActor(ctx, &ateapipb.RevertActorRequest{Actor: actorRef}) + reverted, err := clients.SubstrateAPI.RevertActor(ctx, &ateapi.RevertActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("RevertActor from RUNNING: %v", err) } - if got := reverted.GetActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := reverted.GetActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("state after revert = %v, want SUSPENDED", got) } if got := durableSnapshotURI(reverted.GetActor().GetStatus()); got != snapshotURI { @@ -1153,10 +1153,10 @@ func revertActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj // Resuming proves the guest restored from the count=1 snapshot rather than // continuing from count=2: this call increments from 1 to 2, not from 2 to 3. - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("failed to resume Actor after revert: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) resp, err = callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}) if err != nil { @@ -1168,16 +1168,16 @@ func revertActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj // snapshot over the external one, so clearing the local snapshot is what // prevents this async suspend's count=2 checkpoint from restoring on the // next resume. - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}); err != nil { + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}}); err != nil { t.Fatalf("failed to pause Actor: %v", err) } waitForActorPaused(ctx, t, clients, actorName) - reverted, err = clients.SubstrateAPI.RevertActor(ctx, &ateapipb.RevertActorRequest{Actor: actorRef}) + reverted, err = clients.SubstrateAPI.RevertActor(ctx, &ateapi.RevertActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("RevertActor from paused: %v", err) } - if got := reverted.GetActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := reverted.GetActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("state after revert from paused = %v, want SUSPENDED", got) } if hasLocalSnapshot(reverted.GetActor().GetStatus()) { @@ -1188,16 +1188,16 @@ func revertActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj } // SUSPENDED is rejected with FailedPrecondition rather than no-oping. - if _, err := clients.SubstrateAPI.RevertActor(ctx, &ateapipb.RevertActorRequest{Actor: actorRef}); status.Code(err) != codes.FailedPrecondition { + if _, err := clients.SubstrateAPI.RevertActor(ctx, &ateapi.RevertActorRequest{Actor: actorRef}); status.Code(err) != codes.FailedPrecondition { t.Fatalf("RevertActor from SUSPENDED: got %v, want FailedPrecondition", err) } // Final resume: if the local checkpoint had been restored, the counter // would advance from 2 to 3. Expecting 2 proves the external snapshot won. - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("failed to resume Actor after paused revert: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) resp, err = callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}) if err != nil { @@ -1205,32 +1205,32 @@ func revertActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj } validateCounterResponse(t, resp, "after revert from paused", 2, 2) - if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: actorRef}); err != nil { + if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: actorRef}); err != nil { t.Fatalf("failed to delete Actor: %v", err) } return nil } -func deleteRunningActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, at *ateapipb.ActorTemplate) error { +func deleteRunningActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, at *ateapi.ActorTemplate) error { actorName := "delete-running-actor-" + nsObj.Name // 1. Creating and resuming the actor t.Logf("Creating Actor %q...", actorName) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, ActorTemplate: e2e.TemplateRef(at), }}); err != nil { t.Fatalf("failed to create Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) t.Logf("Resuming Actor %q...", actorName) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to resume Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) // 2. Call the actor to ensure workload is actively serving on worker resp, err := callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}) @@ -1241,64 +1241,64 @@ func deleteRunningActor(ctx context.Context, t *testing.T, clients *e2e.Clients, // 3. Delete the running actor t.Logf("Deleting running Actor %q...", actorName) - if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to delete Actor: %v", err) } // 4. Verify deletion in store - if _, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); status.Code(err) != codes.NotFound { t.Fatalf("expected actor %q to be NotFound after delete, got err: %v", actorName, err) } // 5. Verify actor name can be immediately reused t.Logf("Re-creating Actor %q to verify name reuse...", actorName) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, ActorTemplate: e2e.TemplateRef(at), }}); err != nil { t.Fatalf("failed to recreate Actor: %v", err) } defer func() { - clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }) }() - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) return nil } -func deletePausedActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, at *ateapipb.ActorTemplate) error { +func deletePausedActor(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, at *ateapi.ActorTemplate) error { actorName := "delete-paused-actor-" + nsObj.Name // 1. Creating an actor t.Logf("Creating Actor %q...", actorName) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, ActorTemplate: e2e.TemplateRef(at), }}); err != nil { t.Fatalf("failed to create Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) // 2. Resuming the actor t.Logf("Resuming Actor %q...", actorName) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to resume Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) // 3. Suspending the actor asynchronously t.Logf("Pausing Actor %q...", actorName) - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }); err != nil { t.Fatalf("failed to pause Actor: %v", err) } @@ -1306,15 +1306,15 @@ func deletePausedActor(ctx context.Context, t *testing.T, clients *e2e.Clients, // 4. Delete the asynchronously suspended actor t.Logf("Deleting paused Actor %q...", actorName) - if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to delete Actor: %v", err) } // 5. Verify deletion in store - if _, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); status.Code(err) != codes.NotFound { t.Fatalf("expected actor %q to be NotFound after delete, got err: %v", actorName, err) } @@ -1322,7 +1322,7 @@ func deletePausedActor(ctx context.Context, t *testing.T, clients *e2e.Clients, return nil } -func createActorTemplateInternal(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, base string, fidelity ateapipb.SnapshotFidelity, modifyTemplate func(*ateapipb.ActorTemplate)) (*ateapipb.ActorTemplate, error) { +func createActorTemplateInternal(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, base string, fidelity ateapi.SnapshotFidelity, modifyTemplate func(*ateapi.ActorTemplate)) (*ateapi.ActorTemplate, error) { env, err := e2e.CheckEnv("BUCKET_NAME") if err != nil { t.Fatalf("CheckEnv failed: %v", err) @@ -1338,7 +1338,7 @@ func createActorTemplateInternal(ctx context.Context, t *testing.T, clients *e2e // One actor at a time, plus a spare for the worker-deletion tests. PoolReplicas: 2, Labels: map[string]string{"demo": nsObj.Name}, - SnapshotConfig: &ateapipb.SnapshotConfig{ + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: "gs://" + env["BUCKET_NAME"] + "/ate-demo-" + name, PreferredFidelity: fidelity, }, @@ -1347,17 +1347,17 @@ func createActorTemplateInternal(ctx context.Context, t *testing.T, clients *e2e return at, nil } -func createActorTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, fidelity ateapipb.SnapshotFidelity) (*ateapipb.ActorTemplate, error) { +func createActorTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, fidelity ateapi.SnapshotFidelity) (*ateapi.ActorTemplate, error) { return createActorTemplateInternal(ctx, t, clients, nsObj, "counter", fidelity, nil) } -func createActorTemplateWithExternalVolume(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, fidelity ateapipb.SnapshotFidelity) (*ateapipb.ActorTemplate, error) { +func createActorTemplateWithExternalVolume(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, fidelity ateapi.SnapshotFidelity) (*ateapi.ActorTemplate, error) { scName := e2e.StorageClass if !hasStorageClass(ctx, clients, scName) { t.Fatalf("StorageClass %q not found in cluster; provide a valid --storage-class or install the CSI driver via --setup-csi", scName) } - modify := func(at *ateapipb.ActorTemplate) { + modify := func(at *ateapi.ActorTemplate) { for _, c := range at.GetContainers() { if c.GetName() != "counter" { continue @@ -1372,7 +1372,7 @@ func createActorTemplateWithExternalVolume(ctx context.Context, t *testing.T, cl } } if !hasExtMount { - c.VolumeMounts = append(c.VolumeMounts, &ateapipb.VolumeMount{ + c.VolumeMounts = append(c.VolumeMounts, &ateapi.VolumeMount{ Name: "external-data", MountPath: "/external-data", }) @@ -1387,9 +1387,9 @@ func createActorTemplateWithExternalVolume(ctx context.Context, t *testing.T, cl } } if !hasExtVol { - at.Volumes = append(at.Volumes, &ateapipb.Volume{ + at.Volumes = append(at.Volumes, &ateapi.Volume{ Name: "external-data", - External: &ateapipb.ExternalVolumeSource{Template: &ateapipb.ExternalVolumeTemplate{ + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ CapacityBytes: 1 << 30, StorageClassName: scName, }}, @@ -1410,21 +1410,21 @@ const ( // durable-dir volume alongside the one the demo already declares, and points the // counter's second file counter at it, so both volumes are written on every // request. -func createActorTemplateWithTwoDurableDirs(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, fidelity ateapipb.SnapshotFidelity) (*ateapipb.ActorTemplate, error) { - modify := func(at *ateapipb.ActorTemplate) { +func createActorTemplateWithTwoDurableDirs(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, fidelity ateapi.SnapshotFidelity) (*ateapi.ActorTemplate, error) { + modify := func(at *ateapi.ActorTemplate) { for _, c := range at.GetContainers() { if c.GetName() != "counter" { continue } c.Command = []string{"/ko-app/counter", "--second-file-counter-directory=" + secondDurableDirMountPath} - c.VolumeMounts = append(c.VolumeMounts, &ateapipb.VolumeMount{ + c.VolumeMounts = append(c.VolumeMounts, &ateapi.VolumeMount{ Name: secondDurableDirVolume, MountPath: secondDurableDirMountPath, }) } - at.Volumes = append(at.Volumes, &ateapipb.Volume{ + at.Volumes = append(at.Volumes, &ateapi.Volume{ Name: secondDurableDirVolume, - DurableDir: &ateapipb.DurableDirVolumeSource{}, + DurableDir: &ateapi.DurableDirVolumeSource{}, }) } return createActorTemplateInternal(ctx, t, clients, nsObj, "counter-two-durabledirs", fidelity, modify) @@ -1435,7 +1435,7 @@ func hasStorageClass(ctx context.Context, clients *e2e.Clients, name string) boo return err == nil } -func waitForActorState(ctx context.Context, t *testing.T, clients *e2e.Clients, actorName string, expectedState ateapipb.ActorState) { +func waitForActorState(ctx context.Context, t *testing.T, clients *e2e.Clients, actorName string, expectedState ateapi.ActorState) { waitForActorStateWithTimeout(ctx, t, clients, actorName, expectedState, 60*time.Second) } @@ -1443,9 +1443,9 @@ func waitForActorState(ctx context.Context, t *testing.T, clients *e2e.Clients, // on its node. func waitForActorPaused(ctx context.Context, t *testing.T, clients *e2e.Clients, actorName string) { t.Helper() - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) - resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) + resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }) if err != nil { t.Fatalf("GetActor %q after pause: %v", actorName, err) @@ -1458,13 +1458,13 @@ func waitForActorPaused(ctx context.Context, t *testing.T, clients *e2e.Clients, } } -func waitForActorStateWithTimeout(ctx context.Context, t *testing.T, clients *e2e.Clients, actorName string, expectedState ateapipb.ActorState, timeout time.Duration) { +func waitForActorStateWithTimeout(ctx context.Context, t *testing.T, clients *e2e.Clients, actorName string, expectedState ateapi.ActorState, timeout time.Duration) { t.Helper() t.Logf("Waiting for Actor %q to be %v...", actorName, expectedState) deadline := time.Now().Add(timeout) for time.Now().Before(deadline) { - resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }) if err == nil { if resp.GetStatus().GetState() == expectedState { @@ -1584,7 +1584,7 @@ func TestWorkerPodDeletion(t *testing.T) { clients := e2e.GetClients() // Create actor template. - at, err := createActorTemplate(ctx, t, clients, nsObj, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY) + at, err := createActorTemplate(ctx, t, clients, nsObj, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY) if err != nil { t.Fatalf("failed to initialize ActorTemplate: %v", err) } @@ -1593,32 +1593,32 @@ func TestWorkerPodDeletion(t *testing.T) { // Creating an actor t.Logf("Creating Actor %q...", actorName) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, ActorTemplate: e2e.TemplateRef(at), }}); err != nil { t.Fatalf("failed to create Actor: %v", err) } defer func() { - clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }) }() - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) // Resuming the actor t.Logf("Resuming Actor %q...", actorName) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }); err != nil { t.Fatalf("failed to resume Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) // Get actor to find the pod details - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }) if err != nil { t.Fatalf("failed to get Actor: %v", err) @@ -1637,7 +1637,7 @@ func TestWorkerPodDeletion(t *testing.T) { // Verify worker is in ListWorkers t.Logf("Verifying worker for pod %s/%s is listed...", podNamespace, podName) foundWorker := false - workersResp, err := clients.SubstrateAPI.ListWorkers(ctx, &ateapipb.ListWorkersRequest{}) + workersResp, err := clients.SubstrateAPI.ListWorkers(ctx, &ateapi.ListWorkersRequest{}) if err != nil { t.Fatalf("failed to list workers: %v", err) } @@ -1660,10 +1660,10 @@ func TestWorkerPodDeletion(t *testing.T) { // Wait for the actor to be marked as CRASHED t.Logf("Waiting for actor %q to transition to CRASHED...", actorName) - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_CRASHED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_CRASHED) - crashed, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName}, + crashed, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName}, }) if err != nil { t.Fatalf("failed to get crashed actor %q: %v", actorName, err) @@ -1684,9 +1684,9 @@ func TestWorkerPodDeletion(t *testing.T) { // Verify the worker is cleaned up (deleted) from store t.Logf("Verifying worker for pod %s/%s is removed from store...", podNamespace, podName) deadline := time.Now().Add(30 * time.Second) - var lastWorkers []*ateapipb.Worker + var lastWorkers []*ateapi.Worker for time.Now().Before(deadline) { - workersResp, err = clients.SubstrateAPI.ListWorkers(ctx, &ateapipb.ListWorkersRequest{}) + workersResp, err = clients.SubstrateAPI.ListWorkers(ctx, &ateapi.ListWorkersRequest{}) if err != nil { t.Fatalf("failed to list workers: %v", err) } @@ -1717,32 +1717,32 @@ func TestSandboxCrashIsReported(t *testing.T) { ctx := context.Background() clients := e2e.GetClients() - at, err := createActorTemplate(ctx, t, clients, nsObj, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY) + at, err := createActorTemplate(ctx, t, clients, nsObj, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY) if err != nil { t.Fatalf("failed to initialize ActorTemplate: %v", err) } actorName := "sandbox-crash-actor-" + nsObj.Name - actorRef := &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName} + actorRef := &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName} t.Cleanup(func() { cleanupCtx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() - _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapipb.DeleteActorRequest{Actor: actorRef}) + _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapi.DeleteActorRequest{Actor: actorRef}) }) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, ActorTemplate: e2e.TemplateRef(at), }}); err != nil { t.Fatalf("failed to create Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("failed to resume Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actorRef}) + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("failed to get Actor: %v", err) } @@ -1752,9 +1752,9 @@ func TestSandboxCrashIsReported(t *testing.T) { } e2e.KillActorSandbox(ctx, t, clients, assignment.GetWorkerNamespace(), assignment.GetWorkerPod(), actor.GetMetadata().GetUid()) - waitForActorStateWithTimeout(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_CRASHED, 2*time.Minute) + waitForActorStateWithTimeout(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_CRASHED, 2*time.Minute) - crashed, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actorRef}) + crashed, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("failed to get crashed Actor: %v", err) } @@ -1769,17 +1769,17 @@ func TestSandboxCrashIsReported(t *testing.T) { t.Errorf("worker pod %s/%s is gone: %v", assignment.GetWorkerNamespace(), assignment.GetWorkerPod(), err) } - reverted, err := clients.SubstrateAPI.RevertActor(ctx, &ateapipb.RevertActorRequest{Actor: actorRef}) + reverted, err := clients.SubstrateAPI.RevertActor(ctx, &ateapi.RevertActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("RevertActor from CRASHED: %v", err) } - if got := reverted.GetActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := reverted.GetActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("state after revert = %v, want SUSPENDED", got) } - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("failed to resume the reverted Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) if _, err := callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}); err != nil { t.Fatalf("failed to call the reverted Actor: %v", err) } @@ -1791,31 +1791,31 @@ func TestRevertCrashedActor(t *testing.T) { ctx := context.Background() clients := e2e.GetClients() - at, err := createActorTemplate(ctx, t, clients, nsObj, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY) + at, err := createActorTemplate(ctx, t, clients, nsObj, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY) if err != nil { t.Fatalf("failed to initialize ActorTemplate: %v", err) } actorName := "revert-crash-actor-" + nsObj.Name - actorRef := &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorName} + actorRef := &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorName} t.Cleanup(func() { cleanupCtx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() - _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapipb.DeleteActorRequest{Actor: actorRef}) + _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapi.DeleteActorRequest{Actor: actorRef}) }) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorName}, ActorTemplate: e2e.TemplateRef(at), }}); err != nil { t.Fatalf("failed to create Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_SUSPENDED) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("failed to resume Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) resp, err := callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}) if err != nil { @@ -1823,7 +1823,7 @@ func TestRevertCrashedActor(t *testing.T) { } validateCounterResponse(t, resp, "before snapshot", 1, 1) - suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef, Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) + suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef, Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}) if err != nil { t.Fatalf("failed to suspend Actor: %v", err) } @@ -1832,10 +1832,10 @@ func TestRevertCrashedActor(t *testing.T) { t.Fatal("suspend wrote no external snapshot") } - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("failed to resume Actor after suspend: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) resp, err = callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}) if err != nil { @@ -1843,7 +1843,7 @@ func TestRevertCrashedActor(t *testing.T) { } validateCounterResponse(t, resp, "before crash", 2, 2) - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actorRef}) + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("failed to get Actor: %v", err) } @@ -1860,9 +1860,9 @@ func TestRevertCrashedActor(t *testing.T) { if err := clients.K8s.CoreV1().Pods(podNamespace).Delete(ctx, podName, metav1.DeleteOptions{}); err != nil { t.Fatalf("failed to delete worker pod %s/%s: %v", podNamespace, podName, err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_CRASHED) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_CRASHED) - crashed, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actorRef}) + crashed, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("failed to get crashed Actor: %v", err) } @@ -1870,11 +1870,11 @@ func TestRevertCrashedActor(t *testing.T) { t.Fatalf("crashed actor AssignedNode = %q, want %q", got, nodeName) } - reverted, err := clients.SubstrateAPI.RevertActor(ctx, &ateapipb.RevertActorRequest{Actor: actorRef}) + reverted, err := clients.SubstrateAPI.RevertActor(ctx, &ateapi.RevertActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("RevertActor from CRASHED: %v", err) } - if got := reverted.GetActor().GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := reverted.GetActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("state after revert = %v, want SUSPENDED", got) } if got := durableSnapshotURI(reverted.GetActor().GetStatus()); got != snapshotURI { @@ -1887,10 +1887,10 @@ func TestRevertCrashedActor(t *testing.T) { t.Fatalf("assigned node after revert = %q, want empty", got) } - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatalf("failed to resume crashed-and-reverted Actor: %v", err) } - waitForActorState(ctx, t, clients, actorName, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorName, ateapi.ActorState_ACTOR_STATE_RUNNING) resp, err = callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorName}) if err != nil { diff --git a/internal/e2e/suites/demo/golden_test.go b/internal/e2e/suites/demo/golden_test.go index b11e83cd95..c8a7c0acfe 100644 --- a/internal/e2e/suites/demo/golden_test.go +++ b/internal/e2e/suites/demo/golden_test.go @@ -19,17 +19,17 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestGoldenSnapshotLifecycle(t *testing.T) { - for _, fidelity := range []ateapipb.SnapshotFidelity{ - ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, - ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, + for _, fidelity := range []ateapi.SnapshotFidelity{ + ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, } { t.Run(fidelity.String(), func(t *testing.T) { ctx := t.Context() @@ -45,12 +45,12 @@ func TestGoldenSnapshotLifecycle(t *testing.T) { t.Cleanup(func() { cleanupCtx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - _, _ = clients.SubstrateAPI.DeleteAtespace(cleanupCtx, &ateapipb.DeleteAtespaceRequest{Atespace: &ateapipb.ObjectRef{Name: atespace}}) + _, _ = clients.SubstrateAPI.DeleteAtespace(cleanupCtx, &ateapi.DeleteAtespaceRequest{Atespace: &ateapi.ObjectRef{Name: atespace}}) }) created := e2e.CreateSubstrateCounterTemplate(ctx, t, clients, ns.Name, e2e.SubstrateTemplateOptions{ Atespace: atespace, Name: "counter", PoolName: "counter", PoolReplicas: 1, Labels: map[string]string{"golden-e2e": ns.Name}, - SnapshotConfig: &ateapipb.SnapshotConfig{ + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: "gs://" + env["BUCKET_NAME"] + "/" + atespace, PreferredFidelity: fidelity, }, @@ -58,7 +58,7 @@ func TestGoldenSnapshotLifecycle(t *testing.T) { templateRef := e2e.TemplateRef(created) - tmpl, err := clients.SubstrateAPI.GetActorTemplate(ctx, &ateapipb.GetActorTemplateRequest{ActorTemplate: templateRef}) + tmpl, err := clients.SubstrateAPI.GetActorTemplate(ctx, &ateapi.GetActorTemplateRequest{ActorTemplate: templateRef}) if err != nil { t.Fatal(err) } @@ -69,7 +69,7 @@ func TestGoldenSnapshotLifecycle(t *testing.T) { if got := tagRef.GetName(); got != tmpl.GetMetadata().GetUid() { t.Fatalf("golden tag name = %q, want template UID %q", got, tmpl.GetMetadata().GetUid()) } - tag, err := clients.SubstrateAPI.GetTag(ctx, &ateapipb.GetTagRequest{Tag: tagRef}) + tag, err := clients.SubstrateAPI.GetTag(ctx, &ateapi.GetTagRequest{Tag: tagRef}) if err != nil { t.Fatal(err) } @@ -86,14 +86,14 @@ func TestGoldenSnapshotLifecycle(t *testing.T) { if !uri.OwnedBy(resources.TagSnapshotOwner(atespace, tag.GetMetadata().GetUid())) { t.Fatalf("golden snapshot %s is not owned by its tenant tag", uri) } - actorRef := &ateapipb.ObjectRef{Atespace: atespace, Name: "clone"} + actorRef := &ateapi.ObjectRef{Atespace: atespace, Name: "clone"} t.Cleanup(func() { cleanupCtx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapipb.DeleteActorRequest{Actor: actorRef}) + _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapi.DeleteActorRequest{Actor: actorRef}) }) - actor, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: actorRef.Name}, ActorTemplate: templateRef, + actor, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: actorRef.Name}, ActorTemplate: templateRef, }}) if err != nil { t.Fatal(err) @@ -101,7 +101,7 @@ func TestGoldenSnapshotLifecycle(t *testing.T) { if got := durableSnapshotURI(actor.GetStatus()); got != uri.String() { t.Fatalf("clone snapshot = %q, want golden %q", got, uri) } - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: actorRef}); err != nil { t.Fatal(err) } response, err := callActor(t, resources.ActorRefFromObjectRef(actorRef)) @@ -110,16 +110,16 @@ func TestGoldenSnapshotLifecycle(t *testing.T) { } validateCounterResponse(t, response, "golden restore", 1, 1) // Delete the borrower before collecting the template's snapshot. - if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: actorRef}); err != nil { + if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: actorRef}); err != nil { t.Fatal(err) } - if _, err := clients.SubstrateAPI.DeleteActorTemplate(ctx, &ateapipb.DeleteActorTemplateRequest{ActorTemplate: templateRef}); err != nil { + if _, err := clients.SubstrateAPI.DeleteActorTemplate(ctx, &ateapi.DeleteActorTemplateRequest{ActorTemplate: templateRef}); err != nil { t.Fatal(err) } - if _, err := clients.SubstrateAPI.GetTag(ctx, &ateapipb.GetTagRequest{Tag: tagRef}); status.Code(err) != codes.NotFound { + if _, err := clients.SubstrateAPI.GetTag(ctx, &ateapi.GetTagRequest{Tag: tagRef}); status.Code(err) != codes.NotFound { t.Fatalf("golden tag after template deletion = %v, want NotFound", err) } - if _, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{Actor: tagRef}); status.Code(err) != codes.NotFound { + if _, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{Actor: tagRef}); status.Code(err) != codes.NotFound { t.Fatalf("golden actor after template deletion = %v, want NotFound", err) } t.Logf("golden lifecycle passed: fidelity=%v, snapshot=%s", fidelity, uri) diff --git a/internal/e2e/suites/demo/termination_test.go b/internal/e2e/suites/demo/termination_test.go index 326fbafbaf..5cd6ccf344 100644 --- a/internal/e2e/suites/demo/termination_test.go +++ b/internal/e2e/suites/demo/termination_test.go @@ -19,9 +19,9 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -44,41 +44,41 @@ func TestGracefulWorkerTermination(t *testing.T) { ctx := context.Background() clients := e2e.GetClients() - at, err := createActorTemplate(ctx, t, clients, nsObj, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY) + at, err := createActorTemplate(ctx, t, clients, nsObj, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY) if err != nil { t.Fatalf("failed to initialize ActorTemplate: %v", err) } actorID := "graceful-term-" + nsObj.Name - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorID}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorID}, ActorTemplate: e2e.TemplateRef(at), }, }); err != nil { t.Fatalf("failed to create Actor: %v", err) } defer func() { - _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) }() // Bring the actor up on a worker so it is bound to a pod. - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }); err != nil { t.Fatalf("failed to resume Actor: %v", err) } - waitForActorState(ctx, t, clients, actorID, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorID, ateapi.ActorState_ACTOR_STATE_RUNNING) // Set the sigterm sleep interval to 15 seconds. if _, err := callActorPath(t, resources.ActorRef{Atespace: demoAtespace, Name: actorID}, "GET", "/set-sigterm-sleep?duration=15"); err != nil { t.Fatalf("failed to set sigterm sleep: %v", err) } - running, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + running, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) if err != nil { t.Fatalf("failed to get running Actor: %v", err) @@ -103,11 +103,11 @@ func TestGracefulWorkerTermination(t *testing.T) { } // Verify the actor lands in ACTOR_STATE_CRASHED. - waitForActorState(ctx, t, clients, actorID, ateapipb.ActorState_ACTOR_STATE_CRASHED) + waitForActorState(ctx, t, clients, actorID, ateapi.ActorState_ACTOR_STATE_CRASHED) // Verify the pod assignment was cleared. - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) if err != nil { t.Fatalf("failed to get actor: %v", err) @@ -122,7 +122,7 @@ func waitForWorkerRemoved(ctx context.Context, t *testing.T, clients *e2e.Client t.Helper() deadline := time.Now().Add(timeout) for { - resp, err := clients.SubstrateAPI.ListWorkers(ctx, &ateapipb.ListWorkersRequest{}) + resp, err := clients.SubstrateAPI.ListWorkers(ctx, &ateapi.ListWorkersRequest{}) if err == nil { found := false for _, w := range resp.GetWorkers() { @@ -153,41 +153,41 @@ func TestGracefulWorkerTerminationSuspend(t *testing.T) { ctx := context.Background() clients := e2e.GetClients() - at, err := createActorTemplate(ctx, t, clients, nsObj, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY) + at, err := createActorTemplate(ctx, t, clients, nsObj, ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY) if err != nil { t.Fatalf("failed to initialize ActorTemplate: %v", err) } actorID := "graceful-term-suspend-" + nsObj.Name - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{ - Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorID}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorID}, ActorTemplate: e2e.TemplateRef(at), }, }); err != nil { t.Fatalf("failed to create Actor: %v", err) } defer func() { - _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) }() // Bring the actor up on a worker so it is bound to a pod. - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }); err != nil { t.Fatalf("failed to resume Actor: %v", err) } - waitForActorState(ctx, t, clients, actorID, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorID, ateapi.ActorState_ACTOR_STATE_RUNNING) // Set the sigterm sleep interval to 30 seconds. if _, err := callActorPath(t, resources.ActorRef{Atespace: demoAtespace, Name: actorID}, "GET", "/set-sigterm-sleep?duration=30"); err != nil { t.Fatalf("failed to set sigterm sleep: %v", err) } - running, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + running, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) if err != nil { t.Fatalf("failed to get running Actor: %v", err) @@ -214,18 +214,18 @@ func TestGracefulWorkerTerminationSuspend(t *testing.T) { // Suspend the actor. t.Logf("Suspending actor %q during termination", actorID) - _, suspendErr := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + _, suspendErr := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }) - wantState := ateapipb.ActorState_ACTOR_STATE_SUSPENDED + wantState := ateapi.ActorState_ACTOR_STATE_SUSPENDED switch status.Code(suspendErr) { case codes.OK: case codes.FailedPrecondition, codes.Aborted: // Worker deletion can crash the actor before finalize reads it, or // after that read but before its version-guarded update. Both must // preserve the crash and report failure instead of returning success. - wantState = ateapipb.ActorState_ACTOR_STATE_CRASHED + wantState = ateapi.ActorState_ACTOR_STATE_CRASHED t.Logf("Suspend reported concurrent worker deletion: %v", suspendErr) default: t.Fatalf("failed to suspend Actor: %v", suspendErr) @@ -240,8 +240,8 @@ func TestGracefulWorkerTerminationSuspend(t *testing.T) { waitForActorState(ctx, t, clients, actorID, wantState) // Verify the pod assignment was cleared. - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) if err != nil { t.Fatalf("failed to get actor: %v", err) @@ -251,13 +251,13 @@ func TestGracefulWorkerTerminationSuspend(t *testing.T) { } if got := durableSnapshotURI(actor.GetStatus()); got == "" { t.Error("actor lost its completed durable snapshot") - } else if wantState == ateapipb.ActorState_ACTOR_STATE_CRASHED && got != previousSnapshotURI { + } else if wantState == ateapi.ActorState_ACTOR_STATE_CRASHED && got != previousSnapshotURI { t.Errorf("crashed actor snapshot URI = %q, want previous snapshot %q", got, previousSnapshotURI) } - if wantState == ateapipb.ActorState_ACTOR_STATE_CRASHED && actor.GetStatus().GetCrash().GetMessage() == "" { + if wantState == ateapi.ActorState_ACTOR_STATE_CRASHED && actor.GetStatus().GetCrash().GetMessage() == "" { t.Error("crashed actor lost its crash reason") } - if wantState == ateapipb.ActorState_ACTOR_STATE_SUSPENDED && actor.GetStatus().GetCrash() != nil { + if wantState == ateapi.ActorState_ACTOR_STATE_SUSPENDED && actor.GetStatus().GetCrash() != nil { t.Errorf("successful suspend retained a crash record: %v", actor.GetStatus().GetCrash()) } } diff --git a/internal/e2e/suites/demo/updatetemplate_test.go b/internal/e2e/suites/demo/updatetemplate_test.go index e886c81435..2ba987ccea 100644 --- a/internal/e2e/suites/demo/updatetemplate_test.go +++ b/internal/e2e/suites/demo/updatetemplate_test.go @@ -20,9 +20,9 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // TestUpdateTemplateLifecycle covers repointing a suspended actor at a @@ -36,19 +36,19 @@ func TestUpdateTemplateLifecycle(t *testing.T) { t.Parallel() tests := []struct { name string - fidelity ateapipb.SnapshotFidelity + fidelity ateapi.SnapshotFidelity }{ { name: "preferredFidelity:VOLUMES", - fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, + fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, }, { name: "preferredFidelity:MEMORY", - fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, + fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, }, { name: "preferredFidelity:ROOTFS", - fidelity: ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, + fidelity: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS, }, } for _, test := range tests { @@ -59,7 +59,7 @@ func TestUpdateTemplateLifecycle(t *testing.T) { } } -func runUpdateTemplateTestCase(t *testing.T, fidelity ateapipb.SnapshotFidelity) { +func runUpdateTemplateTestCase(t *testing.T, fidelity ateapi.SnapshotFidelity) { nsObj := e2e.CreateNamespace(t) ctx := context.Background() clients := e2e.GetClients() @@ -75,7 +75,7 @@ func runUpdateTemplateTestCase(t *testing.T, fidelity ateapipb.SnapshotFidelity) // proves B's spec took effect and re-reads the preserved data. nameA, nameB := "update-a-"+nsObj.Name, "update-b-"+nsObj.Name createdA := createUpdateTestTemplate(ctx, t, clients, nsObj, nameA, "update-a", env["BUCKET_NAME"], fidelity, nil) - createdB := createUpdateTestTemplate(ctx, t, clients, nsObj, nameB, "update-b", env["BUCKET_NAME"], fidelity, func(tmpl *ateapipb.ActorTemplate) { + createdB := createUpdateTestTemplate(ctx, t, clients, nsObj, nameB, "update-b", env["BUCKET_NAME"], fidelity, func(tmpl *ateapi.ActorTemplate) { ctr := tmpl.Containers[0] ctr.Command = append(ctr.Command, "--validate-existing-file-path=/home/counter/a.txt") }) @@ -84,37 +84,37 @@ func runUpdateTemplateTestCase(t *testing.T, fidelity ateapipb.SnapshotFidelity) // Create an Actor from template A; a fresh actor sits SUSPENDED. // actorID := "update-" + nsObj.Name - refA := &ateapipb.ObjectRef{Atespace: demoAtespace, Name: nameA} - refB := &ateapipb.ObjectRef{Atespace: demoAtespace, Name: nameB} + refA := &ateapi.ObjectRef{Atespace: demoAtespace, Name: nameA} + refB := &ateapi.ObjectRef{Atespace: demoAtespace, Name: nameB} t.Logf("Creating Actor %q from substrate template %q...", actorID, nameA) - createResp, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: demoAtespace, Name: actorID}, + createResp, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: demoAtespace, Name: actorID}, ActorTemplate: refA, }}) if err != nil { t.Fatalf("failed to create Actor: %v", err) } defer func() { - clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) }() - if got := createResp.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := createResp.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("created Actor state = %v, want SUSPENDED", got) } // Run under template A and write to the data volume (every call bumps the // file counter the workload keeps in the durable dir). t.Logf("Resuming Actor %q under template A...", actorID) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }); err != nil { t.Fatalf("failed to resume Actor: %v", err) } // The first resume also absorbs the freshly created pool's worker // startup, so it gets a longer budget than the steady-state waits. - waitForActorStateWithTimeout(ctx, t, clients, actorID, ateapipb.ActorState_ACTOR_STATE_RUNNING, 120*time.Second) + waitForActorStateWithTimeout(ctx, t, clients, actorID, ateapi.ActorState_ACTOR_STATE_RUNNING, 120*time.Second) for i := 1; i <= 2; i++ { resp, err := callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorID}) @@ -130,16 +130,16 @@ func runUpdateTemplateTestCase(t *testing.T, fidelity ateapipb.SnapshotFidelity) // the resume above) must survive the suspend. // t.Logf("Suspending Actor %q...", actorID) - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }); err != nil { t.Fatalf("failed to suspend Actor: %v", err) } - waitForActorState(ctx, t, clients, actorID, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(ctx, t, clients, actorID, ateapi.ActorState_ACTOR_STATE_SUSPENDED) - suspended, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + suspended, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) if err != nil { t.Fatalf("failed to get suspended Actor: %v", err) @@ -158,7 +158,7 @@ func runUpdateTemplateTestCase(t *testing.T, fidelity ateapipb.SnapshotFidelity) // Repoint the suspended actor at template B. // t.Logf("Repointing Actor %q at template %q...", actorID, nameB) - updated, err := clients.SubstrateAPI.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: &ateapipb.Actor{ + updated, err := clients.SubstrateAPI.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ Metadata: suspended.GetMetadata(), ActorTemplate: refB, }}) @@ -168,7 +168,7 @@ func runUpdateTemplateTestCase(t *testing.T, fidelity ateapipb.SnapshotFidelity) if got := updated.GetActorTemplate().GetName(); got != nameB { t.Errorf("updated Actor actor_template = %q, want %q", got, nameB) } - if got := updated.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := updated.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Errorf("updated Actor state = %v, want SUSPENDED", got) } @@ -178,12 +178,12 @@ func runUpdateTemplateTestCase(t *testing.T, fidelity ateapipb.SnapshotFidelity) // and B's --validate-existing-file-path reads A's file back). // t.Logf("Resuming Actor %q under template B...", actorID) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }); err != nil { t.Fatalf("failed to resume Actor after template update: %v", err) } - waitForActorState(ctx, t, clients, actorID, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorID, ateapi.ActorState_ACTOR_STATE_RUNNING) resp, err := callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorID}) if err != nil { @@ -203,16 +203,16 @@ func runUpdateTemplateTestCase(t *testing.T, fidelity ateapipb.SnapshotFidelity) // template B, since templates can only be updated while SUSPENDED) and // preserves the in-memory counter when preferredFidelity is MEMORY. t.Logf("Pausing Actor %q under template B...", actorID) - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_ASYNCHRONOUS}, }); err != nil { t.Fatalf("failed to pause Actor under template B: %v", err) } waitForActorPaused(ctx, t, clients, actorID) - paused, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + paused, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) if err != nil { t.Fatalf("failed to get paused Actor: %v", err) @@ -222,12 +222,12 @@ func runUpdateTemplateTestCase(t *testing.T, fidelity ateapipb.SnapshotFidelity) } t.Logf("Resuming Actor %q from pause under template B...", actorID) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }); err != nil { t.Fatalf("failed to resume Actor from pause under template B: %v", err) } - waitForActorState(ctx, t, clients, actorID, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorID, ateapi.ActorState_ACTOR_STATE_RUNNING) resp, err = callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorID}) if err != nil { @@ -238,9 +238,9 @@ func runUpdateTemplateTestCase(t *testing.T, fidelity ateapipb.SnapshotFidelity) // VOLUMES neither. wantMemAfterPause, wantRootfsAfterPause := 2, 2 switch fidelity { - case ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES: + case ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES: wantMemAfterPause, wantRootfsAfterPause = 1, 1 - case ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS: + case ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS: wantMemAfterPause = 1 } validateCounterResponse(t, resp, "after pause/resume under template B", wantMemAfterPause, 4) @@ -253,14 +253,14 @@ func runUpdateTemplateTestCase(t *testing.T, fidelity ateapipb.SnapshotFidelity) // what captured it — the next resume has to judge by // external_snapshot.actor_template_uid (A) and restore data-only again. t.Logf("Reverting Actor %q under template B...", actorID) - reverted, err := clients.SubstrateAPI.RevertActor(ctx, &ateapipb.RevertActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + reverted, err := clients.SubstrateAPI.RevertActor(ctx, &ateapi.RevertActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) if err != nil { t.Fatalf("failed to revert Actor under template B: %v", err) } revertedStatus := reverted.GetActor().GetStatus() - if got := revertedStatus.GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if got := revertedStatus.GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("reverted Actor state = %v, want SUSPENDED", got) } // Resume prefers a local checkpoint over the external snapshot, so one @@ -278,12 +278,12 @@ func runUpdateTemplateTestCase(t *testing.T, fidelity ateapipb.SnapshotFidelity) } t.Logf("Resuming Actor %q after the revert...", actorID) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }); err != nil { t.Fatalf("failed to resume Actor after the revert: %v", err) } - waitForActorState(ctx, t, clients, actorID, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorID, ateapi.ActorState_ACTOR_STATE_RUNNING) resp, err = callActor(t, resources.ActorRef{Atespace: demoAtespace, Name: actorID}) if err != nil { @@ -304,15 +304,15 @@ func runUpdateTemplateTestCase(t *testing.T, fidelity ateapipb.SnapshotFidelity) // so the actor is no longer repointed and the next resume restores at the // snapshot's own scope rather than being forced down to data-only. t.Logf("Suspending Actor %q again...", actorID) - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }); err != nil { t.Fatalf("failed to suspend Actor again: %v", err) } - waitForActorState(ctx, t, clients, actorID, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) - suspended, err = clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: demoAtespace, Name: actorID}, + waitForActorState(ctx, t, clients, actorID, ateapi.ActorState_ACTOR_STATE_SUSPENDED) + suspended, err = clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: demoAtespace, Name: actorID}, }) if err != nil { t.Fatalf("failed to get re-suspended Actor: %v", err) @@ -325,7 +325,7 @@ func runUpdateTemplateTestCase(t *testing.T, fidelity ateapipb.SnapshotFidelity) // createUpdateTestTemplate creates a per-test WorkerPool plus a substrate // ActorTemplate copying the deployed counter fixture's resolved runtime, // capturing at the scope under test on suspend. -func createUpdateTestTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, name, poolName, bucket string, fidelity ateapipb.SnapshotFidelity, modify func(*ateapipb.ActorTemplate)) *ateapipb.ActorTemplate { +func createUpdateTestTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, name, poolName, bucket string, fidelity ateapi.SnapshotFidelity, modify func(*ateapi.ActorTemplate)) *ateapi.ActorTemplate { t.Helper() return e2e.CreateSubstrateCounterTemplate(ctx, t, clients, nsObj.Name, e2e.SubstrateTemplateOptions{ Atespace: demoAtespace, @@ -333,7 +333,7 @@ func createUpdateTestTemplate(ctx context.Context, t *testing.T, clients *e2e.Cl PoolName: poolName, PoolReplicas: 2, Labels: map[string]string{"demo": nsObj.Name}, - SnapshotConfig: &ateapipb.SnapshotConfig{ + SnapshotConfig: &ateapi.SnapshotConfig{ StorageLocation: "gs://" + bucket + "/ate-demo-" + nsObj.Name, PreferredFidelity: fidelity, }, diff --git a/internal/e2e/suites/egresscredinject/egresscredinject_test.go b/internal/e2e/suites/egresscredinject/egresscredinject_test.go index f0d0750471..f557743730 100644 --- a/internal/e2e/suites/egresscredinject/egresscredinject_test.go +++ b/internal/e2e/suites/egresscredinject/egresscredinject_test.go @@ -33,10 +33,10 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/actoridjwt" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -128,9 +128,9 @@ func TestActorEgressCredentialInjection(t *testing.T) { const id = "probe-credinject" createAndResumeActor(t, ctx, clients, id, echoHost) - waitForActorState(t, ctx, clients, id, ateapipb.ActorState_ACTOR_STATE_RUNNING) - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: probeNamespace, Name: id}, + waitForActorState(t, ctx, clients, id, ateapi.ActorState_ACTOR_STATE_RUNNING) + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: probeNamespace, Name: id}, }) if err != nil { t.Fatalf("GetActor %q: %v", id, err) @@ -274,7 +274,7 @@ func assertEchoedHeaders(t *testing.T, step string, resp fetchResponse) map[stri // checkActorJWT checks the claims of an injected actor JWT against the actor // and the echo rules' actor_jwt source. It does not verify the signature. -func checkActorJWT(t *testing.T, jwt string, actor *ateapipb.ResourceMetadata) { +func checkActorJWT(t *testing.T, jwt string, actor *ateapi.ResourceMetadata) { t.Helper() parts := strings.Split(jwt, ".") if len(parts) != 3 { @@ -361,26 +361,26 @@ func probeFetch(t *testing.T, ctx context.Context, rc *e2e.RouterClient, id, ori // name, whose rules inject a credential the provider resolves. func createAndResumeActor(t *testing.T, ctx context.Context, clients *e2e.Clients, id, echoHost string) { t.Helper() - ref := &ateapipb.ObjectRef{Atespace: probeNamespace, Name: id} + ref := &ateapi.ObjectRef{Atespace: probeNamespace, Name: id} // NotFound is the normal case on a fresh run. Other errors don't stop the // test, but they are logged in case CreateActor then fails. - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: ref}); err != nil && status.Code(err) != codes.NotFound { + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref}); err != nil && status.Code(err) != codes.NotFound { t.Logf("removing leftover actor %q: SuspendActor: %v", id, err) } - if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref}); err != nil && status.Code(err) != codes.NotFound { + if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}); err != nil && status.Code(err) != codes.NotFound { t.Logf("removing leftover actor %q: DeleteActor: %v", id, err) } - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: probeNamespace, Name: id}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: probeNamespace, Name: probeTemplate}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: probeNamespace, Name: id}, + ActorTemplate: &ateapi.ObjectRef{Atespace: probeNamespace, Name: probeTemplate}, }}); err != nil { t.Fatalf("CreateActor %q: %v", id, err) } t.Cleanup(func() { - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: ref}); err != nil { + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref}); err != nil { t.Logf("cleanup: SuspendActor %q: %v", id, err) } - if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref}); err != nil { + if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}); err != nil { t.Logf("cleanup: DeleteActor %q failed, actor leaked (remove with: kubectl ate delete actor %s -a %s): %v", id, id, probeNamespace, err) } }) @@ -390,7 +390,7 @@ func createAndResumeActor(t *testing.T, ctx context.Context, clients *e2e.Client echoHTTPSRule.Https.Effects.ReplaceHeaders = append(echoHTTPSRule.Https.Effects.ReplaceHeaders, actorJWTInjection()) echoHTTPRule := e2e.EgressInjectHeaderHTTP("Authorization", "Bearer ", e2e.CredentialInjectionURI, echoHost, echoHost+".cluster.local") echoHTTPRule.Http.Effects.ReplaceHeaders = append(echoHTTPRule.Http.Effects.ReplaceHeaders, actorJWTInjection()) - rules := []*ateapipb.EgressRule{echoHTTPSRule, echoHTTPRule} + rules := []*ateapi.EgressRule{echoHTTPSRule, echoHTTPRule} for _, credential := range []struct { host string uri string @@ -406,27 +406,27 @@ func createAndResumeActor(t *testing.T, ctx context.Context, clients *e2e.Client } e2e.EnsureEgressPolicy(t, ctx, clients, ref, rules...) - if _, err := clients.SubstrateAPI.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := clients.SubstrateAPI.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor %q: %v", id, err) } } -func actorJWTInjection() *ateapipb.CredentialHeader { - return &ateapipb.CredentialHeader{ +func actorJWTInjection() *ateapi.CredentialHeader { + return &ateapi.CredentialHeader{ Header: actorJWTHeader, - ActorJwt: &ateapipb.ActorJwtSource{ + ActorJwt: &ateapi.ActorJwtSource{ Audiences: []string{actorJWTAudience}, ExpirationSeconds: actorJWTLifetime, }, } } -func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, actorName string, want ateapipb.ActorState) { +func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, actorName string, want ateapi.ActorState) { t.Helper() deadline := time.Now().Add(60 * time.Second) for time.Now().Before(deadline) { - resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: probeNamespace, Name: actorName}, + resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: probeNamespace, Name: actorName}, }) if err == nil && resp.GetStatus().GetState() == want { return diff --git a/internal/e2e/suites/egressmitm/egressmitm_test.go b/internal/e2e/suites/egressmitm/egressmitm_test.go index 014a4c1a88..d862a78b44 100644 --- a/internal/e2e/suites/egressmitm/egressmitm_test.go +++ b/internal/e2e/suites/egressmitm/egressmitm_test.go @@ -32,9 +32,9 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const probeTemplate = "probe" @@ -97,7 +97,7 @@ func TestActorEgressMITMTrust(t *testing.T) { const id = "probe-mitm" createAndResumeActor(t, ctx, clients, id, mitm, passthrough) - waitForActorState(t, ctx, clients, id, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(t, ctx, clients, probeNamespace, id, ateapi.ActorState_ACTOR_STATE_RUNNING) rc, err := e2e.NewRouterClient(t, ctx) if err != nil { @@ -346,12 +346,12 @@ func holdsCertificate(t *testing.T, bundle, commonName string) bool { func createAndResumeActor(t *testing.T, ctx context.Context, clients *e2e.Clients, id string, mitm, passthrough e2e.Server) { t.Helper() - ref := &ateapipb.ObjectRef{Atespace: probeNamespace, Name: id} - _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: ref}) - _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref}) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: probeNamespace, Name: id}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: probeNamespace, Name: probeTemplate}, + ref := &ateapi.ObjectRef{Atespace: probeNamespace, Name: id} + _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref}) + _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}) + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: probeNamespace, Name: id}, + ActorTemplate: &ateapi.ObjectRef{Atespace: probeNamespace, Name: probeTemplate}, }}); err != nil { t.Fatalf("CreateActor %q: %v", id, err) } @@ -366,22 +366,22 @@ func createAndResumeActor(t *testing.T, ctx context.Context, clients *e2e.Client e2e.EgressAllowPassthroughOnPorts([]int32{8443}, passthrough.SvcName()+".cluster.local"), ) t.Cleanup(func() { - _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: ref}) - if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref}); err != nil { + _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref}) + if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}); err != nil { t.Logf("cleanup: DeleteActor %q failed, actor leaked (remove with: kubectl ate delete actor %s -a %s): %v", id, id, probeNamespace, err) } }) - if _, err := clients.SubstrateAPI.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := clients.SubstrateAPI.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor %q: %v", id, err) } } -func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, actorName string, want ateapipb.ActorState) { +func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, actorName string, want ateapi.ActorState) { t.Helper() deadline := time.Now().Add(60 * time.Second) for time.Now().Before(deadline) { - resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: probeNamespace, Name: actorName}, + resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: atespace, Name: actorName}, }) if err == nil && resp.GetStatus().GetState() == want { return diff --git a/internal/e2e/suites/egressmitm/goldenboot_test.go b/internal/e2e/suites/egressmitm/goldenboot_test.go new file mode 100644 index 0000000000..fb8a862500 --- /dev/null +++ b/internal/e2e/suites/egressmitm/goldenboot_test.go @@ -0,0 +1,85 @@ +// Copyright 2026 Google LLC +// +// 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 egressmitm + +import ( + "context" + "testing" + + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/internal/e2e" + "go.ate.dev/substrate/internal/preview" +) + +var bootFetchManifests = e2e.SubstrateFixtureManifests{ + Pool: "internal/e2e/fixtures/probe/probe.yaml.tmpl", + Template: "internal/e2e/fixtures/probe/probe-bootfetch-template.yaml.tmpl", +} + +// TestGoldenBootEgress proves an actor has egress while it boots: the +// probe-bootfetch workload fetches an in-cluster origin through the MITM +// gateway before it listens, and exits if it cannot, so its template gets a +// golden snapshot only if the worker tunneled the golden actor's egress +// before the wakeup probe and the gateway admitted the actor while it was +// still resuming. The template's goldenEgressPolicy gives the golden actor its +// policy before the controller resumes it. An actor restored from that +// snapshot then has to fetch again as itself before its wakeup probe passes, +// which covers the restore paths. +// +// goldenEgressPolicy is a preview feature: install the cluster with its gate +// and pass the gate to the suite, which skips the test otherwise. +// +// ATE_PREVIEW=GoldenEgressPolicy hack/install-ate-kind.sh +// hack/run-e2e-kind.sh ./internal/e2e/suites/egressmitm -run TestGoldenBootEgress -v -args --no-color --preview=GoldenEgressPolicy +func TestGoldenBootEgress(t *testing.T) { + e2e.RequirePreview(t, preview.GateGoldenEgressPolicy) + env, err := e2e.CheckEnv("BUCKET_NAME", "KO_DOCKER_REPO") + if err != nil { + t.Fatalf("CheckEnv failed: %v", err) + } + ctx := context.Background() + clients := e2e.GetClients() + e2e.EnsureEgressTrustBundle(t, ctx, clients) + origin := e2e.DeployServerPod(t, ctx, originSpec("bootfetch-origin")) + + // DeploySubstrateFixture returns once every template has its golden + // snapshot, which is the assertion. + atespace, _ := e2e.DeploySubstrateFixture(t, ctx, clients, bootFetchManifests, env["BUCKET_NAME"], "egressmitm-bootfetch", []string{e2e.EgressTrustBundleName}, + e2e.WithTemplateValue("BOOT_FETCH_HOST", origin.SvcName()), + e2e.WithTemplateValue("BOOT_FETCH_URL", "https://"+origin.SvcName()+"/healthz")) + + t.Run("restore", func(t *testing.T) { + const id = "bootfetch-restore" + ref := &ateapi.ObjectRef{Atespace: atespace, Name: id} + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: id}, + ActorTemplate: &ateapi.ObjectRef{Atespace: atespace, Name: "probe-bootfetch"}, + }}); err != nil { + t.Fatalf("CreateActor %q: %v", id, err) + } + t.Cleanup(func() { + _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref}) + if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}); err != nil { + t.Logf("cleanup: DeleteActor %q failed: %v", id, err) + } + }) + // Before the resume, so the gateway never caches a missing policy. + e2e.EnsureEgressPolicy(t, ctx, clients, ref, e2e.EgressAllowHTTPS(origin.SvcName(), origin.SvcName()+".cluster.local")) + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { + t.Fatalf("ResumeActor %q: %v", id, err) + } + waitForActorState(t, ctx, clients, atespace, id, ateapi.ActorState_ACTOR_STATE_RUNNING) + }) +} diff --git a/internal/e2e/suites/identity/identity_test.go b/internal/e2e/suites/identity/identity_test.go index 690e8155c0..544e953d2c 100644 --- a/internal/e2e/suites/identity/identity_test.go +++ b/internal/e2e/suites/identity/identity_test.go @@ -26,9 +26,9 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const probeTemplate = "probe" @@ -82,7 +82,7 @@ func TestActorIdentity_AfterRestore_IsOwnID_NotGolden(t *testing.T) { // a bundle EXISTS), so the assertions below know the bundle's exact // contents. wantTrust := e2e.AddEgressCA(t, ctx, clients, "ate-e2e-probe-trust") - var tmpl *ateapipb.ActorTemplate + var tmpl *ateapi.ActorTemplate probeNamespace, tmpl = e2e.DeployProbe(t, env["BUCKET_NAME"], "identity", e2e.WithTrustBundle()) // The golden actor's id, for the not-golden assertion below. Coupled to // the reconciler's naming: the golden actor is named after the template's @@ -141,7 +141,7 @@ func TestActorIdentity_AfterRestore_IsOwnID_NotGolden(t *testing.T) { // The projected UID must match the control plane's authoritative view // of this actor, and be distinct per actor even though both actors // were seeded from the same golden snapshot. - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: probeNamespace, Name: id}}) + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: probeNamespace, Name: id}}) if err != nil { t.Fatalf("GetActor %q: %v", id, err) } @@ -180,7 +180,7 @@ func TestActorIdentity_AfterRestore_IsOwnID_NotGolden(t *testing.T) { // must see the rotated contents. rotatedTrust := e2e.AddEgressCA(t, ctx, clients, "ate-e2e-probe-trust-rotated") id := ids[0] - ref := &ateapipb.ObjectRef{Atespace: probeNamespace, Name: id} + ref := &ateapi.ObjectRef{Atespace: probeNamespace, Name: id} // The actor may edit its /etc files, as under Docker or kubelet, and the // edits outlive the suspend like any other rootfs write. etcFiles := []string{"/etc/hosts", "/etc/resolv.conf"} @@ -189,14 +189,14 @@ func TestActorIdentity_AfterRestore_IsOwnID_NotGolden(t *testing.T) { t.Fatalf("actor %q: editing %s: %v %v", id, path, err, out["error"]) } } - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: ref}); err != nil { + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref}); err != nil { t.Fatalf("SuspendActor %q: %v", id, err) } - waitForActorState(t, ctx, clients, id, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + waitForActorState(t, ctx, clients, id, ateapi.ActorState_ACTOR_STATE_SUSPENDED) + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor %q (after suspend): %v", id, err) } - waitForActorState(t, ctx, clients, id, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(t, ctx, clients, id, ateapi.ActorState_ACTOR_STATE_RUNNING) got := whoami(t, ctx, rc, id) if got.File != id { @@ -253,12 +253,12 @@ func seenUIDFor(t *testing.T, seenUIDs map[string]string, id string) string { return "" } -func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, actorName string, want ateapipb.ActorState) { +func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, actorName string, want ateapi.ActorState) { t.Helper() deadline := time.Now().Add(60 * time.Second) for time.Now().Before(deadline) { - resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: probeNamespace, Name: actorName}, + resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: probeNamespace, Name: actorName}, }) if err == nil && resp.GetStatus().GetState() == want { return @@ -270,16 +270,16 @@ func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, func createAndResumeActor(t *testing.T, ctx context.Context, clients *e2e.Clients, id string) { t.Helper() - ref := &ateapipb.ObjectRef{Atespace: probeNamespace, Name: id} + ref := &ateapi.ObjectRef{Atespace: probeNamespace, Name: id} // The actor record lives in the ateapi store and outlives the fixture // namespace, so a failed prior run can leak it and wedge every rerun on // AlreadyExists. Best-effort clear it before creating (DeleteActor // requires SUSPENDED or CRASHED, hence the suspend first). - _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: ref}) - _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref}) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: probeNamespace, Name: id}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: probeNamespace, Name: probeTemplate}, + _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref}) + _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}) + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: probeNamespace, Name: id}, + ActorTemplate: &ateapi.ObjectRef{Atespace: probeNamespace, Name: probeTemplate}, }}); err != nil { t.Fatalf("CreateActor %q: %v", id, err) } @@ -287,14 +287,14 @@ func createAndResumeActor(t *testing.T, ctx context.Context, clients *e2e.Client // Suspend is best-effort: the actor may already be suspended, or may // never have resumed. A failed delete is only logged — the pre-create // clear above keeps the next run working regardless. - _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: ref}) - if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref}); err != nil { + _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref}) + if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}); err != nil { t.Logf("cleanup: DeleteActor %q failed, actor leaked (remove with: kubectl ate delete actor %s -a %s): %v", id, id, probeNamespace, err) } }) // Resume from the golden snapshot (the restore path). - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: probeNamespace, Name: id}}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: probeNamespace, Name: id}}); err != nil { t.Fatalf("ResumeActor %q: %v", id, err) } } diff --git a/internal/e2e/suites/metrics/metrics_test.go b/internal/e2e/suites/metrics/metrics_test.go index 2971911e90..da84fd9fe8 100644 --- a/internal/e2e/suites/metrics/metrics_test.go +++ b/internal/e2e/suites/metrics/metrics_test.go @@ -27,10 +27,10 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -53,19 +53,19 @@ func TestPlatformMetricsEmitted(t *testing.T) { lifecycleBaseline := e2e.LifecycleEventSeries(baselineScrape) // CreateActor requires the atespace to exist first; ignore AlreadyExists. - _, _ = clients.SubstrateAPI.CreateAtespace(ctx, &ateapipb.CreateAtespaceRequest{ - Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: metricsAtespace}}, + _, _ = clients.SubstrateAPI.CreateAtespace(ctx, &ateapi.CreateAtespaceRequest{ + Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: metricsAtespace}}, }) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: metricsAtespace, Name: actorID}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: tmpl.Atespace, Name: tmpl.Name}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: metricsAtespace, Name: actorID}, + ActorTemplate: &ateapi.ObjectRef{Atespace: tmpl.Atespace, Name: tmpl.Name}, }}); err != nil { t.Fatalf("CreateActor: %v", err) } t.Cleanup(func() { - _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: &ateapipb.ObjectRef{Atespace: metricsAtespace, Name: actorID}}) - _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: &ateapipb.ObjectRef{Atespace: metricsAtespace, Name: actorID}}) + _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: &ateapi.ObjectRef{Atespace: metricsAtespace, Name: actorID}}) + _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: &ateapi.ObjectRef{Atespace: metricsAtespace, Name: actorID}}) }) // Resume so the pool has an assigned worker, which the ateapi worker-count @@ -264,8 +264,8 @@ func triggerActorCrash(t *testing.T, ctx context.Context, clients *e2e.Clients, t.Helper() // Get running actor to find its assigned worker pod. - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: metricsAtespace, Name: actorID}, + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: metricsAtespace, Name: actorID}, }) if err != nil { t.Fatalf("GetActor failed: %v", err) @@ -284,17 +284,17 @@ func triggerActorCrash(t *testing.T, ctx context.Context, clients *e2e.Clients, t.Fatalf("Actor %s has no assigned worker pod to delete", actorID) } - waitForStatus(t, ctx, clients, actorID, ateapipb.ActorState_ACTOR_STATE_CRASHED) + waitForStatus(t, ctx, clients, actorID, ateapi.ActorState_ACTOR_STATE_CRASHED) } func resume(t *testing.T, ctx context.Context, clients *e2e.Clients, actorID string) { t.Helper() - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: metricsAtespace, Name: actorID}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: metricsAtespace, Name: actorID}, }); err != nil { t.Fatalf("ResumeActor: %v", err) } - waitForStatus(t, ctx, clients, actorID, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForStatus(t, ctx, clients, actorID, ateapi.ActorState_ACTOR_STATE_RUNNING) } // validateSnapshotPhaseLabels guards atelet's cold-start histograms against a @@ -352,20 +352,20 @@ func validateNodeAttribution(scrape string) error { func suspend(t *testing.T, ctx context.Context, clients *e2e.Clients, actorID string) { t.Helper() - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: metricsAtespace, Name: actorID}, + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: metricsAtespace, Name: actorID}, }); err != nil { t.Fatalf("SuspendActor: %v", err) } - waitForStatus(t, ctx, clients, actorID, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForStatus(t, ctx, clients, actorID, ateapi.ActorState_ACTOR_STATE_SUSPENDED) } -func waitForStatus(t *testing.T, ctx context.Context, clients *e2e.Clients, actorID string, want ateapipb.ActorState) { +func waitForStatus(t *testing.T, ctx context.Context, clients *e2e.Clients, actorID string, want ateapi.ActorState) { t.Helper() deadline := time.Now().Add(2 * time.Minute) for time.Now().Before(deadline) { - resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: metricsAtespace, Name: actorID}, + resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: metricsAtespace, Name: actorID}, }) if err == nil && resp.GetStatus().GetState() == want { return diff --git a/internal/e2e/suites/multiactor/multiactor_test.go b/internal/e2e/suites/multiactor/multiactor_test.go index c495a3845f..f496c557b3 100644 --- a/internal/e2e/suites/multiactor/multiactor_test.go +++ b/internal/e2e/suites/multiactor/multiactor_test.go @@ -22,9 +22,9 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const multiactorTemplate = "probe-multiactor" @@ -94,9 +94,9 @@ func TestTwoActorsShareOneWorker(t *testing.T) { func createActor(t *testing.T, ctx context.Context, clients *e2e.Clients, name string) { t.Helper() - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: multiactorNamespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: multiactorNamespace, Name: multiactorTemplate}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: multiactorNamespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: multiactorNamespace, Name: multiactorTemplate}, }}); err != nil { t.Fatalf("CreateActor %q: %v", name, err) } @@ -104,25 +104,25 @@ func createActor(t *testing.T, ctx context.Context, clients *e2e.Clients, name s cctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() // DeleteActor requires the actor to be suspended. - _, _ = clients.SubstrateAPI.SuspendActor(cctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: multiactorNamespace, Name: name}}) - _, _ = clients.SubstrateAPI.DeleteActor(cctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: multiactorNamespace, Name: name}}) + _, _ = clients.SubstrateAPI.SuspendActor(cctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: multiactorNamespace, Name: name}}) + _, _ = clients.SubstrateAPI.DeleteActor(cctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: multiactorNamespace, Name: name}}) }) } func resumeActor(t *testing.T, ctx context.Context, clients *e2e.Clients, name string) { t.Helper() - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: multiactorNamespace, Name: name}}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: multiactorNamespace, Name: name}}); err != nil { t.Fatalf("ResumeActor %q: %v", name, err) } } func suspendActor(t *testing.T, ctx context.Context, clients *e2e.Clients, name string) { t.Helper() - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: multiactorNamespace, Name: name}}); err != nil { + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: multiactorNamespace, Name: name}}); err != nil { t.Fatalf("SuspendActor %q: %v", name, err) } } @@ -130,12 +130,12 @@ func suspendActor(t *testing.T, ctx context.Context, clients *e2e.Clients, name // workerPodOf is the pod the actor was placed on, once it is RUNNING. func workerPodOf(t *testing.T, ctx context.Context, clients *e2e.Clients, name string) string { t.Helper() - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: multiactorNamespace, Name: name}}) + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: multiactorNamespace, Name: name}}) if err != nil { t.Fatalf("GetActor %q: %v", name, err) } - if got := actor.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_RUNNING { + if got := actor.GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_RUNNING { t.Fatalf("actor %q is %v, want RUNNING", name, got) } pod := actor.GetStatus().GetWorkerAssignment().GetWorkerPod() diff --git a/internal/e2e/suites/networking/arbitraryport_test.go b/internal/e2e/suites/networking/arbitraryport_test.go index af3e6223e7..8fe9a692ce 100644 --- a/internal/e2e/suites/networking/arbitraryport_test.go +++ b/internal/e2e/suites/networking/arbitraryport_test.go @@ -237,10 +237,11 @@ func waitForTunneledRouteReady(t *testing.T, ctx context.Context, router *e2e.Ro // from the first bytes. func dialConnectH2(t *testing.T, ctx context.Context, router *e2e.RouterClient) *http.ClientConn { t.Helper() - address, err := router.ConnectAddress(ctx) + address, stop, err := router.ConnectPortForward(ctx) if err != nil { t.Fatal(err) } + t.Cleanup(stop) protocols := new(http.Protocols) protocols.SetUnencryptedHTTP2(true) transport := &http.Transport{ diff --git a/internal/e2e/suites/networking/microvmclock_test.go b/internal/e2e/suites/networking/microvmclock_test.go index cbbef4a26e..54976e33e3 100644 --- a/internal/e2e/suites/networking/microvmclock_test.go +++ b/internal/e2e/suites/networking/microvmclock_test.go @@ -23,8 +23,8 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/e2e" - "go.ate.dev/substrate/pkg/proto/ateapipb" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -42,7 +42,7 @@ func TestMicroVMClockAfterDelayedRestore(t *testing.T) { actorName, router, actorRef := prepareProtocolActor(t, ctx, "clock") clients := e2e.GetClients() t.Logf("clock evidence host_utc_before_suspend=%s actor=%s/%s", time.Now().UTC().Format(time.RFC3339Nano), actorRef.Atespace, actorName) - beforeSuspend, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{Actor: actorRef.ToObjectRef()}) + beforeSuspend, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{Actor: actorRef.ToObjectRef()}) if err != nil { t.Fatalf("GetActor before SuspendActor: %v", err) } @@ -50,11 +50,11 @@ func TestMicroVMClockAfterDelayedRestore(t *testing.T) { t.Fatalf("actor had no worker assignment before SuspendActor: %v", assignment) } suspendBoundary := time.Now().UTC() - suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: actorRef.ToObjectRef()}) + suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: actorRef.ToObjectRef()}) if err != nil { t.Fatalf("SuspendActor: %v", err) } - if actor := suspended.GetActor(); actor.GetStatus().GetState() != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + if actor := suspended.GetActor(); actor.GetStatus().GetState() != ateapi.ActorState_ACTOR_STATE_SUSPENDED { t.Fatalf("SuspendActor returned state %s, want SUSPENDED", actor.GetStatus().GetState()) } else if actor.GetStatus().GetWorkerAssignment() != nil { t.Fatalf("SuspendActor returned worker assignment %v, want it cleared", actor.GetStatus().GetWorkerAssignment()) @@ -79,7 +79,7 @@ func TestMicroVMClockAfterDelayedRestore(t *testing.T) { }, true) logOriginCertificateValidity(t, ctx, target, rootCA, suspendBoundary) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef.ToObjectRef()}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: actorRef.ToObjectRef()}); err != nil { t.Fatalf("ResumeActor: %v", err) } waitForRouteReady(t, "restored actor ingress readiness", func() (*http.Response, error) { diff --git a/internal/e2e/suites/networking/networking_test.go b/internal/e2e/suites/networking/networking_test.go index 574de7c2de..ce94a214d6 100644 --- a/internal/e2e/suites/networking/networking_test.go +++ b/internal/e2e/suites/networking/networking_test.go @@ -27,12 +27,12 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/atenet" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/localca" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/testcert" - "go.ate.dev/substrate/pkg/proto/ateapipb" corev1 "k8s.io/api/core/v1" discoveryv1 "k8s.io/api/discovery/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -479,46 +479,46 @@ func accessLogField(line, key string) (string, bool) { // createAndResumeActorWithEgress creates an actor from template, gives it an // EgressPolicy of exactly rules (none leaves it without one) and resumes it. -func createAndResumeActorWithEgress(t *testing.T, ctx context.Context, prefix string, template e2e.Fixture, rules ...*ateapipb.EgressRule) (string, string, *ateapipb.Actor) { +func createAndResumeActorWithEgress(t *testing.T, ctx context.Context, prefix string, template e2e.Fixture, rules ...*ateapi.EgressRule) (string, string, *ateapi.Actor) { t.Helper() - actor := &ateapipb.Actor{ActorTemplate: &ateapipb.ObjectRef{Atespace: template.Namespace, Name: template.Name}} + actor := &ateapi.Actor{ActorTemplate: &ateapi.ObjectRef{Atespace: template.Namespace, Name: template.Name}} return createAndResume(t, ctx, prefix, actor, template.Namespace+"/"+template.Name, template.DeployWith, rules) } // createAndResumeSubstrateActor is createAndResumeActor for a substrate // ActorTemplate fixture, referenced by atespace/name instead of the CRD pair. -func createAndResumeSubstrateActor(t *testing.T, ctx context.Context, prefix string, template e2e.SubstrateFixture) (string, string, *ateapipb.Actor) { +func createAndResumeSubstrateActor(t *testing.T, ctx context.Context, prefix string, template e2e.SubstrateFixture) (string, string, *ateapi.Actor) { t.Helper() - actor := &ateapipb.Actor{ActorTemplate: &ateapipb.ObjectRef{Atespace: template.Atespace, Name: template.Name}} + actor := &ateapi.Actor{ActorTemplate: &ateapi.ObjectRef{Atespace: template.Atespace, Name: template.Name}} return createAndResume(t, ctx, prefix, actor, template.Atespace+"/"+template.Name, template.DeployWith, e2e.EgressAllowAll()) } // createAndResume creates the actor, gives it an EgressPolicy with rules (none // when rules is nil), and resumes it. The policy goes in before the resume so // the actor's first outbound connection already finds it. -func createAndResume(t *testing.T, ctx context.Context, prefix string, actor *ateapipb.Actor, source, deployWith string, rules []*ateapipb.EgressRule) (string, string, *ateapipb.Actor) { +func createAndResume(t *testing.T, ctx context.Context, prefix string, actor *ateapi.Actor, source, deployWith string, rules []*ateapi.EgressRule) (string, string, *ateapi.Actor) { t.Helper() clients := e2e.GetClients() actorName := fmt.Sprintf("%s-%d", prefix, time.Now().UnixNano()) - actorRef := &ateapipb.ObjectRef{Atespace: networkingAtespace, Name: actorName} + actorRef := &ateapi.ObjectRef{Atespace: networkingAtespace, Name: actorName} t.Logf("creating actor %s/%s", networkingAtespace, actorName) - _, _ = clients.SubstrateAPI.CreateAtespace(ctx, &ateapipb.CreateAtespaceRequest{ - Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: networkingAtespace}}, + _, _ = clients.SubstrateAPI.CreateAtespace(ctx, &ateapi.CreateAtespaceRequest{ + Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: networkingAtespace}}, }) - actor.Metadata = &ateapipb.ResourceMetadata{Atespace: networkingAtespace, Name: actorName} - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: actor}); err != nil { + actor.Metadata = &ateapi.ResourceMetadata{Atespace: networkingAtespace, Name: actorName} + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: actor}); err != nil { t.Fatalf("CreateActor from %s: %v (deploy the fixture with %s)", source, err, deployWith) } t.Cleanup(func() { - _, _ = clients.SubstrateAPI.SuspendActor(context.Background(), &ateapipb.SuspendActorRequest{Actor: actorRef}) - _, _ = clients.SubstrateAPI.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{Actor: actorRef}) + _, _ = clients.SubstrateAPI.SuspendActor(context.Background(), &ateapi.SuspendActorRequest{Actor: actorRef}) + _, _ = clients.SubstrateAPI.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{Actor: actorRef}) }) if rules != nil { e2e.EnsureEgressPolicy(t, ctx, clients, actorRef, rules...) } - resumeResponse, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: actorRef}) + resumeResponse, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: actorRef}) if err != nil { t.Fatalf("ResumeActor: %v", err) } @@ -566,7 +566,7 @@ func waitForRouteReady(t *testing.T, what string, request func() (*http.Response } } -func assertDirectActorAccess(t *testing.T, ctx context.Context, clients *e2e.Clients, actor *ateapipb.Actor) { +func assertDirectActorAccess(t *testing.T, ctx context.Context, clients *e2e.Clients, actor *ateapi.Actor) { t.Helper() if actor.GetStatus().GetWorkerAssignment().GetWorkerNamespace() == "" || actor.GetStatus().GetWorkerAssignment().GetWorkerPod() == "" { t.Fatalf("resumed Actor has no worker pod assignment: %+v", actor) @@ -919,7 +919,7 @@ func TestBoundedOriginDiagnosticText(t *testing.T) { func prepareProtocolActor(t *testing.T, ctx context.Context, prefix string) (string, *e2e.RouterClient, resources.ActorRef) { t.Helper() https8443 := e2e.EgressAllowHTTPS("*") - https8443.Https.Ports = &ateapipb.Ports{Numbers: []int32{8443}} + https8443.Https.Ports = &ateapi.Ports{Numbers: []int32{8443}} rules := append(e2e.EgressAllowAll(), https8443) _, actorName, _ := createAndResumeActorWithEgress(t, ctx, prefix, egressFixture(), rules...) router := mustRouterClient(t, ctx) diff --git a/internal/e2e/suites/networkpolicy/networkpolicy_test.go b/internal/e2e/suites/networkpolicy/networkpolicy_test.go index b7de552548..2b98c499fc 100644 --- a/internal/e2e/suites/networkpolicy/networkpolicy_test.go +++ b/internal/e2e/suites/networkpolicy/networkpolicy_test.go @@ -33,12 +33,12 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" + "go.ate.dev/substrate/api/ateapi/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/ateclient" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/portforward" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/api/v1alpha1" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const ( @@ -51,20 +51,20 @@ func TestNetworkPolicyLifecycleAndReconciliation(t *testing.T) { clients := e2e.GetClients() wpName := "test-wp-netpol" - wp := &v1alpha1.WorkerPool{ + wp := &atev1.WorkerPool{ ObjectMeta: metav1.ObjectMeta{ Name: wpName, Namespace: nsObj.Name, }, - Spec: v1alpha1.WorkerPoolSpec{ + Spec: atev1.WorkerPoolSpec{ Replicas: 1, WorkerImage: "worker:v1", - SandboxClasses: []v1alpha1.WorkerPoolSandboxClass{{Name: v1alpha1.SandboxClassGvisor}}, + SandboxClasses: []atev1.WorkerPoolSandboxClass{{Name: atev1.SandboxClassGvisor}}, }, } t.Logf("Creating WorkerPool %s/%s...", nsObj.Name, wpName) - if _, err := clients.SubstrateK8s.ApiV1alpha1().WorkerPools(nsObj.Name).Create(ctx, wp, metav1.CreateOptions{}); err != nil { + if _, err := clients.SubstrateK8s.AteV1().WorkerPools(nsObj.Name).Create(ctx, wp, metav1.CreateOptions{}); err != nil { t.Fatalf("failed to create WorkerPool: %v", err) } @@ -123,7 +123,7 @@ func TestNetworkPolicyLifecycleAndReconciliation(t *testing.T) { // Verify Garbage Collection upon deletion t.Logf("Deleting WorkerPool %s/%s and verifying NetworkPolicy GC...", nsObj.Name, wpName) - if err := clients.SubstrateK8s.ApiV1alpha1().WorkerPools(nsObj.Name).Delete(ctx, wpName, metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { + if err := clients.SubstrateK8s.AteV1().WorkerPools(nsObj.Name).Delete(ctx, wpName, metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { t.Fatalf("failed to delete WorkerPool: %v", err) } @@ -156,24 +156,24 @@ func TestNetworkPolicyDataPlaneEnforcement(t *testing.T) { // Create and Resume Actor actorName := "netpol-dataplane-" + nsObj.Name t.Logf("Creating Actor %q in Atespace %q...", actorName, nsObj.Name) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: nsObj.Name, Name: actorName}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: nsObj.Name, Name: actorName}, ActorTemplate: e2e.TemplateRef(at), }}); err != nil { t.Fatalf("failed to create Actor: %v", err) } defer func() { - _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: nsObj.Name, Name: actorName}, + _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: nsObj.Name, Name: actorName}, }) - _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: nsObj.Name, Name: actorName}, + _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: nsObj.Name, Name: actorName}, }) }() t.Logf("Resuming Actor %q...", actorName) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: nsObj.Name, Name: actorName}, + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: nsObj.Name, Name: actorName}, }); err != nil { t.Fatalf("failed to resume Actor: %v", err) } @@ -355,7 +355,7 @@ func (c *probeClient) dial(t *testing.T, ctx context.Context, address string) di // the template. The template lives in an atespace named after the test's k8s // namespace, so its name needs no per-test suffix. SnapshotConfig is copied // from the source, as the CRD-era setup did. -func setupDemoCounterTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients, ns string) (string, *ateapipb.ActorTemplate) { +func setupDemoCounterTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients, ns string) (string, *ateapi.ActorTemplate) { t.Helper() const poolName = "counter" at := e2e.CreateSubstrateCounterTemplate(ctx, t, clients, ns, e2e.SubstrateTemplateOptions{ @@ -372,10 +372,10 @@ func waitForActorRunning(ctx context.Context, t *testing.T, clients *e2e.Clients t.Helper() deadline := time.Now().Add(60 * time.Second) for time.Now().Before(deadline) { - resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: atespace, Name: actorName}, + resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: atespace, Name: actorName}, }) - if err == nil && resp.GetStatus().GetState() == ateapipb.ActorState_ACTOR_STATE_RUNNING { + if err == nil && resp.GetStatus().GetState() == ateapi.ActorState_ACTOR_STATE_RUNNING { t.Logf("Actor %q reached RUNNING state", actorName) return } diff --git a/internal/e2e/suites/parking/parking_test.go b/internal/e2e/suites/parking/parking_test.go index 0eb61b0c1a..76b1d7b1fa 100644 --- a/internal/e2e/suites/parking/parking_test.go +++ b/internal/e2e/suites/parking/parking_test.go @@ -30,9 +30,9 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // parkingAtespace is where deployParkingFixture applies the fixture, and the @@ -73,7 +73,7 @@ func TestRequestParking(t *testing.T) { t.Run("ParkThenServed", func(t *testing.T) { // Occupy the only worker with actor A. resumeActor(ctx, t, clients, actorA) - waitForActorState(ctx, t, clients, actorA, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorA, ateapi.ActorState_ACTOR_STATE_RUNNING) // Request actor B: the pool is full, so the request parks. Freeing // the worker is asynchronous — SuspendActor(A) returns before the @@ -139,7 +139,7 @@ func TestRequestParking(t *testing.T) { // The flake's root cause stranded actors in RESUMING with the worker // claimed (#675): pin that B really converges and a follow-up request // is served warm — a stranded actor would 503 it. - waitForActorState(ctx, t, clients, actorB, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(ctx, t, clients, actorB, ateapi.ActorState_ACTOR_STATE_RUNNING) followUp, err := router.Get(ctx, resources.ActorRef{Atespace: parkingAtespace, Name: actorB}, "/whoami") if err != nil { t.Fatalf("follow-up request failed transport-level: %v", err) @@ -197,7 +197,7 @@ func TestRequestParking(t *testing.T) { // class under test and waits for its golden snapshot. The fixture declares // both halves of the oversubscription: one worker, sized to one of its own // actors (see probe-parking.yaml.tmpl). -func deployParkingFixture(t *testing.T, ctx context.Context, clients *e2e.Clients) *ateapipb.ActorTemplate { +func deployParkingFixture(t *testing.T, ctx context.Context, clients *e2e.Clients) *ateapi.ActorTemplate { t.Helper() env, err := e2e.CheckEnv("BUCKET_NAME") if err != nil { @@ -210,10 +210,10 @@ func deployParkingFixture(t *testing.T, ctx context.Context, clients *e2e.Client return templates[0] } -func createActor(ctx context.Context, t *testing.T, clients *e2e.Clients, at *ateapipb.ActorTemplate, name string) { +func createActor(ctx context.Context, t *testing.T, clients *e2e.Clients, at *ateapi.ActorTemplate, name string) { t.Helper() - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: parkingAtespace, Name: name}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: parkingAtespace, Name: name}, ActorTemplate: e2e.TemplateRef(at), }}); err != nil { t.Fatalf("failed to create actor %q: %v", name, err) @@ -223,19 +223,19 @@ func createActor(ctx context.Context, t *testing.T, clients *e2e.Clients, at *at defer cancel() // Deletion requires the actor to be suspended first; both are // best-effort so one failed cleanup doesn't mask the test result. - _, _ = clients.SubstrateAPI.SuspendActor(cleanupCtx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: parkingAtespace, Name: name}, + _, _ = clients.SubstrateAPI.SuspendActor(cleanupCtx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: parkingAtespace, Name: name}, }) - _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapipb.DeleteActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: parkingAtespace, Name: name}, + _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapi.DeleteActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: parkingAtespace, Name: name}, }) }) } func resumeActor(ctx context.Context, t *testing.T, clients *e2e.Clients, name string) { t.Helper() - if _, err := clients.SubstrateAPI.ResumeActor(ctx, &ateapipb.ResumeActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: parkingAtespace, Name: name}, + if _, err := clients.SubstrateAPI.ResumeActor(ctx, &ateapi.ResumeActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: parkingAtespace, Name: name}, }); err != nil { t.Fatalf("failed to resume actor %q: %v", name, err) } @@ -243,19 +243,19 @@ func resumeActor(ctx context.Context, t *testing.T, clients *e2e.Clients, name s func suspendActor(ctx context.Context, t *testing.T, clients *e2e.Clients, name string) { t.Helper() - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: parkingAtespace, Name: name}, + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: parkingAtespace, Name: name}, }); err != nil { t.Fatalf("failed to suspend actor %q: %v", name, err) } } -func waitForActorState(ctx context.Context, t *testing.T, clients *e2e.Clients, name string, want ateapipb.ActorState) { +func waitForActorState(ctx context.Context, t *testing.T, clients *e2e.Clients, name string, want ateapi.ActorState) { t.Helper() deadline := time.Now().Add(60 * time.Second) for time.Now().Before(deadline) { - resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: parkingAtespace, Name: name}, + resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: parkingAtespace, Name: name}, }) if err == nil && resp.GetStatus().GetState() == want { return diff --git a/internal/e2e/suites/sandboxconfig/classdefault_test.go b/internal/e2e/suites/sandboxconfig/classdefault_test.go index 220cf0689c..59853b3e27 100644 --- a/internal/e2e/suites/sandboxconfig/classdefault_test.go +++ b/internal/e2e/suites/sandboxconfig/classdefault_test.go @@ -36,8 +36,8 @@ import ( "testing" "time" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/e2e" - atev1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" corev1 "k8s.io/api/core/v1" eventsv1 "k8s.io/api/events/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -67,9 +67,9 @@ func TestWorkerPoolFollowsClassDefault(t *testing.T) { ctx := t.Context() clients := e2e.GetClients() - class := atev1alpha1.SandboxClassGvisor + class := atev1.SandboxClassGvisor if e2e.IsMicroVM() { - class = atev1alpha1.SandboxClassMicroVM + class = atev1.SandboxClassMicroVM } base := newestClassDefault(t, ctx, clients, class) t.Logf("Class %q default as installed: %s", class, base.Name) @@ -80,13 +80,13 @@ func TestWorkerPoolFollowsClassDefault(t *testing.T) { // 1. A pool with no configRef resolves to the installed default. ns := e2e.CreateNamespace(t).Name - pool, err := clients.SubstrateK8s.ApiV1alpha1().WorkerPools(ns).Create(ctx, &atev1alpha1.WorkerPool{ + pool, err := clients.SubstrateK8s.AteV1().WorkerPools(ns).Create(ctx, &atev1.WorkerPool{ ObjectMeta: metav1.ObjectMeta{Name: "follows-default", Namespace: ns}, - Spec: atev1alpha1.WorkerPoolSpec{ + Spec: atev1.WorkerPoolSpec{ Replicas: 0, // Never pulled: the pool runs no workers. WorkerImage: "worker:unused", - SandboxClasses: []atev1alpha1.WorkerPoolSandboxClass{{Name: class}}, + SandboxClasses: []atev1.WorkerPoolSandboxClass{{Name: class}}, }, }, metav1.CreateOptions{}) if err != nil { @@ -99,10 +99,10 @@ func TestWorkerPoolFollowsClassDefault(t *testing.T) { // before the installed default's, which is the tie-break should both // carry the same creation second. v2Name := fmt.Sprintf("e2e-%s-default-%s", class, ns) - if _, err := clients.SubstrateK8s.ApiV1alpha1().SandboxConfigs().Create(ctx, &atev1alpha1.SandboxConfig{ + if _, err := clients.SubstrateK8s.AteV1().SandboxConfigs().Create(ctx, &atev1.SandboxConfig{ ObjectMeta: metav1.ObjectMeta{ Name: v2Name, - Annotations: map[string]string{atev1alpha1.SandboxConfigClassDefaultAnnotation: "true"}, + Annotations: map[string]string{atev1.SandboxConfigClassDefaultAnnotation: "true"}, }, Spec: *base.Spec.DeepCopy(), }, metav1.CreateOptions{}); err != nil { @@ -113,7 +113,7 @@ func TestWorkerPoolFollowsClassDefault(t *testing.T) { t.Cleanup(func() { cleanupCtx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - if err := clients.SubstrateK8s.ApiV1alpha1().SandboxConfigs().Delete(cleanupCtx, v2Name, metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { + if err := clients.SubstrateK8s.AteV1().SandboxConfigs().Delete(cleanupCtx, v2Name, metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { t.Errorf("failed to delete SandboxConfig %s: %v", v2Name, err) } }) @@ -132,7 +132,7 @@ func TestWorkerPoolFollowsClassDefault(t *testing.T) { waitForSandboxConfig(t, ctx, clients, pool, v2Name) waitForEvent(t, ctx, clients, pool, switched(base.Name, v2Name)) - if err := clients.SubstrateK8s.ApiV1alpha1().SandboxConfigs().Delete(ctx, v2Name, metav1.DeleteOptions{}); err != nil { + if err := clients.SubstrateK8s.AteV1().SandboxConfigs().Delete(ctx, v2Name, metav1.DeleteOptions{}); err != nil { t.Fatalf("failed to delete SandboxConfig %s: %v", v2Name, err) } waitForSandboxConfig(t, ctx, clients, pool, base.Name) @@ -173,16 +173,16 @@ func TestWorkerPoolFollowsClassDefault(t *testing.T) { // configRef resolves to when the test starts: the newest of the class // annotated as its default, by creation time and then by name, the same rule // atecontroller applies. The test cannot start without one. -func newestClassDefault(t *testing.T, ctx context.Context, clients *e2e.Clients, class atev1alpha1.SandboxClass) *atev1alpha1.SandboxConfig { +func newestClassDefault(t *testing.T, ctx context.Context, clients *e2e.Clients, class atev1.SandboxClass) *atev1.SandboxConfig { t.Helper() - list, err := clients.SubstrateK8s.ApiV1alpha1().SandboxConfigs().List(ctx, metav1.ListOptions{}) + list, err := clients.SubstrateK8s.AteV1().SandboxConfigs().List(ctx, metav1.ListOptions{}) if err != nil { t.Fatalf("failed to list SandboxConfigs: %v", err) } - var best *atev1alpha1.SandboxConfig + var best *atev1.SandboxConfig for i := range list.Items { sc := &list.Items[i] - if sc.Spec.SandboxClass != class || sc.Annotations[atev1alpha1.SandboxConfigClassDefaultAnnotation] != "true" || !sc.DeletionTimestamp.IsZero() { + if sc.Spec.SandboxClass != class || sc.Annotations[atev1.SandboxConfigClassDefaultAnnotation] != "true" || !sc.DeletionTimestamp.IsZero() { continue } if best == nil || best.CreationTimestamp.Before(&sc.CreationTimestamp) || @@ -191,7 +191,7 @@ func newestClassDefault(t *testing.T, ctx context.Context, clients *e2e.Clients, } } if best == nil { - t.Fatalf("no SandboxConfig of class %q is annotated %s=true; the install ships one, see manifests/ate-install", class, atev1alpha1.SandboxConfigClassDefaultAnnotation) + t.Fatalf("no SandboxConfig of class %q is annotated %s=true; the install ships one, see manifests/ate-install", class, atev1.SandboxConfigClassDefaultAnnotation) } return best } @@ -205,28 +205,28 @@ func setClassDefault(t *testing.T, ctx context.Context, clients *e2e.Clients, na value = "true" } patch, err := json.Marshal(map[string]any{"metadata": map[string]any{"annotations": map[string]any{ - atev1alpha1.SandboxConfigClassDefaultAnnotation: value, + atev1.SandboxConfigClassDefaultAnnotation: value, }}}) if err != nil { t.Fatalf("failed to marshal patch: %v", err) } - if _, err := clients.SubstrateK8s.ApiV1alpha1().SandboxConfigs().Patch(ctx, name, types.MergePatchType, patch, metav1.PatchOptions{}); err != nil { + if _, err := clients.SubstrateK8s.AteV1().SandboxConfigs().Patch(ctx, name, types.MergePatchType, patch, metav1.PatchOptions{}); err != nil { t.Fatalf("failed to patch SandboxConfig %s: %v", name, err) } - t.Logf("SandboxConfig %s: %s=%v", name, atev1alpha1.SandboxConfigClassDefaultAnnotation, value) + t.Logf("SandboxConfig %s: %s=%v", name, atev1.SandboxConfigClassDefaultAnnotation, value) } // waitForSandboxConfig blocks until pool's status reports its sandbox class // Resolved, using the SandboxConfig named want, with no switch pending. -func waitForSandboxConfig(t *testing.T, ctx context.Context, clients *e2e.Clients, pool *atev1alpha1.WorkerPool, want string) { +func waitForSandboxConfig(t *testing.T, ctx context.Context, clients *e2e.Clients, pool *atev1.WorkerPool, want string) { t.Helper() ctx, cancel := context.WithTimeout(ctx, stepTimeout) defer cancel() class := pool.Spec.DefaultSandboxClass() - var last *atev1alpha1.WorkerPoolSandboxClassStatus + var last *atev1.WorkerPoolSandboxClassStatus for { - wp, err := clients.SubstrateK8s.ApiV1alpha1().WorkerPools(pool.Namespace).Get(ctx, pool.Name, metav1.GetOptions{}) + wp, err := clients.SubstrateK8s.AteV1().WorkerPools(pool.Namespace).Get(ctx, pool.Name, metav1.GetOptions{}) if err == nil { last = nil for i := range wp.Status.SandboxClasses { @@ -235,7 +235,7 @@ func waitForSandboxConfig(t *testing.T, ctx context.Context, clients *e2e.Client } } if last != nil && last.ConfigRef != nil && last.ConfigRef.Name == want && last.PendingConfigRef == nil && - meta.IsStatusConditionTrue(last.Conditions, atev1alpha1.WorkerPoolSandboxClassConditionResolved) { + meta.IsStatusConditionTrue(last.Conditions, atev1.WorkerPoolSandboxClassConditionResolved) { t.Logf("WorkerPool %s/%s uses SandboxConfig %s", pool.Namespace, pool.Name, want) return } @@ -258,7 +258,7 @@ func waitForSandboxConfigGone(t *testing.T, ctx context.Context, clients *e2e.Cl defer cancel() for { - sc, err := clients.SubstrateK8s.ApiV1alpha1().SandboxConfigs().Get(ctx, name, metav1.GetOptions{}) + sc, err := clients.SubstrateK8s.AteV1().SandboxConfigs().Get(ctx, name, metav1.GetOptions{}) if apierrors.IsNotFound(err) { t.Logf("SandboxConfig %s is gone", name) return @@ -279,7 +279,7 @@ func waitForSandboxConfigGone(t *testing.T, ctx context.Context, clients *e2e.Cl // waitForEvent blocks until an event regarding pool carries note. Events are // recorded asynchronously, so one can trail the status write it reports. -func waitForEvent(t *testing.T, ctx context.Context, clients *e2e.Clients, pool *atev1alpha1.WorkerPool, note string) { +func waitForEvent(t *testing.T, ctx context.Context, clients *e2e.Clients, pool *atev1.WorkerPool, note string) { t.Helper() ctx, cancel := context.WithTimeout(ctx, stepTimeout) defer cancel() @@ -306,7 +306,7 @@ func waitForEvent(t *testing.T, ctx context.Context, clients *e2e.Clients, pool } // poolEvents returns the events regarding pool, oldest first. -func poolEvents(ctx context.Context, clients *e2e.Clients, pool *atev1alpha1.WorkerPool) ([]eventsv1.Event, error) { +func poolEvents(ctx context.Context, clients *e2e.Clients, pool *atev1.WorkerPool) ([]eventsv1.Event, error) { list, err := clients.K8s.EventsV1().Events(pool.Namespace).List(ctx, metav1.ListOptions{}) if err != nil { return nil, err diff --git a/internal/e2e/suites/security/crossatespace_test.go b/internal/e2e/suites/security/crossatespace_test.go index 43e467dcc6..c0590122f3 100644 --- a/internal/e2e/suites/security/crossatespace_test.go +++ b/internal/e2e/suites/security/crossatespace_test.go @@ -37,10 +37,10 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/nodepath" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -130,12 +130,12 @@ func TestCrossAtespaceIsolation(t *testing.T) { // Suspend the victim to free the worker. The durable marker stays on the // worker; the snapshot goes to object storage. - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: ns.b, Name: victim}, + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: ns.b, Name: victim}, }); err != nil { t.Fatalf("SuspendActor %s/%s: %v", ns.b, victim, err) } - waitForActorState(t, ctx, clients, ns.b, victim, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + waitForActorState(t, ctx, clients, ns.b, victim, ateapi.ActorState_ACTOR_STATE_SUSPENDED) // Attacker: the actor in atespace A takes the freed worker. const attacker = "attacker" @@ -219,9 +219,9 @@ func actorHostPath(actorUID string, elem ...string) string { func testTagScopeBoundary(t *testing.T, ctx context.Context, clients *e2e.Clients, rc *e2e.RouterClient, ns atespaces, source string) { t.Helper() - suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: ns.a, Name: source}, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, + suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: ns.a, Name: source}, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}, }) if err != nil { t.Fatalf("SuspendActor %s/%s: %v", ns.a, source, err) @@ -230,18 +230,18 @@ func testTagScopeBoundary(t *testing.T, ctx context.Context, clients *e2e.Client t.Fatalf("suspended actor %s/%s has no external snapshot, so there is nothing for a tag to capture", ns.a, source) } - tagRef := &ateapipb.ObjectRef{Atespace: ns.a, Name: "atespace-a-tag"} + tagRef := &ateapi.ObjectRef{Atespace: ns.a, Name: "atespace-a-tag"} t.Cleanup(func() { - _, _ = clients.SubstrateAPI.DeleteTag(context.Background(), &ateapipb.DeleteTagRequest{Tag: tagRef}) + _, _ = clients.SubstrateAPI.DeleteTag(context.Background(), &ateapi.DeleteTagRequest{Tag: tagRef}) }) // Tags outlive the fixture namespace, so an interrupted run can leave one // behind and wedge reruns on AlreadyExists. Clear it first, best-effort. - _, _ = clients.SubstrateAPI.DeleteTag(ctx, &ateapipb.DeleteTagRequest{Tag: tagRef}) - tag, err := clients.SubstrateAPI.CreateTag(ctx, &ateapipb.CreateTagRequest{ - Tag: &ateapipb.Tag{ - Metadata: &ateapipb.ResourceMetadata{Atespace: ns.a, Name: tagRef.GetName()}, - Scope: ateapipb.TagScope_TAG_SCOPE_ATESPACE, - SourceActor: &ateapipb.ObjectRef{Atespace: ns.a, Name: source}, + _, _ = clients.SubstrateAPI.DeleteTag(ctx, &ateapi.DeleteTagRequest{Tag: tagRef}) + tag, err := clients.SubstrateAPI.CreateTag(ctx, &ateapi.CreateTagRequest{ + Tag: &ateapi.Tag{ + Metadata: &ateapi.ResourceMetadata{Atespace: ns.a, Name: tagRef.GetName()}, + Scope: ateapi.TagScope_TAG_SCOPE_ATESPACE, + SourceActor: &ateapi.ObjectRef{Atespace: ns.a, Name: source}, }, }) if err != nil { @@ -253,13 +253,13 @@ func testTagScopeBoundary(t *testing.T, ctx context.Context, clients *e2e.Client } // The boundary: the other atespace may not name this tag. - crossRef := &ateapipb.ObjectRef{Atespace: ns.b, Name: "cross-atespace-clone"} + crossRef := &ateapi.ObjectRef{Atespace: ns.b, Name: "cross-atespace-clone"} t.Cleanup(func() { - _, _ = clients.SubstrateAPI.DeleteActor(context.Background(), &ateapipb.DeleteActorRequest{Actor: crossRef}) + _, _ = clients.SubstrateAPI.DeleteActor(context.Background(), &ateapi.DeleteActorRequest{Actor: crossRef}) }) - _, err = clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: ns.b, Name: crossRef.GetName()}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: ns.b, Name: templateName}, + _, err = clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: ns.b, Name: crossRef.GetName()}, + ActorTemplate: &ateapi.ObjectRef{Atespace: ns.b, Name: templateName}, SourceTag: tagRef, }}) switch { @@ -279,24 +279,24 @@ func testTagScopeBoundary(t *testing.T, ctx context.Context, clients *e2e.Client // clone carries the source's durable data. Otherwise an unusable tag would // make the rejection above look like enforcement. const clone = "same-atespace-clone" - cloneRef := &ateapipb.ObjectRef{Atespace: ns.a, Name: clone} + cloneRef := &ateapi.ObjectRef{Atespace: ns.a, Name: clone} t.Cleanup(func() { cleanupCtx := context.Background() - _, _ = clients.SubstrateAPI.SuspendActor(cleanupCtx, &ateapipb.SuspendActorRequest{Actor: cloneRef}) - _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapipb.DeleteActorRequest{Actor: cloneRef}) + _, _ = clients.SubstrateAPI.SuspendActor(cleanupCtx, &ateapi.SuspendActorRequest{Actor: cloneRef}) + _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapi.DeleteActorRequest{Actor: cloneRef}) }) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: ns.a, Name: clone}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: ns.a, Name: templateName}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: ns.a, Name: clone}, + ActorTemplate: &ateapi.ObjectRef{Atespace: ns.a, Name: templateName}, SourceTag: tagRef, }}); err != nil { t.Fatalf("control: CreateActor %s/%s from tag %s in its own atespace: %v — the tag is unusable, so the cross-atespace rejection above proves nothing", ns.a, clone, tagRef.GetName(), err) } - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: cloneRef}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: cloneRef}); err != nil { t.Fatalf("control: ResumeActor %s/%s: %v", ns.a, clone, err) } - waitForActorState(t, ctx, clients, ns.a, clone, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(t, ctx, clients, ns.a, clone, ateapi.ActorState_ACTOR_STATE_RUNNING) if got := readFile(t, ctx, rc, resources.ActorRef{Atespace: ns.a, Name: clone}, markerA); got.Content != writtenByProbe { t.Fatalf("control: actor %s/%s restored from tag %s reads %s = %q (error %q), want %q — the tag carries no durable data, so the cross-atespace rejection above proves nothing", ns.a, clone, tagRef.GetName(), markerA, got.Content, got.Error, writtenByProbe) @@ -337,8 +337,8 @@ func requireReusedWorker(t *testing.T, ctx context.Context, clients *e2e.Clients func assignedWorker(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, name string) string { t.Helper() - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: atespace, Name: name}, + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: atespace, Name: name}, }) if err != nil { t.Fatalf("GetActor %s/%s: %v", atespace, name, err) @@ -352,8 +352,8 @@ func assignedWorker(t *testing.T, ctx context.Context, clients *e2e.Clients, ate func actorUID(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, name string) string { t.Helper() - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: atespace, Name: name}, + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: atespace, Name: name}, }) if err != nil { t.Fatalf("GetActor %s/%s: %v", atespace, name, err) @@ -369,38 +369,38 @@ func actorUID(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, // it from the golden snapshot, removing it when the test ends. func createAndResumeActor(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, name string) { t.Helper() - ref := &ateapipb.ObjectRef{Atespace: atespace, Name: name} + ref := &ateapi.ObjectRef{Atespace: atespace, Name: name} // Actor records outlive the fixture namespace, so an interrupted run can // leave one behind and wedge reruns on AlreadyExists. DeleteActor needs // SUSPENDED or CRASHED, hence the suspend; both are best-effort. - _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: ref}) - _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref}) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: atespace, Name: templateName}, + _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref}) + _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}) + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: atespace, Name: templateName}, }}); err != nil { t.Fatalf("CreateActor %s/%s: %v", atespace, name, err) } t.Cleanup(func() { cleanupCtx := context.Background() - _, _ = clients.SubstrateAPI.SuspendActor(cleanupCtx, &ateapipb.SuspendActorRequest{Actor: ref}) - if _, err := clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapipb.DeleteActorRequest{Actor: ref}); err != nil { + _, _ = clients.SubstrateAPI.SuspendActor(cleanupCtx, &ateapi.SuspendActorRequest{Actor: ref}) + if _, err := clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapi.DeleteActorRequest{Actor: ref}); err != nil { t.Logf("cleanup: DeleteActor %s/%s failed, actor leaked (remove with: kubectl ate delete actor %s -a %s): %v", atespace, name, name, atespace, err) } }) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor %s/%s: %v", atespace, name, err) } - waitForActorState(t, ctx, clients, atespace, name, ateapipb.ActorState_ACTOR_STATE_RUNNING) + waitForActorState(t, ctx, clients, atespace, name, ateapi.ActorState_ACTOR_STATE_RUNNING) } -func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, name string, want ateapipb.ActorState) { +func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, name string, want ateapi.ActorState) { t.Helper() deadline := time.Now().Add(60 * time.Second) for time.Now().Before(deadline) { - resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: atespace, Name: name}, + resp, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: atespace, Name: name}, }) if err == nil && resp.GetStatus().GetState() == want { return @@ -453,8 +453,8 @@ func probeFileOp(t *testing.T, ctx context.Context, rc *e2e.RouterClient, actor return out } -func durableSnapshotURI(status *ateapipb.ActorStatus) string { - var best *ateapipb.Snapshot +func durableSnapshotURI(status *ateapi.ActorStatus) string { + var best *ateapi.Snapshot for _, snap := range status.GetSnapshots() { if uri := snapshotURI(snap); uri != "" { if best == nil || snap.GetGeneration() > best.GetGeneration() { @@ -465,9 +465,9 @@ func durableSnapshotURI(status *ateapipb.ActorStatus) string { return snapshotURI(best) } -func snapshotURI(snap *ateapipb.Snapshot) string { +func snapshotURI(snap *ateapi.Snapshot) string { st := snap.GetDurableSnapshot() - if st.GetStatus() == ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { + if st.GetStatus() == ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { return st.GetObject().GetSnapshotUri() } return "" diff --git a/internal/e2e/suites/sizing/sizing_test.go b/internal/e2e/suites/sizing/sizing_test.go index fec9b7cc81..b56e6f59f4 100644 --- a/internal/e2e/suites/sizing/sizing_test.go +++ b/internal/e2e/suites/sizing/sizing_test.go @@ -21,9 +21,9 @@ import ( "net/http" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const ( @@ -119,20 +119,20 @@ func deploySizedProbe(t *testing.T, ctx context.Context, clients *e2e.Clients, b func createAndResumeActor(t *testing.T, ctx context.Context, clients *e2e.Clients, id string) { t.Helper() - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: sizingNamespace, Name: id}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: sizingNamespace, Name: sizingTemplate}, + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: sizingNamespace, Name: id}, + ActorTemplate: &ateapi.ObjectRef{Atespace: sizingNamespace, Name: sizingTemplate}, }}); err != nil { t.Fatalf("CreateActor %q: %v", id, err) } t.Cleanup(func() { // DeleteActor requires the actor to be suspended. - _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: &ateapipb.ObjectRef{Atespace: sizingNamespace, Name: id}}) - _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: &ateapipb.ObjectRef{Atespace: sizingNamespace, Name: id}}) + _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: &ateapi.ObjectRef{Atespace: sizingNamespace, Name: id}}) + _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: &ateapi.ObjectRef{Atespace: sizingNamespace, Name: id}}) }) // Resume from the golden snapshot (the restore path). - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: sizingNamespace, Name: id}}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: sizingNamespace, Name: id}}); err != nil { t.Fatalf("ResumeActor %q: %v", id, err) } } diff --git a/internal/e2e/suites/snapshotcredentials/snapshotcredentials_test.go b/internal/e2e/suites/snapshotcredentials/snapshotcredentials_test.go index cc71b2ecd3..502690aa07 100644 --- a/internal/e2e/suites/snapshotcredentials/snapshotcredentials_test.go +++ b/internal/e2e/suites/snapshotcredentials/snapshotcredentials_test.go @@ -37,6 +37,7 @@ import ( "google.golang.org/protobuf/proto" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/actoridjwt" "go.ate.dev/substrate/internal/ateclient" "go.ate.dev/substrate/internal/e2e" @@ -45,7 +46,6 @@ import ( "go.ate.dev/substrate/internal/portforward" "go.ate.dev/substrate/internal/preview" exchangepb "go.ate.dev/substrate/internal/proto/objectstoreexchangepb" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const probeTemplate = "probe" @@ -107,13 +107,13 @@ func newSigner(t *testing.T, ctx context.Context, clients *e2e.Clients) *signer type claims struct { kind actoridjwt.Kind audience string - actor *ateapipb.Actor + actor *ateapi.Actor uid string node string } // forActor is the token ate-api-server would mint for the node hosting actor. -func forActor(actor *ateapipb.Actor) claims { +func forActor(actor *ateapi.Actor) claims { return claims{ kind: actoridjwt.KindWorkerForActor, audience: exchange.ActorJWTAudience, actor: actor, uid: actor.GetMetadata().GetUid(), node: actor.GetStatus().GetAssignedNode(), @@ -196,10 +196,10 @@ func expectGCS(t *testing.T, ctx context.Context, what, token, method, uri, body // durableURI is the prefix of the actor's generation with the given owner, // which must be COMPLETED in object storage. -func durableURI(t *testing.T, actor *ateapipb.Actor, owner ateapipb.SnapshotOwner) string { +func durableURI(t *testing.T, actor *ateapi.Actor, owner ateapi.SnapshotOwner) string { t.Helper() for _, snap := range actor.GetStatus().GetSnapshots() { - if snap.GetOwner() == owner && snap.GetDurableSnapshot().GetStatus() == ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { + if snap.GetOwner() == owner && snap.GetDurableSnapshot().GetStatus() == ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { return snap.GetDurableSnapshot().GetObject().GetSnapshotUri() } } @@ -207,16 +207,16 @@ func durableURI(t *testing.T, actor *ateapipb.Actor, owner ateapipb.SnapshotOwne return "" } -func getActor(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, name string) *ateapipb.Actor { +func getActor(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, name string) *ateapi.Actor { t.Helper() - actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{Actor: &ateapipb.ObjectRef{Atespace: atespace, Name: name}}) + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapi.GetActorRequest{Actor: &ateapi.ObjectRef{Atespace: atespace, Name: name}}) if err != nil { t.Fatalf("GetActor %s: %v", name, err) } return actor } -func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, name string, want ateapipb.ActorState) *ateapipb.Actor { +func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, name string, want ateapi.ActorState) *ateapi.Actor { t.Helper() deadline := time.Now().Add(2 * time.Minute) for { @@ -234,14 +234,14 @@ func waitForActorState(t *testing.T, ctx context.Context, clients *e2e.Clients, // createAndResume creates an actor from the probe template and resumes it // from the golden snapshot. The record outlives the fixture namespace, so a // leftover from a failed run is cleared first. -func createAndResume(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, name string) *ateapipb.Actor { +func createAndResume(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, name string) *ateapi.Actor { t.Helper() - ref := &ateapipb.ObjectRef{Atespace: atespace, Name: name} - _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: ref}) - _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref}) - if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: name}, - ActorTemplate: &ateapipb.ObjectRef{Atespace: atespace, Name: probeTemplate}, + ref := &ateapi.ObjectRef{Atespace: atespace, Name: name} + _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref}) + _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}) + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: atespace, Name: probeTemplate}, }}); err != nil { t.Fatalf("CreateActor %s: %v", name, err) } @@ -250,26 +250,26 @@ func createAndResume(t *testing.T, ctx context.Context, clients *e2e.Clients, at // actor left running crashes when the fixture's worker pool goes. ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() - _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: ref}) - if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: ref}); err != nil { + _, _ = clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref}) + if _, err := clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}); err != nil { t.Logf("cleanup: DeleteActor %s failed, actor leaked (remove with: kubectl ate delete actor %s -a %s): %v", name, name, atespace, err) } }) - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor %s: %v", name, err) } - return waitForActorState(t, ctx, clients, atespace, name, ateapipb.ActorState_ACTOR_STATE_RUNNING) + return waitForActorState(t, ctx, clients, atespace, name, ateapi.ActorState_ACTOR_STATE_RUNNING) } // suspendSync suspends the actor and waits for its snapshot to be durable. -func suspendSync(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, name string) *ateapipb.Actor { +func suspendSync(t *testing.T, ctx context.Context, clients *e2e.Clients, atespace, name string) *ateapi.Actor { t.Helper() - ref := &ateapipb.ObjectRef{Atespace: atespace, Name: name} - if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: ref, - Options: &ateapipb.SuspendOptions{Mode: ateapipb.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}); err != nil { + ref := &ateapi.ObjectRef{Atespace: atespace, Name: name} + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref, + Options: &ateapi.SuspendOptions{Mode: ateapi.DurabilityMode_DURABILITY_MODE_SYNCHRONOUS}}); err != nil { t.Fatalf("SuspendActor %s: %v", name, err) } - return waitForActorState(t, ctx, clients, atespace, name, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) + return waitForActorState(t, ctx, clients, atespace, name, ateapi.ActorState_ACTOR_STATE_SUSPENDED) } // TestExchangeScopesTheTokenToTheActor walks the exchange and the boundary @@ -296,7 +296,7 @@ func TestExchangeScopesTheTokenToTheActor(t *testing.T) { // scheduler picks. alpha := createAndResume(t, ctx, clients, atespace, "creds-alpha") beta := createAndResume(t, ctx, clients, atespace, "creds-beta") - goldenURI := durableURI(t, alpha, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG) + goldenURI := durableURI(t, alpha, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG) // A token for alpha, as its node would present it. resp, err := xchg.ExchangeActorJwt(ctx, &exchangepb.ExchangeActorJwtRequest{ActorJwt: sign.jwt(t, forActor(alpha))}) @@ -356,10 +356,10 @@ func TestExchangeScopesTheTokenToTheActor(t *testing.T) { if _, err := xchg.ExchangeActorJwt(ctx, &exchangepb.ExchangeActorJwtRequest{ActorJwt: sign.jwt(t, withNode(forActor(beta), "any-node"))}); status.Code(err) != codes.PermissionDenied { t.Errorf("exchange for a suspended actor held by no node = %v, want PermissionDenied", err) } - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: atespace, Name: "creds-alpha"}}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: &ateapi.ObjectRef{Atespace: atespace, Name: "creds-alpha"}}); err != nil { t.Fatalf("ResumeActor creds-alpha: %v", err) } - alpha = waitForActorState(t, ctx, clients, atespace, "creds-alpha", ateapipb.ActorState_ACTOR_STATE_RUNNING) + alpha = waitForActorState(t, ctx, clients, atespace, "creds-alpha", ateapi.ActorState_ACTOR_STATE_RUNNING) // The forced exchange re-derives the grants: the golden is gone from // alpha's status, its own snapshot is in. @@ -368,15 +368,15 @@ func TestExchangeScopesTheTokenToTheActor(t *testing.T) { t.Fatalf("forced exchange after the first suspend: %v", err) } token = resp.GetAccessToken() - expectGCS(t, ctx, "own snapshot manifest read", token, http.MethodGet, durableURI(t, alpha, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR)+"/manifest.json", "", http.StatusOK) - expectGCS(t, ctx, "sibling snapshot manifest refused", token, http.MethodGet, durableURI(t, beta, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR)+"/manifest.json", "", http.StatusForbidden) + expectGCS(t, ctx, "own snapshot manifest read", token, http.MethodGet, durableURI(t, alpha, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR)+"/manifest.json", "", http.StatusOK) + expectGCS(t, ctx, "sibling snapshot manifest refused", token, http.MethodGet, durableURI(t, beta, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR)+"/manifest.json", "", http.StatusForbidden) expectGCS(t, ctx, "golden read dropped with the tag generation", token, http.MethodGet, goldenURI+"/manifest.json", "", http.StatusForbidden) } // ownPrefix is the actor's own prefix at the location its golden lives in, // the read-write grant the exchange derives before the actor has a snapshot // of its own: /atespaces//actors/. -func ownPrefix(goldenURI string, actor *ateapipb.Actor) string { +func ownPrefix(goldenURI string, actor *ateapi.Actor) string { location, _, _ := strings.Cut(goldenURI, "/atespaces/") return location + "/atespaces/" + actor.GetMetadata().GetAtespace() + "/actors/" + actor.GetMetadata().GetUid() } @@ -390,7 +390,7 @@ func locationOf(snapshotURI string) string { // ownPrefixAt is ownPrefix for a location given directly, for a template // whose location differs from the golden's. -func ownPrefixAt(location string, actor *ateapipb.Actor) string { +func ownPrefixAt(location string, actor *ateapi.Actor) string { return strings.TrimSuffix(location, "/") + "/atespaces/" + actor.GetMetadata().GetAtespace() + "/actors/" + actor.GetMetadata().GetUid() } @@ -425,16 +425,16 @@ func TestRepointMovesTheGrant(t *testing.T) { // next snapshot goes under B's location. const nameB = "probe-repoint" locationB := "gs://" + env["BUCKET_NAME"] + "/ate-e2e-repoint-" + stamp + "/" - templateB := proto.Clone(probe).(*ateapipb.ActorTemplate) - templateB.Metadata = &ateapipb.ResourceMetadata{Atespace: atespace, Name: nameB} + templateB := proto.Clone(probe).(*ateapi.ActorTemplate) + templateB.Metadata = &ateapi.ResourceMetadata{Atespace: atespace, Name: nameB} templateB.Status = nil - templateB.SnapshotConfig = proto.Clone(probe.GetSnapshotConfig()).(*ateapipb.SnapshotConfig) + templateB.SnapshotConfig = proto.Clone(probe.GetSnapshotConfig()).(*ateapi.SnapshotConfig) templateB.SnapshotConfig.StorageLocation = locationB - if _, err := clients.SubstrateAPI.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ActorTemplate: templateB}); err != nil { + if _, err := clients.SubstrateAPI.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ActorTemplate: templateB}); err != nil { t.Fatalf("CreateActorTemplate %s: %v", nameB, err) } t.Cleanup(func() { - if _, err := clients.SubstrateAPI.DeleteActorTemplate(context.Background(), &ateapipb.DeleteActorTemplateRequest{ActorTemplate: &ateapipb.ObjectRef{Atespace: atespace, Name: nameB}}); err != nil { + if _, err := clients.SubstrateAPI.DeleteActorTemplate(context.Background(), &ateapi.DeleteActorTemplateRequest{ActorTemplate: &ateapi.ObjectRef{Atespace: atespace, Name: nameB}}); err != nil { t.Logf("cleanup: DeleteActorTemplate %s failed: %v", nameB, err) } }) @@ -443,7 +443,7 @@ func TestRepointMovesTheGrant(t *testing.T) { // Running from template A, the token writes under A's location only. const name = "creds-repoint" actor := createAndResume(t, ctx, clients, atespace, name) - locationA := locationOf(durableURI(t, actor, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG)) + locationA := locationOf(durableURI(t, actor, ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG)) first, err := xchg.ExchangeActorJwt(ctx, &exchangepb.ExchangeActorJwtRequest{ActorJwt: sign.jwt(t, forActor(actor))}) if err != nil { t.Fatalf("exchange before the repoint: %v", err) @@ -454,19 +454,19 @@ func TestRepointMovesTheGrant(t *testing.T) { // A repoint needs a suspended actor that owns no snapshot, so the actor // is reverted to its golden rather than suspended. - ref := &ateapipb.ObjectRef{Atespace: atespace, Name: name} - if _, err := clients.SubstrateAPI.RevertActor(ctx, &ateapipb.RevertActorRequest{Actor: ref}); err != nil { + ref := &ateapi.ObjectRef{Atespace: atespace, Name: name} + if _, err := clients.SubstrateAPI.RevertActor(ctx, &ateapi.RevertActorRequest{Actor: ref}); err != nil { t.Fatalf("RevertActor %s: %v", name, err) } - actor = waitForActorState(t, ctx, clients, atespace, name, ateapipb.ActorState_ACTOR_STATE_SUSPENDED) - actor.ActorTemplate = &ateapipb.ObjectRef{Atespace: atespace, Name: nameB} - if _, err := clients.SubstrateAPI.UpdateActor(ctx, &ateapipb.UpdateActorRequest{Actor: actor}); err != nil { + actor = waitForActorState(t, ctx, clients, atespace, name, ateapi.ActorState_ACTOR_STATE_SUSPENDED) + actor.ActorTemplate = &ateapi.ObjectRef{Atespace: atespace, Name: nameB} + if _, err := clients.SubstrateAPI.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: actor}); err != nil { t.Fatalf("UpdateActor %s to template %s: %v", name, nameB, err) } - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor %s after the repoint: %v", name, err) } - actor = waitForActorState(t, ctx, clients, atespace, name, ateapipb.ActorState_ACTOR_STATE_RUNNING) + actor = waitForActorState(t, ctx, clients, atespace, name, ateapi.ActorState_ACTOR_STATE_RUNNING) // The actor's status still names only A's location, so the exchange // still grants A and not B, whatever it serves from its cache. @@ -483,7 +483,7 @@ func TestRepointMovesTheGrant(t *testing.T) { // cached for the resume, and one forced re-exchange, now granting B, // carries the upload. The snapshot lands under B's location. actor = suspendSync(t, ctx, clients, atespace, name) - snapshot := durableURI(t, actor, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR) + snapshot := durableURI(t, actor, ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR) if !strings.HasPrefix(snapshot, ownPrefixAt(locationB, actor)) { t.Fatalf("snapshot after the repoint is at %s, want it under %s", snapshot, ownPrefixAt(locationB, actor)) } @@ -492,10 +492,10 @@ func TestRepointMovesTheGrant(t *testing.T) { // once it runs again. Now the status names B, so an exchange without // force must not serve the old token, whose grants no longer cover the // actor. - if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { t.Fatalf("ResumeActor %s after the suspend: %v", name, err) } - actor = waitForActorState(t, ctx, clients, atespace, name, ateapipb.ActorState_ACTOR_STATE_RUNNING) + actor = waitForActorState(t, ctx, clients, atespace, name, ateapi.ActorState_ACTOR_STATE_RUNNING) after, err := xchg.ExchangeActorJwt(ctx, &exchangepb.ExchangeActorJwtRequest{ActorJwt: sign.jwt(t, forActor(actor))}) if err != nil { t.Fatalf("exchange after the suspend: %v", err) diff --git a/internal/e2e/template.go b/internal/e2e/template.go index f76153291c..019cac8762 100644 --- a/internal/e2e/template.go +++ b/internal/e2e/template.go @@ -19,16 +19,16 @@ import ( "testing" "time" - "go.ate.dev/substrate/pkg/api/v1alpha1" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // TemplateRef builds the substrate template reference an Actor carries. -func TemplateRef(at *ateapipb.ActorTemplate) *ateapipb.ObjectRef { - return &ateapipb.ObjectRef{Atespace: at.GetMetadata().GetAtespace(), Name: at.GetMetadata().GetName()} +func TemplateRef(at *ateapi.ActorTemplate) *ateapi.ObjectRef { + return &ateapi.ObjectRef{Atespace: at.GetMetadata().GetAtespace(), Name: at.GetMetadata().GetName()} } // SubstrateTemplateOptions shapes CreateSubstrateTemplateFrom. @@ -46,15 +46,15 @@ type SubstrateTemplateOptions struct { // pool's workers invisible to other namespaces' actors. Labels map[string]string // SnapshotConfig for the new template; nil copies the source's. - SnapshotConfig *ateapipb.SnapshotConfig + SnapshotConfig *ateapi.SnapshotConfig // Modify, when set, edits the template before it is created. - Modify func(*ateapipb.ActorTemplate) + Modify func(*ateapi.ActorTemplate) } // CreateSubstrateCounterTemplate creates a per-test WorkerPool CRD plus a // substrate ActorTemplate copying the resolved runtime from the substrate // counter demo for the sandbox class under test. -func CreateSubstrateCounterTemplate(ctx context.Context, t *testing.T, clients *Clients, namespace string, opts SubstrateTemplateOptions) *ateapipb.ActorTemplate { +func CreateSubstrateCounterTemplate(ctx context.Context, t *testing.T, clients *Clients, namespace string, opts SubstrateTemplateOptions) *ateapi.ActorTemplate { t.Helper() return CreateSubstrateTemplateFrom(ctx, t, clients, namespace, SubstrateCounterFixture(), opts) } @@ -64,38 +64,38 @@ func CreateSubstrateCounterTemplate(ctx context.Context, t *testing.T, clients * // container images, sandbox size) from the installed fixture src. It // registers cleanup of the template (which does not ride the k8s namespace GC // the CRD templates did) and blocks until the golden snapshot exists. -func CreateSubstrateTemplateFrom(ctx context.Context, t *testing.T, clients *Clients, namespace string, src SubstrateFixture, opts SubstrateTemplateOptions) *ateapipb.ActorTemplate { +func CreateSubstrateTemplateFrom(ctx context.Context, t *testing.T, clients *Clients, namespace string, src SubstrateFixture, opts SubstrateTemplateOptions) *ateapi.ActorTemplate { t.Helper() - existingWp, err := clients.SubstrateK8s.ApiV1alpha1().WorkerPools(src.PoolNamespace).Get(ctx, src.PoolName, metav1.GetOptions{}) + existingWp, err := clients.SubstrateK8s.AteV1().WorkerPools(src.PoolNamespace).Get(ctx, src.PoolName, metav1.GetOptions{}) if err != nil { t.Fatalf("failed to get WorkerPool %s/%s (deploy with: %s): %v", src.PoolNamespace, src.PoolName, src.DeployWith, err) } - srcTmpl, err := clients.SubstrateAPI.GetActorTemplate(ctx, &ateapipb.GetActorTemplateRequest{ - ActorTemplate: &ateapipb.ObjectRef{Atespace: src.Atespace, Name: src.Name}, + srcTmpl, err := clients.SubstrateAPI.GetActorTemplate(ctx, &ateapi.GetActorTemplateRequest{ + ActorTemplate: &ateapi.ObjectRef{Atespace: src.Atespace, Name: src.Name}, }) if err != nil { t.Fatalf("failed to get ActorTemplate %s/%s (deploy with: %s): %v", src.Atespace, src.Name, src.DeployWith, err) } - wp := &v1alpha1.WorkerPool{ + wp := &atev1.WorkerPool{ ObjectMeta: metav1.ObjectMeta{ Name: opts.PoolName, Namespace: namespace, Labels: opts.Labels, }, - Spec: v1alpha1.WorkerPoolSpec{ + Spec: atev1.WorkerPoolSpec{ Replicas: opts.PoolReplicas, WorkerImage: existingWp.Spec.WorkerImage, SandboxClasses: existingWp.Spec.SandboxClasses, }, } - if _, err := clients.SubstrateK8s.ApiV1alpha1().WorkerPools(namespace).Create(ctx, wp, metav1.CreateOptions{}); err != nil { + if _, err := clients.SubstrateK8s.AteV1().WorkerPools(namespace).Create(ctx, wp, metav1.CreateOptions{}); err != nil { t.Fatalf("failed to create WorkerPool: %v", err) } // CreateActorTemplate requires the atespace to exist first. - if _, err := clients.SubstrateAPI.CreateAtespace(ctx, &ateapipb.CreateAtespaceRequest{Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: opts.Atespace}}}); err != nil && status.Code(err) != codes.AlreadyExists { + if _, err := clients.SubstrateAPI.CreateAtespace(ctx, &ateapi.CreateAtespaceRequest{Atespace: &ateapi.Atespace{Metadata: &ateapi.ResourceMetadata{Name: opts.Atespace}}}); err != nil && status.Code(err) != codes.AlreadyExists { t.Fatalf("failed to create atespace %q: %v", opts.Atespace, err) } @@ -103,9 +103,9 @@ func CreateSubstrateTemplateFrom(ctx context.Context, t *testing.T, clients *Cli if snapshots == nil { snapshots = srcTmpl.GetSnapshotConfig() } - tmpl := &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: opts.Atespace, Name: opts.Name}, - WorkerSelector: &ateapipb.Selector{MatchLabels: opts.Labels}, + tmpl := &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: opts.Atespace, Name: opts.Name}, + WorkerSelector: &ateapi.Selector{MatchLabels: opts.Labels}, Containers: srcTmpl.GetContainers(), // The source's limits size the sandbox, and the API requires them. Resources: srcTmpl.GetResources(), @@ -115,7 +115,7 @@ func CreateSubstrateTemplateFrom(ctx context.Context, t *testing.T, clients *Cli if opts.Modify != nil { opts.Modify(tmpl) } - created, err := clients.SubstrateAPI.CreateActorTemplate(ctx, &ateapipb.CreateActorTemplateRequest{ActorTemplate: tmpl}) + created, err := clients.SubstrateAPI.CreateActorTemplate(ctx, &ateapi.CreateActorTemplateRequest{ActorTemplate: tmpl}) if err != nil { t.Fatalf("failed to create ActorTemplate %s/%s: %v", opts.Atespace, opts.Name, err) } @@ -125,8 +125,8 @@ func CreateSubstrateTemplateFrom(ctx context.Context, t *testing.T, clients *Cli t.Cleanup(func() { cleanupCtx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - if _, err := clients.SubstrateAPI.DeleteActorTemplate(cleanupCtx, &ateapipb.DeleteActorTemplateRequest{ - ActorTemplate: &ateapipb.ObjectRef{Atespace: opts.Atespace, Name: opts.Name}, + if _, err := clients.SubstrateAPI.DeleteActorTemplate(cleanupCtx, &ateapi.DeleteActorTemplateRequest{ + ActorTemplate: &ateapi.ObjectRef{Atespace: opts.Atespace, Name: opts.Name}, }); err != nil && status.Code(err) != codes.NotFound { t.Logf("failed to delete ActorTemplate %s/%s: %v", opts.Atespace, opts.Name, err) } @@ -151,13 +151,13 @@ func WaitForSubstrateTemplateReady(ctx context.Context, t *testing.T, clients *C ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() - var lastStatus *ateapipb.GoldenSnapshotStatus + var lastStatus *ateapi.GoldenSnapshotStatus for { - at, err := clients.SubstrateAPI.GetActorTemplate(ctx, &ateapipb.GetActorTemplateRequest{ - ActorTemplate: &ateapipb.ObjectRef{Atespace: atespace, Name: name}, + at, err := clients.SubstrateAPI.GetActorTemplate(ctx, &ateapi.GetActorTemplateRequest{ + ActorTemplate: &ateapi.ObjectRef{Atespace: atespace, Name: name}, }) if err == nil { - if at.GetSnapshotConfig().GetGoldenSnapshotConfig().GetMode() == ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED { + if at.GetSnapshotConfig().GetGoldenSnapshotConfig().GetMode() == ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED { // The template opted out: no golden snapshot will ever appear, // and none is needed. return diff --git a/internal/e2e/template_test.go b/internal/e2e/template_test.go index 3211d14f34..96d92c39b3 100644 --- a/internal/e2e/template_test.go +++ b/internal/e2e/template_test.go @@ -18,21 +18,21 @@ import ( "context" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/ateclient" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc" ) // disabledGoldenTemplateClient serves one ActorTemplate that opted out of the // golden snapshot and has no golden status. type disabledGoldenTemplateClient struct { - ateapipb.ControlClient + ateapi.ControlClient } -func (disabledGoldenTemplateClient) GetActorTemplate(_ context.Context, in *ateapipb.GetActorTemplateRequest, _ ...grpc.CallOption) (*ateapipb.ActorTemplate, error) { - return &ateapipb.ActorTemplate{ - Metadata: &ateapipb.ResourceMetadata{Atespace: in.GetActorTemplate().GetAtespace(), Name: in.GetActorTemplate().GetName()}, - SnapshotConfig: &ateapipb.SnapshotConfig{GoldenSnapshotConfig: &ateapipb.GoldenSnapshotConfig{Mode: ateapipb.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED}}, +func (disabledGoldenTemplateClient) GetActorTemplate(_ context.Context, in *ateapi.GetActorTemplateRequest, _ ...grpc.CallOption) (*ateapi.ActorTemplate, error) { + return &ateapi.ActorTemplate{ + Metadata: &ateapi.ResourceMetadata{Atespace: in.GetActorTemplate().GetAtespace(), Name: in.GetActorTemplate().GetName()}, + SnapshotConfig: &ateapi.SnapshotConfig{GoldenSnapshotConfig: &ateapi.GoldenSnapshotConfig{Mode: ateapi.GoldenSnapshotMode_GOLDEN_SNAPSHOT_MODE_DISABLED}}, }, nil } diff --git a/internal/egresspolicy/egresspolicy.go b/internal/egresspolicy/egresspolicy.go index 4d7e984da7..b5b1bc67fe 100644 --- a/internal/egresspolicy/egresspolicy.go +++ b/internal/egresspolicy/egresspolicy.go @@ -33,7 +33,7 @@ import ( "k8s.io/apimachinery/pkg/api/validate/content" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) // Destination is what a request is going to, as far as the leg evaluating it @@ -61,7 +61,7 @@ type Decision struct { RuleIndex int // Effects are the effects of the deciding rule, when it declares any. // Nil otherwise. - Effects *ateapipb.HttpRuleEffects + Effects *ateapi.HttpRuleEffects } // Policy is an EgressPolicy with its patterns and ports parsed once, ready to @@ -84,7 +84,7 @@ type compiledRule struct { // ports the rule names; anyPort when it names all of them. ports []uint16 anyPort bool - effects *ateapipb.HttpRuleEffects + effects *ateapi.HttpRuleEffects } // Ports read for an http or https rule that names none. ateapi fills these @@ -99,7 +99,7 @@ const ( // same way, so nothing should fail here; an entry that does (an older // ateapi accepted it) is dropped and reported, which fails closed because it // only narrows an allow rule. The Policy is always usable. -func Compile(policy *ateapipb.EgressPolicy) (*Policy, []error) { +func Compile(policy *ateapi.EgressPolicy) (*Policy, []error) { var errs []error compiled := &Policy{} for i, rule := range policy.GetRules() { @@ -107,7 +107,7 @@ func Compile(policy *ateapipb.EgressPolicy) (*Policy, []error) { cr compiledRule member string raw []string - ports *ateapipb.Ports + ports *ateapi.Ports defaultPort uint16 ) switch { diff --git a/internal/egresspolicy/egresspolicy_test.go b/internal/egresspolicy/egresspolicy_test.go index a4561754e0..267e02bdd7 100644 --- a/internal/egresspolicy/egresspolicy_test.go +++ b/internal/egresspolicy/egresspolicy_test.go @@ -19,34 +19,34 @@ import ( "slices" "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) -func httpRule(patterns ...string) *ateapipb.EgressRule { - return &ateapipb.EgressRule{Http: &ateapipb.HttpRule{Hostnames: patterns}} +func httpRule(patterns ...string) *ateapi.EgressRule { + return &ateapi.EgressRule{Http: &ateapi.HttpRule{Hostnames: patterns}} } -func httpRuleOnPorts(ports *ateapipb.Ports, patterns ...string) *ateapipb.EgressRule { - return &ateapipb.EgressRule{Http: &ateapipb.HttpRule{Hostnames: patterns, Ports: ports}} +func httpRuleOnPorts(ports *ateapi.Ports, patterns ...string) *ateapi.EgressRule { + return &ateapi.EgressRule{Http: &ateapi.HttpRule{Hostnames: patterns, Ports: ports}} } -func httpsRule(patterns ...string) *ateapipb.EgressRule { - return &ateapipb.EgressRule{Https: &ateapipb.HttpsRule{Hostnames: patterns}} +func httpsRule(patterns ...string) *ateapi.EgressRule { + return &ateapi.EgressRule{Https: &ateapi.HttpsRule{Hostnames: patterns}} } -func passthroughRule(ports *ateapipb.Ports, patterns ...string) *ateapipb.EgressRule { - return &ateapipb.EgressRule{TlsPassthrough: &ateapipb.TlsPassthroughRule{Hostnames: patterns, Ports: ports}} +func passthroughRule(ports *ateapi.Ports, patterns ...string) *ateapi.EgressRule { + return &ateapi.EgressRule{TlsPassthrough: &ateapi.TlsPassthroughRule{Hostnames: patterns, Ports: ports}} } -func ports(numbers ...int32) *ateapipb.Ports { return &ateapipb.Ports{Numbers: numbers} } +func ports(numbers ...int32) *ateapi.Ports { return &ateapi.Ports{Numbers: numbers} } -func allPorts() *ateapipb.Ports { return &ateapipb.Ports{All: &ateapipb.AllPorts{}} } +func allPorts() *ateapi.Ports { return &ateapi.Ports{All: &ateapi.AllPorts{}} } -func policy(rules ...*ateapipb.EgressRule) *ateapipb.EgressPolicy { - return &ateapipb.EgressPolicy{Rules: rules} +func policy(rules ...*ateapi.EgressRule) *ateapi.EgressPolicy { + return &ateapi.EgressPolicy{Rules: rules} } -func mustCompile(t *testing.T, p *ateapipb.EgressPolicy) *Policy { +func mustCompile(t *testing.T, p *ateapi.EgressPolicy) *Policy { t.Helper() compiled, errs := Compile(p) if len(errs) != 0 { @@ -235,21 +235,21 @@ func TestCompileReportsAndDropsInvalidEntries(t *testing.T) { } func TestEvaluateRequest(t *testing.T) { - effects := &ateapipb.HttpRuleEffects{ - ReplaceHeaders: []*ateapipb.CredentialHeader{{ + effects := &ateapi.HttpRuleEffects{ + ReplaceHeaders: []*ateapi.CredentialHeader{{ Header: "authorization", Prefix: "Bearer ", CredentialUri: "ate-secret://k8s/default/token", }}, } - withEffects := &ateapipb.EgressRule{Https: &ateapipb.HttpsRule{ + withEffects := &ateapi.EgressRule{Https: &ateapi.HttpsRule{ Hostnames: []string{"api.example.com"}, Effects: effects, }} tests := []struct { name string - policy *ateapipb.EgressPolicy + policy *ateapi.EgressPolicy dest Destination decrypted bool want Decision @@ -413,7 +413,7 @@ func TestEvaluateRequest(t *testing.T) { }, { name: "empty rule matches nothing", - policy: policy(&ateapipb.EgressRule{}, httpRule("example.com")), + policy: policy(&ateapi.EgressRule{}, httpRule("example.com")), dest: host("example.com"), want: Decision{Allowed: true, RuleIndex: 1}, }, @@ -427,8 +427,8 @@ func TestEvaluateRequest(t *testing.T) { } } -func httpsRuleOnPorts(ports *ateapipb.Ports, patterns ...string) *ateapipb.EgressRule { - return &ateapipb.EgressRule{Https: &ateapipb.HttpsRule{Hostnames: patterns, Ports: ports}} +func httpsRuleOnPorts(ports *ateapi.Ports, patterns ...string) *ateapi.EgressRule { + return &ateapi.EgressRule{Https: &ateapi.HttpsRule{Hostnames: patterns, Ports: ports}} } func TestSNIRules(t *testing.T) { @@ -448,11 +448,11 @@ func TestSNIRules(t *testing.T) { } tests := []struct { name string - policy *ateapipb.EgressPolicy + policy *ateapi.EgressPolicy port uint16 want []SNIRule }{ - {name: "no rules", policy: &ateapipb.EgressPolicy{}, port: 443}, + {name: "no rules", policy: &ateapi.EgressPolicy{}, port: 443}, {name: "http rules decide requests, not connections", policy: policy(httpRule("api.example.com")), port: 80}, {name: "tls_passthrough on a named port", policy: policy(passthroughRule(ports(443), "tls.example.com", "*")), port: 443, want: passthrough("tls.example.com", "*")}, {name: "tls_passthrough on all ports", policy: policy(passthroughRule(allPorts(), "tls.example.com")), port: 8443, want: passthrough("tls.example.com")}, diff --git a/internal/hardware/hardware.go b/internal/hardware/hardware.go index 1887d3cd66..6848b6a5c7 100644 --- a/internal/hardware/hardware.go +++ b/internal/hardware/hardware.go @@ -19,8 +19,8 @@ package hardware import ( "runtime" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/proto/ateletpb" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const ( @@ -72,8 +72,8 @@ func ProbeHost() *ateletpb.VersionedSandboxCompat { // AttrCPUFeatures is parsed here, once, rather than on every comparison. The // zero Requirement, like NewRequirement(nil), requires nothing. type Requirement struct { - snap *ateapipb.ActorSandboxRuntime - compat *ateapipb.VersionedSandboxCompat // snap's version + snap *ateapi.ActorSandboxRuntime + compat *ateapi.VersionedSandboxCompat // snap's version // cpuFeatures is compat's AttrCPUFeatures parsed, when it has one. // badCPUFeatures records one that is not a canonical mask, which no // worker satisfies. @@ -82,13 +82,13 @@ type Requirement struct { } // NewRequirement prepares snap for matching. A nil snap requires nothing. -func NewRequirement(snap *ateapipb.ActorSandboxRuntime) Requirement { +func NewRequirement(snap *ateapi.ActorSandboxRuntime) Requirement { r := compatRequirement(snap.GetVersion()) r.snap = snap return r } -func compatRequirement(compat *ateapipb.VersionedSandboxCompat) Requirement { +func compatRequirement(compat *ateapi.VersionedSandboxCompat) Requirement { r := Requirement{compat: compat} for _, a := range compat.GetAttributes() { if a.GetKey() == AttrCPUFeatures { @@ -103,14 +103,14 @@ func compatRequirement(compat *ateapipb.VersionedSandboxCompat) Requirement { // Runtime returns the ActorSandboxRuntime the requirement was prepared from, or // nil when it requires nothing. -func (r Requirement) Runtime() *ateapipb.ActorSandboxRuntime { +func (r Requirement) Runtime() *ateapi.ActorSandboxRuntime { return r.snap } // Matches reports whether rt, the runtime an assignment records, can restore // the snapshot. A requirement of nothing is met by any runtime. Otherwise the // sandbox classes must be equal and the compat must match. -func (r Requirement) Matches(rt *ateapipb.ActorSandboxRuntime) bool { +func (r Requirement) Matches(rt *ateapi.ActorSandboxRuntime) bool { if r.snap == nil { return true } @@ -128,7 +128,7 @@ func (r Requirement) Matches(rt *ateapipb.ActorSandboxRuntime) bool { // start reporting a new key under the same schema version without // invalidating the snapshots taken before it; removing or recomputing a key // is a new schema version, under which older snapshots no longer match. -func (r Requirement) matchesCompat(worker *ateapipb.VersionedSandboxCompat) bool { +func (r Requirement) matchesCompat(worker *ateapi.VersionedSandboxCompat) bool { if worker == nil || r.compat == nil { return false } @@ -174,7 +174,7 @@ func (r Requirement) attributeSatisfied(key, workerVal, snapVal string) bool { // classOf returns the entry of status for class, or nil when the worker does // not run that class. -func classOf(status *ateapipb.WorkerStatus, class string) *ateapipb.WorkerSandboxClass { +func classOf(status *ateapi.WorkerStatus, class string) *ateapi.WorkerSandboxClass { for _, c := range status.GetSandboxClasses() { if c.GetSandboxClass() == class { return c @@ -185,8 +185,8 @@ func classOf(status *ateapipb.WorkerStatus, class string) *ateapipb.WorkerSandbo // runtimeOf is the ActorSandboxRuntime an assignment or snapshot is stamped with // for compat under class. -func runtimeOf(class string, compat *ateapipb.VersionedSandboxCompat) *ateapipb.ActorSandboxRuntime { - return &ateapipb.ActorSandboxRuntime{SandboxClass: class, Version: compat} +func runtimeOf(class string, compat *ateapi.VersionedSandboxCompat) *ateapi.ActorSandboxRuntime { + return &ateapi.ActorSandboxRuntime{SandboxClass: class, Version: compat} } // matchingCompat returns the version from status that can restore the @@ -194,7 +194,7 @@ func runtimeOf(class string, compat *ateapipb.VersionedSandboxCompat) *ateapipb. // first, then RestorableRuntimes in order. nil if the worker does not run // that class or nothing in its entry matches. Only for a requirement of // something. -func (r Requirement) matchingCompat(status *ateapipb.WorkerStatus) *ateapipb.VersionedSandboxCompat { +func (r Requirement) matchingCompat(status *ateapi.WorkerStatus) *ateapi.VersionedSandboxCompat { c := classOf(status, r.snap.GetSandboxClass()) if c == nil { return nil @@ -214,7 +214,7 @@ func (r Requirement) matchingCompat(status *ateapipb.WorkerStatus) *ateapipb.Ver // snapshot, as a stamp: the snapshot's class with the version matchingCompat // finds, or nil when it finds none. A requirement of nothing returns // ColdBootRuntime. -func (r Requirement) MatchingRuntime(status *ateapipb.WorkerStatus) *ateapipb.ActorSandboxRuntime { +func (r Requirement) MatchingRuntime(status *ateapi.WorkerStatus) *ateapi.ActorSandboxRuntime { if r.snap == nil { return ColdBootRuntime(status) } @@ -226,7 +226,7 @@ func (r Requirement) MatchingRuntime(status *ateapipb.WorkerStatus) *ateapipb.Ac // WorkerMatches reports whether a worker with status can restore the // snapshot. A requirement of nothing is met by any worker. -func (r Requirement) WorkerMatches(status *ateapipb.WorkerStatus) bool { +func (r Requirement) WorkerMatches(status *ateapi.WorkerStatus) bool { return r.snap == nil || r.matchingCompat(status) != nil } @@ -235,7 +235,7 @@ func (r Requirement) WorkerMatches(status *ateapipb.WorkerStatus) bool { // when it can restore the snapshot, else the ColdBootRuntime the guest boots // fresh under. This is what an assignment records and what the actor's next // checkpoint is stamped with. -func (r Requirement) RuntimeFor(status *ateapipb.WorkerStatus) *ateapipb.ActorSandboxRuntime { +func (r Requirement) RuntimeFor(status *ateapi.WorkerStatus) *ateapi.ActorSandboxRuntime { if rt := r.MatchingRuntime(status); rt != nil { return rt } @@ -245,7 +245,7 @@ func (r Requirement) RuntimeFor(status *ateapipb.WorkerStatus) *ateapipb.ActorSa // ColdBootRuntime returns the runtime a fresh actor starts under on a worker // with status: the DefaultRuntime of its class, as a stamp, or nil before the // worker has registered. -func ColdBootRuntime(status *ateapipb.WorkerStatus) *ateapipb.ActorSandboxRuntime { +func ColdBootRuntime(status *ateapi.WorkerStatus) *ateapi.ActorSandboxRuntime { classes := status.GetSandboxClasses() if len(classes) == 0 { return nil @@ -255,7 +255,7 @@ func ColdBootRuntime(status *ateapipb.WorkerStatus) *ateapipb.ActorSandboxRuntim // SandboxClass returns the sandbox class a worker with status registered, or // "" before it has. -func SandboxClass(status *ateapipb.WorkerStatus) string { +func SandboxClass(status *ateapi.WorkerStatus) string { classes := status.GetSandboxClasses() if len(classes) == 0 { return "" @@ -267,28 +267,28 @@ func SandboxClass(status *ateapipb.WorkerStatus) string { // a snapshot stamped with snap, for one comparison; a caller holding one snap // against many workers should prepare a Requirement once. A nil snap imposes // no constraint. -func Matches(rt, snap *ateapipb.ActorSandboxRuntime) bool { +func Matches(rt, snap *ateapi.ActorSandboxRuntime) bool { return NewRequirement(snap).Matches(rt) } // MatchesCompat reports whether worker can restore a snapshot stamped with // snap, for one comparison. Unlike Matches, a nil snap is a stamp missing its // identity and matches nothing. -func MatchesCompat(worker, snap *ateapipb.VersionedSandboxCompat) bool { +func MatchesCompat(worker, snap *ateapi.VersionedSandboxCompat) bool { return compatRequirement(snap).matchesCompat(worker) } // MatchingRuntime is NewRequirement(snap).MatchingRuntime(status). -func MatchingRuntime(status *ateapipb.WorkerStatus, snap *ateapipb.ActorSandboxRuntime) *ateapipb.ActorSandboxRuntime { +func MatchingRuntime(status *ateapi.WorkerStatus, snap *ateapi.ActorSandboxRuntime) *ateapi.ActorSandboxRuntime { return NewRequirement(snap).MatchingRuntime(status) } // WorkerMatches is NewRequirement(snap).WorkerMatches(status). -func WorkerMatches(status *ateapipb.WorkerStatus, snap *ateapipb.ActorSandboxRuntime) bool { +func WorkerMatches(status *ateapi.WorkerStatus, snap *ateapi.ActorSandboxRuntime) bool { return NewRequirement(snap).WorkerMatches(status) } // RuntimeFor is NewRequirement(snap).RuntimeFor(status). -func RuntimeFor(status *ateapipb.WorkerStatus, snap *ateapipb.ActorSandboxRuntime) *ateapipb.ActorSandboxRuntime { +func RuntimeFor(status *ateapi.WorkerStatus, snap *ateapi.ActorSandboxRuntime) *ateapi.ActorSandboxRuntime { return NewRequirement(snap).RuntimeFor(status) } diff --git a/internal/hardware/hardware_test.go b/internal/hardware/hardware_test.go index bd268cb80a..0465917bc1 100644 --- a/internal/hardware/hardware_test.go +++ b/internal/hardware/hardware_test.go @@ -18,7 +18,7 @@ import ( "runtime" "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/protobuf/proto" ) @@ -34,45 +34,45 @@ func TestProbeHost(t *testing.T) { } func TestMatches(t *testing.T) { - runtimeWith := func(class, ver string, attrs ...*ateapipb.AttributeEntry) *ateapipb.ActorSandboxRuntime { - return &ateapipb.ActorSandboxRuntime{ + runtimeWith := func(class, ver string, attrs ...*ateapi.AttributeEntry) *ateapi.ActorSandboxRuntime { + return &ateapi.ActorSandboxRuntime{ SandboxClass: class, - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: ver, Attributes: attrs, }, } } amd64GVisor := runtimeWith("gvisor", "v1", - &ateapipb.AttributeEntry{Key: AttrArchitecture, Value: "amd64"}, - &ateapipb.AttributeEntry{Key: AttrCPUFeatures, Value: "7"}, + &ateapi.AttributeEntry{Key: AttrArchitecture, Value: "amd64"}, + &ateapi.AttributeEntry{Key: AttrCPUFeatures, Value: "7"}, ) amd64GVisorReordered := runtimeWith("gvisor", "v1", - &ateapipb.AttributeEntry{Key: AttrCPUFeatures, Value: "7"}, - &ateapipb.AttributeEntry{Key: AttrArchitecture, Value: "amd64"}, + &ateapi.AttributeEntry{Key: AttrCPUFeatures, Value: "7"}, + &ateapi.AttributeEntry{Key: AttrArchitecture, Value: "amd64"}, ) arm64GVisor := runtimeWith("gvisor", "v1", - &ateapipb.AttributeEntry{Key: AttrArchitecture, Value: "arm64"}, - &ateapipb.AttributeEntry{Key: AttrCPUFeatures, Value: "7"}, + &ateapi.AttributeEntry{Key: AttrArchitecture, Value: "arm64"}, + &ateapi.AttributeEntry{Key: AttrCPUFeatures, Value: "7"}, ) amd64MicroVM := runtimeWith("microvm", "v1", - &ateapipb.AttributeEntry{Key: AttrArchitecture, Value: "amd64"}, - &ateapipb.AttributeEntry{Key: AttrCPUFeatures, Value: "7"}, + &ateapi.AttributeEntry{Key: AttrArchitecture, Value: "amd64"}, + &ateapi.AttributeEntry{Key: AttrCPUFeatures, Value: "7"}, ) amd64GVisorV2 := runtimeWith("gvisor", "v2", - &ateapipb.AttributeEntry{Key: AttrArchitecture, Value: "amd64"}, - &ateapipb.AttributeEntry{Key: AttrCPUFeatures, Value: "7"}, + &ateapi.AttributeEntry{Key: AttrArchitecture, Value: "amd64"}, + &ateapi.AttributeEntry{Key: AttrCPUFeatures, Value: "7"}, ) amd64GVisorExtraAttr := runtimeWith("gvisor", "v1", - &ateapipb.AttributeEntry{Key: AttrArchitecture, Value: "amd64"}, - &ateapipb.AttributeEntry{Key: AttrCPUFeatures, Value: "7"}, - &ateapipb.AttributeEntry{Key: AttrSandboxBundleHash, Value: "sha256:abc"}, + &ateapi.AttributeEntry{Key: AttrArchitecture, Value: "amd64"}, + &ateapi.AttributeEntry{Key: AttrCPUFeatures, Value: "7"}, + &ateapi.AttributeEntry{Key: AttrSandboxBundleHash, Value: "sha256:abc"}, ) tests := []struct { name string - worker *ateapipb.ActorSandboxRuntime - snap *ateapipb.ActorSandboxRuntime + worker *ateapi.ActorSandboxRuntime + snap *ateapi.ActorSandboxRuntime want bool }{ {"nil snapshot imposes no constraint", amd64GVisor, nil, true}, @@ -84,7 +84,7 @@ func TestMatches(t *testing.T) { {"attribute only the worker has is ignored", amd64GVisorExtraAttr, amd64GVisor, true}, {"attribute missing on worker fails", amd64GVisor, amd64GVisorExtraAttr, false}, {"nil worker fails when snapshot is stamped", nil, amd64GVisor, false}, - {"nil version fails", &ateapipb.ActorSandboxRuntime{SandboxClass: "gvisor"}, amd64GVisor, false}, + {"nil version fails", &ateapi.ActorSandboxRuntime{SandboxClass: "gvisor"}, amd64GVisor, false}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { @@ -96,14 +96,14 @@ func TestMatches(t *testing.T) { } func TestMatchesCompat(t *testing.T) { - compat := func(ver string, attrs ...*ateapipb.AttributeEntry) *ateapipb.VersionedSandboxCompat { - return &ateapipb.VersionedSandboxCompat{SchemaVersion: ver, Attributes: attrs} + compat := func(ver string, attrs ...*ateapi.AttributeEntry) *ateapi.VersionedSandboxCompat { + return &ateapi.VersionedSandboxCompat{SchemaVersion: ver, Attributes: attrs} } - amd64 := &ateapipb.AttributeEntry{Key: AttrArchitecture, Value: "amd64"} - arm64 := &ateapipb.AttributeEntry{Key: AttrArchitecture, Value: "arm64"} - hash := &ateapipb.AttributeEntry{Key: AttrSandboxBundleHash, Value: "sha256:abc"} - cpuBits := func(val string) *ateapipb.AttributeEntry { - return &ateapipb.AttributeEntry{Key: AttrCPUFeatures, Value: val} + amd64 := &ateapi.AttributeEntry{Key: AttrArchitecture, Value: "amd64"} + arm64 := &ateapi.AttributeEntry{Key: AttrArchitecture, Value: "arm64"} + hash := &ateapi.AttributeEntry{Key: AttrSandboxBundleHash, Value: "sha256:abc"} + cpuBits := func(val string) *ateapi.AttributeEntry { + return &ateapi.AttributeEntry{Key: AttrCPUFeatures, Value: val} } // Build >64-bit masks so the subset check spans mask words. @@ -122,7 +122,7 @@ func TestMatchesCompat(t *testing.T) { tests := []struct { name string - worker, snap *ateapipb.VersionedSandboxCompat + worker, snap *ateapi.VersionedSandboxCompat want bool }{ {"equal", compat("v1", amd64), compat("v1", amd64), true}, @@ -161,12 +161,12 @@ func TestMatchesCompat(t *testing.T) { // of the snapshot must hold across comparisons, and the zero value must // require nothing. func TestRequirement(t *testing.T) { - rt := func(cpu string) *ateapipb.ActorSandboxRuntime { - return &ateapipb.ActorSandboxRuntime{ + rt := func(cpu string) *ateapi.ActorSandboxRuntime { + return &ateapi.ActorSandboxRuntime{ SandboxClass: "gvisor", - Version: &ateapipb.VersionedSandboxCompat{ + Version: &ateapi.VersionedSandboxCompat{ SchemaVersion: SchemaVersionV1, - Attributes: []*ateapipb.AttributeEntry{ + Attributes: []*ateapi.AttributeEntry{ {Key: AttrArchitecture, Value: "amd64"}, {Key: AttrCPUFeatures, Value: cpu}, }, @@ -180,7 +180,7 @@ func TestRequirement(t *testing.T) { } for _, tc := range []struct { name string - worker *ateapipb.ActorSandboxRuntime + worker *ateapi.ActorSandboxRuntime want bool }{ {"worker superset", rt("f"), true}, @@ -192,10 +192,10 @@ func TestRequirement(t *testing.T) { t.Errorf("%s: Matches() = %v, want %v", tc.name, got, tc.want) } } - status := &ateapipb.WorkerStatus{SandboxClasses: []*ateapipb.WorkerSandboxClass{{ + status := &ateapi.WorkerStatus{SandboxClasses: []*ateapi.WorkerSandboxClass{{ SandboxClass: "gvisor", - DefaultRuntime: &ateapipb.WorkerSandboxRuntime{Version: rt("3").GetVersion()}, - RestorableRuntimes: []*ateapipb.WorkerSandboxRuntime{{Version: rt("f").GetVersion()}}, + DefaultRuntime: &ateapi.WorkerSandboxRuntime{Version: rt("3").GetVersion()}, + RestorableRuntimes: []*ateapi.WorkerSandboxRuntime{{Version: rt("f").GetVersion()}}, }}} if got := req.MatchingRuntime(status); !proto.Equal(got, rt("f")) { t.Errorf("MatchingRuntime() = %v, want the restorable superset", got) @@ -216,15 +216,15 @@ func TestRequirement(t *testing.T) { } func TestMatchingRuntimeAndWorkerMatches(t *testing.T) { - compat := func(arch, hash string) *ateapipb.VersionedSandboxCompat { - attrs := []*ateapipb.AttributeEntry{{Key: AttrArchitecture, Value: arch}} + compat := func(arch, hash string) *ateapi.VersionedSandboxCompat { + attrs := []*ateapi.AttributeEntry{{Key: AttrArchitecture, Value: arch}} if hash != "" { - attrs = append(attrs, &ateapipb.AttributeEntry{Key: AttrSandboxBundleHash, Value: hash}) + attrs = append(attrs, &ateapi.AttributeEntry{Key: AttrSandboxBundleHash, Value: hash}) } - return &ateapipb.VersionedSandboxCompat{SchemaVersion: SchemaVersionV1, Attributes: attrs} + return &ateapi.VersionedSandboxCompat{SchemaVersion: SchemaVersionV1, Attributes: attrs} } - rt := func(class string, c *ateapipb.VersionedSandboxCompat) *ateapipb.ActorSandboxRuntime { - return &ateapipb.ActorSandboxRuntime{SandboxClass: class, Version: c} + rt := func(class string, c *ateapi.VersionedSandboxCompat) *ateapi.ActorSandboxRuntime { + return &ateapi.ActorSandboxRuntime{SandboxClass: class, Version: c} } defCompat := compat("amd64", "v2-hash") @@ -233,17 +233,17 @@ func TestMatchingRuntimeAndWorkerMatches(t *testing.T) { defRT := rt("gvisor", defCompat) unmatchedRT := rt("gvisor", compat("arm64", "v2-hash")) - status := &ateapipb.WorkerStatus{SandboxClasses: []*ateapipb.WorkerSandboxClass{{ + status := &ateapi.WorkerStatus{SandboxClasses: []*ateapi.WorkerSandboxClass{{ SandboxClass: "gvisor", - DefaultRuntime: &ateapipb.WorkerSandboxRuntime{Version: defCompat}, - RestorableRuntimes: []*ateapipb.WorkerSandboxRuntime{{Version: restorable1}, {Version: restorable2}}, + DefaultRuntime: &ateapi.WorkerSandboxRuntime{Version: defCompat}, + RestorableRuntimes: []*ateapi.WorkerSandboxRuntime{{Version: restorable1}, {Version: restorable2}}, }}} t.Run("nil snap matches any worker status and returns the default", func(t *testing.T) { if !WorkerMatches(nil, nil) { t.Errorf("WorkerMatches(nil, nil) = false, want true") } - if !WorkerMatches(&ateapipb.WorkerStatus{}, nil) { + if !WorkerMatches(&ateapi.WorkerStatus{}, nil) { t.Errorf("WorkerMatches(empty, nil) = false, want true") } if got := MatchingRuntime(status, nil); !proto.Equal(got, defRT) { @@ -303,13 +303,13 @@ func TestMatchingRuntimeAndWorkerMatches(t *testing.T) { t.Errorf("RuntimeFor(status, nil) = %v, want %v", got, defRT) } // A worker that reported no classes runs the actor under none. - if got := RuntimeFor(&ateapipb.WorkerStatus{}, unmatchedRT); got != nil { + if got := RuntimeFor(&ateapi.WorkerStatus{}, unmatchedRT); got != nil { t.Errorf("RuntimeFor(empty, unmatchedRT) = %v, want nil", got) } }) t.Run("ColdBootRuntime before registration", func(t *testing.T) { - if got := ColdBootRuntime(&ateapipb.WorkerStatus{}); got != nil { + if got := ColdBootRuntime(&ateapi.WorkerStatus{}); got != nil { t.Errorf("ColdBootRuntime(empty) = %v, want nil", got) } if got := ColdBootRuntime(nil); got != nil { diff --git a/internal/imagecache/README.md b/internal/imagecache/README.md index fe992bd9ca..672f7240be 100644 --- a/internal/imagecache/README.md +++ b/internal/imagecache/README.md @@ -145,8 +145,8 @@ staging the virtio-fs lower (micro-VM): The mount uses the new mount API (`fsopen` + one `fsconfig` `lowerdir+` append per layer) rather than `mount(2)`, whose single-page option-string cap the digest-derived layer paths would hit at ~34 layers. **Minimum - supported kernel: Linux 6.5** (`lowerdir+`); every current GKE channel - ships ≥ 6.6 (Stable: COS 121 LTS). + supported kernel: Linux 6.7, or 6.6.23** (`lowerdir+`, backported to + 6.6.y). 3. **ExtraDirs** are created through the mount (landing in the upper), again under `os.Root` confinement. 4. **Implicit-parent metadata repair.** A layer tar routinely omits entries diff --git a/internal/imagecache/bundle_linux.go b/internal/imagecache/bundle_linux.go index 0cb364352d..a60f762ff8 100644 --- a/internal/imagecache/bundle_linux.go +++ b/internal/imagecache/bundle_linux.go @@ -154,10 +154,10 @@ func mountImageVolume(mountpoint string, layers []string) error { // An empty upper mounts the overlay without a writable layer, which overlayfs // makes read-only. // -// Minimum supported kernel: Linux 6.5, where overlayfs gained the -// incremental "lowerdir+" option. Every current GKE channel is at or above -// it (Stable runs COS 121 LTS on kernel 6.6; Regular and Rapid run COS -// 125/129 on 6.12). +// Requires overlayfs's "lowerdir+" option: Linux 6.7+, or 6.6.23+ where it was +// backported. +// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=24e16e385f2272b1a9df51337a5c32d28a29c7ad +// https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=cc0918b3582c98f12cfb30bf7496496d14bff3e9 func mountOverlay(mountpoint string, lowers []string, upper, work string) error { fsfd, err := unix.Fsopen("overlay", unix.FSOPEN_CLOEXEC) if err != nil { diff --git a/internal/objectstoreplugin/actorlookup/lookup.go b/internal/objectstoreplugin/actorlookup/lookup.go index e57a8c9b50..5c9c44d2a4 100644 --- a/internal/objectstoreplugin/actorlookup/lookup.go +++ b/internal/objectstoreplugin/actorlookup/lookup.go @@ -26,9 +26,9 @@ import ( "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "google.golang.org/grpc" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/actoridjwt" "go.ate.dev/substrate/internal/ateapiauth" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // ErrStale is returned when the actor at the name a JWT carries has a @@ -53,7 +53,7 @@ type Config struct { // Lookup resolves actors over one connection to ate-api-server. type Lookup struct { conn *grpc.ClientConn - client ateapipb.ControlClient + client ateapi.ControlClient } // New dials ate-api-server. The connection is lazy, so a server that is not up @@ -77,19 +77,19 @@ func New(cfg Config) (*Lookup, error) { if err != nil { return nil, fmt.Errorf("actorlookup: while creating the ate-api-server client: %w", err) } - return &Lookup{conn: conn, client: ateapipb.NewControlClient(conn)}, nil + return &Lookup{conn: conn, client: ateapi.NewControlClient(conn)}, nil } // Actor returns the actor the claims name. The claims come from a verified // JWT, so the atespace and name are trusted, but the actor may have been // recreated since, which the UID detects. A gRPC status error from // ate-api-server, such as NotFound, is returned unchanged. -func (l *Lookup) Actor(ctx context.Context, claims *actoridjwt.WireSubstrateClaims) (*ateapipb.Actor, error) { +func (l *Lookup) Actor(ctx context.Context, claims *actoridjwt.WireSubstrateClaims) (*ateapi.Actor, error) { if claims == nil || claims.Atespace == "" || claims.ActorName == "" || claims.ActorUID == "" { return nil, errors.New("actorlookup: claims lack atespace, actor name, or UID") } - actor, err := l.client.GetActor(ctx, &ateapipb.GetActorRequest{ - Actor: &ateapipb.ObjectRef{Atespace: claims.Atespace, Name: claims.ActorName}, + actor, err := l.client.GetActor(ctx, &ateapi.GetActorRequest{ + Actor: &ateapi.ObjectRef{Atespace: claims.Atespace, Name: claims.ActorName}, }) if err != nil { return nil, err diff --git a/internal/objectstoreplugin/actorlookup/lookup_test.go b/internal/objectstoreplugin/actorlookup/lookup_test.go index c3d81be4fe..6a3535ea57 100644 --- a/internal/objectstoreplugin/actorlookup/lookup_test.go +++ b/internal/objectstoreplugin/actorlookup/lookup_test.go @@ -38,8 +38,8 @@ import ( "google.golang.org/grpc/peer" "google.golang.org/grpc/status" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/actoridjwt" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const serverName = "api.ate-system.svc" @@ -47,12 +47,12 @@ const serverName = "api.ate-system.svc" // fakeControl serves GetActor for one actor and records the client identity // it saw. type fakeControl struct { - ateapipb.UnimplementedControlServer - actor *ateapipb.Actor + ateapi.UnimplementedControlServer + actor *ateapi.Actor peerURIs []*url.URL } -func (f *fakeControl) GetActor(ctx context.Context, req *ateapipb.GetActorRequest) (*ateapipb.Actor, error) { +func (f *fakeControl) GetActor(ctx context.Context, req *ateapi.GetActorRequest) (*ateapi.Actor, error) { if p, ok := peerCert(ctx); ok { f.peerURIs = p.URIs } @@ -96,7 +96,7 @@ func startServer(t *testing.T, fake *fakeControl, spiffeID string) Config { ClientAuth: tls.RequireAndVerifyClientCert, ClientCAs: pool, }))) - ateapipb.RegisterControlServer(srv, fake) + ateapi.RegisterControlServer(srv, fake) lis, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) @@ -106,8 +106,8 @@ func startServer(t *testing.T, fake *fakeControl, spiffeID string) Config { return Config{Address: lis.Addr().String(), CAFile: caFile, ServerName: serverName, ClientCredBundle: bundle} } -func testActor(uid string) *ateapipb.Actor { - return &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "agent-1", Uid: uid}} +func testActor(uid string) *ateapi.Actor { + return &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "agent-1", Uid: uid}} } func TestActor(t *testing.T) { diff --git a/internal/objectstoreplugin/actorscope/actorscope.go b/internal/objectstoreplugin/actorscope/actorscope.go index ffef87b397..98ffc9b966 100644 --- a/internal/objectstoreplugin/actorscope/actorscope.go +++ b/internal/objectstoreplugin/actorscope/actorscope.go @@ -22,8 +22,8 @@ import ( "fmt" "sort" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // Access is what a grant permits under its prefix. @@ -72,7 +72,7 @@ type Grant struct { // The status is taken as ate-api-server wrote it. An owner this code does not // know is an error, so a new kind is never silently dropped. Local-only // generations have no URI and contribute nothing. -func FromActor(actor *ateapipb.Actor) ([]Grant, error) { +func FromActor(actor *ateapi.Actor) ([]Grant, error) { meta := actor.GetMetadata() self := resources.ActorSnapshotOwner(meta.GetAtespace(), meta.GetUid()) seen := map[Grant]bool{} @@ -100,10 +100,10 @@ func FromActor(actor *ateapipb.Actor) ([]Grant, error) { } add(own, ReadWrite) switch gen.GetOwner() { - case ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR: + case ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR: // Its own prefix is already granted above. - case ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG: - if durable.GetStatus() != ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { + case ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG: + if durable.GetStatus() != ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED { continue } add(parsed.OwnerPrefix(), ReadOnly) diff --git a/internal/objectstoreplugin/actorscope/actorscope_test.go b/internal/objectstoreplugin/actorscope/actorscope_test.go index 021c053d22..2cec8b1191 100644 --- a/internal/objectstoreplugin/actorscope/actorscope_test.go +++ b/internal/objectstoreplugin/actorscope/actorscope_test.go @@ -19,8 +19,8 @@ import ( "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const ( @@ -34,20 +34,20 @@ func actorURI(location, name string) string { return location + "/atespaces/" + atespace + "/actors/" + uid + "/snapshots/" + name } -func gen(n int32, owner ateapipb.SnapshotOwner, status ateapipb.SnapshotStorageStatus, uri string) *ateapipb.Snapshot { - s := &ateapipb.Snapshot{Generation: n, Owner: owner} +func gen(n int32, owner ateapi.SnapshotOwner, status ateapi.SnapshotStorageStatus, uri string) *ateapi.Snapshot { + s := &ateapi.Snapshot{Generation: n, Owner: owner} if uri != "" { - s.DurableSnapshot = &ateapipb.SnapshotStorage{Status: status, Object: &ateapipb.ObjectSnapshot{SnapshotUri: uri}} + s.DurableSnapshot = &ateapi.SnapshotStorage{Status: status, Object: &ateapi.ObjectSnapshot{SnapshotUri: uri}} } else { s.Locality = "node-1" } return s } -func actorWith(snaps ...*ateapipb.Snapshot) *ateapipb.Actor { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: "bot", Uid: uid}, - Status: &ateapipb.ActorStatus{Snapshots: snaps}, +func actorWith(snaps ...*ateapi.Snapshot) *ateapi.Actor { + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: "bot", Uid: uid}, + Status: &ateapi.ActorStatus{Snapshots: snaps}, } } @@ -65,16 +65,16 @@ var ( tagURI = loc + "/atespaces/ate-golden/tags/" + tagUID tagGrant = Grant{Prefix: prefix(tagURI), Access: ReadOnly} actorGrant = Grant{Prefix: prefix(loc + "/atespaces/" + atespace + "/actors/" + uid), Access: ReadWrite} - completed = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED - pending = ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING - ownerActor = ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR - ownerTag = ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG + completed = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED + pending = ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_PENDING + ownerActor = ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR + ownerTag = ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG ) func TestFromActor(t *testing.T) { for _, tc := range []struct { name string - actor *ateapipb.Actor + actor *ateapi.Actor want []Grant }{ { @@ -146,7 +146,7 @@ func TestFromActor(t *testing.T) { } func TestFromActor_RefusesUnknownOwner(t *testing.T) { - if _, err := FromActor(actorWith(gen(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_UNSPECIFIED, completed, tagURI))); err == nil { + if _, err := FromActor(actorWith(gen(1, ateapi.SnapshotOwner_SNAPSHOT_OWNER_UNSPECIFIED, completed, tagURI))); err == nil { t.Fatal("a generation with an unspecified owner was accepted") } } diff --git a/internal/objectstoreplugin/asset.go b/internal/objectstoreplugin/asset.go index 36bd0dc7de..b31bbfe647 100644 --- a/internal/objectstoreplugin/asset.go +++ b/internal/objectstoreplugin/asset.go @@ -20,9 +20,9 @@ import ( "io" "strings" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/pkg/assetfetch" "go.ate.dev/substrate/pkg/objectstorage" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -38,7 +38,7 @@ import ( // check out (see assetfetch.Stager). The caller can therefore never read bytes // it did not pin, such as a snapshot's. type AssetPlugin struct { - objectstorev1.UnimplementedAssetProviderServer + objectstore.UnimplementedAssetProviderServer client objectstorage.ObjectStorage scheme string @@ -63,7 +63,7 @@ func NewAssetPlugin(client objectstorage.ObjectStorage, scheme, root, stagingDir // FetchAsset downloads the object at asset_uri into the staging directory and, // if it is at most max_bytes long and hashes to sha256, copies it into the // existing file at write_path (see assetfetch.Stager.Fetch). -func (p *AssetPlugin) FetchAsset(ctx context.Context, req *objectstorev1.FetchAssetRequest) (*objectstorev1.FetchAssetResponse, error) { +func (p *AssetPlugin) FetchAsset(ctx context.Context, req *objectstore.FetchAssetRequest) (*objectstore.FetchAssetResponse, error) { bucket, object, err := parseAssetURI(req.GetAssetUri(), p.scheme) if err != nil { return nil, err @@ -82,7 +82,7 @@ func (p *AssetPlugin) FetchAsset(ctx context.Context, req *objectstorev1.FetchAs if err := p.stager.Fetch(ctx, req, req.GetAssetUri(), open, toStatus); err != nil { return nil, err } - return &objectstorev1.FetchAssetResponse{}, nil + return &objectstore.FetchAssetResponse{}, nil } // parseAssetURI accepts :/// whose object name is in diff --git a/internal/objectstoreplugin/asset_test.go b/internal/objectstoreplugin/asset_test.go index 3ab28d6d84..dabb5d42de 100644 --- a/internal/objectstoreplugin/asset_test.go +++ b/internal/objectstoreplugin/asset_test.go @@ -26,9 +26,9 @@ import ( "sync/atomic" "testing" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/internal/pluginsocket" "go.ate.dev/substrate/pkg/assetfetch" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -66,7 +66,7 @@ func (r *sizedReader) ObjectSize() int64 { return r.size } // assetFixture is an AssetProvider served on a real Unix socket, as the // sidecar serves it, with a write root and a separate staging directory. type assetFixture struct { - client objectstorev1.AssetProviderClient + client objectstore.AssetProviderClient backend *countingObjects root string staging string @@ -95,7 +95,7 @@ func newAssetFixture(t *testing.T, scheme string) *assetFixture { t.Fatal(err) } srv := grpc.NewServer() - objectstorev1.RegisterAssetProviderServer(srv, plugin) + objectstore.RegisterAssetProviderServer(srv, plugin) go srv.Serve(lis) t.Cleanup(srv.Stop) conn, err := pluginsocket.Dial(sock, pluginsocket.ReadyWait) @@ -103,7 +103,7 @@ func newAssetFixture(t *testing.T, scheme string) *assetFixture { t.Fatal(err) } t.Cleanup(func() { conn.Close() }) - f.client = objectstorev1.NewAssetProviderClient(conn) + f.client = objectstore.NewAssetProviderClient(conn) return f } @@ -164,7 +164,7 @@ func TestFetchAsset(t *testing.T) { f := newAssetFixture(t, scheme) sum := f.put(t, "kata-assets/vmlinux", content) dst := f.writeFile(t, untouched) - _, err := f.client.FetchAsset(t.Context(), &objectstorev1.FetchAssetRequest{ + _, err := f.client.FetchAsset(t.Context(), &objectstore.FetchAssetRequest{ AssetUri: scheme + "://" + testBucket + "/kata-assets/vmlinux", Sha256: sum, WritePath: dst, @@ -182,7 +182,7 @@ func TestFetchAsset(t *testing.T) { f := newAssetFixture(t, "gs") f.put(t, "kata-assets/vmlinux", content) dst := f.writeFile(t, untouched) - _, err := f.client.FetchAsset(t.Context(), &objectstorev1.FetchAssetRequest{ + _, err := f.client.FetchAsset(t.Context(), &objectstore.FetchAssetRequest{ AssetUri: "gs://" + testBucket + "/kata-assets/vmlinux", Sha256: strings.Repeat("a", 64), WritePath: dst, @@ -199,7 +199,7 @@ func TestFetchAsset(t *testing.T) { f := newAssetFixture(t, "gs") sum := f.put(t, "kata-assets/vmlinux", content) dst := f.writeFile(t, untouched) - _, err := f.client.FetchAsset(t.Context(), &objectstorev1.FetchAssetRequest{ + _, err := f.client.FetchAsset(t.Context(), &objectstore.FetchAssetRequest{ AssetUri: "gs://" + testBucket + "/kata-assets/vmlinux", Sha256: sum, WritePath: dst, @@ -217,7 +217,7 @@ func TestFetchAsset(t *testing.T) { f := newAssetFixture(t, tc.plugin) sum := f.put(t, "kata-assets/vmlinux", content) dst := f.writeFile(t, untouched) - _, err := f.client.FetchAsset(t.Context(), &objectstorev1.FetchAssetRequest{ + _, err := f.client.FetchAsset(t.Context(), &objectstore.FetchAssetRequest{ AssetUri: tc.asset + "://" + testBucket + "/kata-assets/vmlinux", Sha256: sum, WritePath: dst, @@ -238,7 +238,7 @@ func TestFetchAsset(t *testing.T) { f.backend.reportSize = true sum := f.put(t, "kata-assets/vmlinux", content) dst := f.writeFile(t, untouched) - _, err := f.client.FetchAsset(t.Context(), &objectstorev1.FetchAssetRequest{ + _, err := f.client.FetchAsset(t.Context(), &objectstore.FetchAssetRequest{ AssetUri: "gs://" + testBucket + "/kata-assets/vmlinux", Sha256: sum, WritePath: dst, @@ -255,7 +255,7 @@ func TestFetchAsset(t *testing.T) { t.Run("not found", func(t *testing.T) { f := newAssetFixture(t, "gs") dst := f.writeFile(t, untouched) - _, err := f.client.FetchAsset(t.Context(), &objectstorev1.FetchAssetRequest{ + _, err := f.client.FetchAsset(t.Context(), &objectstore.FetchAssetRequest{ AssetUri: "gs://" + testBucket + "/kata-assets/missing", Sha256: strings.Repeat("a", 64), WritePath: dst, @@ -294,7 +294,7 @@ func TestFetchAsset(t *testing.T) { {"directory", dir, codes.FailedPrecondition}, {"symlink to a file outside root", link, codes.FailedPrecondition}, } { - _, err := f.client.FetchAsset(t.Context(), &objectstorev1.FetchAssetRequest{ + _, err := f.client.FetchAsset(t.Context(), &objectstore.FetchAssetRequest{ AssetUri: "gs://" + testBucket + "/kata-assets/vmlinux", Sha256: sum, WritePath: tc.path, @@ -337,7 +337,7 @@ func TestFetchAsset(t *testing.T) { {"zero max_bytes", "gs://" + testBucket + "/kata-assets/vmlinux", sum, 0}, {"over-long URI", "gs://" + testBucket + "/" + strings.Repeat("x/", assetfetch.MaxURIBytes/2) + "vmlinux", sum, 1 << 20}, } { - _, err := f.client.FetchAsset(t.Context(), &objectstorev1.FetchAssetRequest{ + _, err := f.client.FetchAsset(t.Context(), &objectstore.FetchAssetRequest{ AssetUri: tc.uri, Sha256: tc.sum, WritePath: dst, MaxBytes: tc.max, }) if status.Code(err) != codes.InvalidArgument { @@ -387,7 +387,7 @@ func testFetchAssetRefusesSnapshots(t *testing.T, scheme string) { dst := f.writeFile(t, untouched) for _, object := range snapshotObjects { uri := scheme + "://" + testBucket + "/" + object - _, err := f.client.FetchAsset(t.Context(), &objectstorev1.FetchAssetRequest{ + _, err := f.client.FetchAsset(t.Context(), &objectstore.FetchAssetRequest{ AssetUri: uri, Sha256: sums[object], WritePath: dst, @@ -409,7 +409,7 @@ func testFetchAssetRefusesSnapshots(t *testing.T, scheme string) { if object != "kata-assets/vmlinux" { sum = f.put(t, object, []byte("asset "+object)) } - if _, err := f.client.FetchAsset(t.Context(), &objectstorev1.FetchAssetRequest{ + if _, err := f.client.FetchAsset(t.Context(), &objectstore.FetchAssetRequest{ AssetUri: scheme + "://" + testBucket + "/" + object, Sha256: sum, WritePath: dst, @@ -441,7 +441,7 @@ func TestFetchAssetManySegmentURIs(t *testing.T) { served := pad("x/", "/vmlinux") object := strings.TrimPrefix(served, "s3://"+testBucket+"/") sum := f.put(t, object, []byte("kernel")) - if _, err := f.client.FetchAsset(t.Context(), &objectstorev1.FetchAssetRequest{ + if _, err := f.client.FetchAsset(t.Context(), &objectstore.FetchAssetRequest{ AssetUri: served, Sha256: sum, WritePath: dst, MaxBytes: 1 << 20, }); err != nil { t.Fatalf("FetchAsset(%d segments) = %v, want success", strings.Count(served, "/")-2, err) @@ -457,7 +457,7 @@ func TestFetchAssetManySegmentURIs(t *testing.T) { {"tag after many owner-like segments", pad("atespaces/team-a/actors/", "/atespaces/team-a/tags/tag1/manifest.json"), codes.PermissionDenied}, {"one byte over the limit", served + "x", codes.InvalidArgument}, } { - _, err := f.client.FetchAsset(t.Context(), &objectstorev1.FetchAssetRequest{ + _, err := f.client.FetchAsset(t.Context(), &objectstore.FetchAssetRequest{ AssetUri: tc.uri, Sha256: sum, WritePath: dst, MaxBytes: 1 << 20, }) if status.Code(err) != tc.want { diff --git a/internal/objectstoreplugin/control.go b/internal/objectstoreplugin/control.go index 6541584e08..5099adbec3 100644 --- a/internal/objectstoreplugin/control.go +++ b/internal/objectstoreplugin/control.go @@ -17,9 +17,9 @@ package objectstoreplugin import ( "context" + objectstorev1 "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/internal/objectstore" "go.ate.dev/substrate/internal/resources" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/internal/objectstoreplugin/credentials_test.go b/internal/objectstoreplugin/credentials_test.go index 4adbd35b16..93d1266b17 100644 --- a/internal/objectstoreplugin/credentials_test.go +++ b/internal/objectstoreplugin/credentials_test.go @@ -29,8 +29,8 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/pkg/objectstorage" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" ) // refusingObjects wraps a backend and answers 403 to every object request @@ -121,7 +121,7 @@ func TestTransferRetriesOnceWithAReplacedCredential(t *testing.T) { creds := &fakeCredentials{backend: newMemObjects(), stale: true} p := newCredsPlugin(t, creds, root) - _, err := p.UploadSnapshot(t.Context(), &objectstorev1.UploadSnapshotRequest{ + _, err := p.UploadSnapshot(t.Context(), &objectstore.UploadSnapshotRequest{ SnapshotUri: testURI, ActorJwt: "jwt", LocalPath: src, Files: []string{"a.img", "b.img", "c.img", manifestFile}, }) if err != nil { @@ -143,7 +143,7 @@ func TestTransferRetriesOnceWithAReplacedCredential(t *testing.T) { } creds2 := &fakeCredentials{backend: creds.backend, stale: true} p2 := newCredsPlugin(t, creds2, root) - if _, err := p2.FetchSnapshot(t.Context(), &objectstorev1.FetchSnapshotRequest{ + if _, err := p2.FetchSnapshot(t.Context(), &objectstore.FetchSnapshotRequest{ SnapshotUri: testURI, ActorJwt: "jwt", WritePath: dst, Files: []string{"a.img", manifestFile}, }); err != nil { t.Fatalf("FetchSnapshot with a stale credential: %v", err) @@ -158,7 +158,7 @@ func TestTransferRetriesTheManifestFromItsStart(t *testing.T) { writeFiles(t, root, manifestFile) creds := &fakeCredentials{backend: newMemObjects(), stale: true} p := newCredsPlugin(t, creds, root) - if _, err := p.UploadSnapshot(t.Context(), &objectstorev1.UploadSnapshotRequest{ + if _, err := p.UploadSnapshot(t.Context(), &objectstore.UploadSnapshotRequest{ SnapshotUri: testURI, ActorJwt: "jwt", LocalPath: root, Files: []string{manifestFile}, }); err != nil { t.Fatalf("UploadSnapshot of the manifest with a stale credential: %v", err) @@ -186,7 +186,7 @@ func TestTransferReportsAnActorItCannotTransferFor(t *testing.T) { for _, code := range []codes.Code{codes.NotFound, codes.Aborted} { creds := &fakeCredentials{backend: newMemObjects(), err: status.Error(code, "actor not found")} p := newCredsPlugin(t, creds, root) - _, err := p.FetchSnapshot(t.Context(), &objectstorev1.FetchSnapshotRequest{ + _, err := p.FetchSnapshot(t.Context(), &objectstore.FetchSnapshotRequest{ SnapshotUri: testURI, ActorJwt: "jwt", WritePath: root, Files: []string{manifestFile}, }) if status.Code(err) != codes.FailedPrecondition { @@ -209,7 +209,7 @@ func TestTransferFailsClosedOnASecondRefusal(t *testing.T) { } return client, err }) - _, err := p.FetchSnapshot(t.Context(), &objectstorev1.FetchSnapshotRequest{ + _, err := p.FetchSnapshot(t.Context(), &objectstore.FetchSnapshotRequest{ SnapshotUri: testURI, ActorJwt: "jwt", WritePath: root, Files: []string{manifestFile}, }) if status.Code(err) != codes.PermissionDenied { @@ -230,7 +230,7 @@ func TestTransferReturnsTheCredentialSourcesStatus(t *testing.T) { root := t.TempDir() creds := &fakeCredentials{backend: newMemObjects(), err: status.Error(codes.PermissionDenied, "actor is no longer on the token's node")} p := newCredsPlugin(t, creds, root) - _, err := p.FetchSnapshot(t.Context(), &objectstorev1.FetchSnapshotRequest{ + _, err := p.FetchSnapshot(t.Context(), &objectstore.FetchSnapshotRequest{ SnapshotUri: testURI, ActorJwt: "jwt", WritePath: root, Files: []string{manifestFile}, }) if status.Code(err) != codes.PermissionDenied || !strings.Contains(status.Convert(err).Message(), "actor is no longer on the token's node") { @@ -247,7 +247,7 @@ func TestAmbientCredentialsIgnoreTheJWT(t *testing.T) { } writeFiles(t, root, manifestFile) for _, jwt := range []string{"", "anything"} { - if _, err := p.UploadSnapshot(t.Context(), &objectstorev1.UploadSnapshotRequest{ + if _, err := p.UploadSnapshot(t.Context(), &objectstore.UploadSnapshotRequest{ SnapshotUri: testURI, ActorJwt: jwt, LocalPath: root, Files: []string{manifestFile}, }); err != nil { t.Fatalf("UploadSnapshot(actor_jwt=%q) with ambient credentials: %v", jwt, err) diff --git a/internal/objectstoreplugin/exchange/exchange.go b/internal/objectstoreplugin/exchange/exchange.go index dc6b1c60f0..8bb4b5a2ce 100644 --- a/internal/objectstoreplugin/exchange/exchange.go +++ b/internal/objectstoreplugin/exchange/exchange.go @@ -32,6 +32,7 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/actoridjwt" "go.ate.dev/substrate/internal/objectstoreplugin/actorlookup" "go.ate.dev/substrate/internal/objectstoreplugin/actorscope" @@ -39,7 +40,6 @@ import ( "go.ate.dev/substrate/internal/oidcjwt" exchangepb "go.ate.dev/substrate/internal/proto/objectstoreexchangepb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // DefaultPort is the port the control sidecar serves the exchange on and the @@ -64,7 +64,7 @@ type Issuer interface { // Lookup resolves the actor a verified JWT names. actorlookup implements it. type Lookup interface { - Actor(ctx context.Context, claims *actoridjwt.WireSubstrateClaims) (*ateapipb.Actor, error) + Actor(ctx context.Context, claims *actoridjwt.WireSubstrateClaims) (*ateapi.Actor, error) } // Verifier checks a JWT and returns its claims. oidcjwt.Verifier implements @@ -161,7 +161,7 @@ func issueCode(err error) codes.Code { // detaches the actor, by a revert and by a delete, or replaced by a resume // onto another node. So a token from a node the actor moved away from, or // one kept past the actor's last transfer there, no longer matches. -func actorStillOnNode(actor *ateapipb.Actor, node string) error { +func actorStillOnNode(actor *ateapi.Actor, node string) error { st := actor.GetStatus() if !slices.Contains(resources.TransferStates, st.GetState()) { return status.Errorf(codes.PermissionDenied, "actor is %s, no transfer is due", st.GetState()) diff --git a/internal/objectstoreplugin/exchange/exchange_test.go b/internal/objectstoreplugin/exchange/exchange_test.go index 8bcdd954f0..e3ced082e8 100644 --- a/internal/objectstoreplugin/exchange/exchange_test.go +++ b/internal/objectstoreplugin/exchange/exchange_test.go @@ -32,6 +32,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/actoridjwt" "go.ate.dev/substrate/internal/localjwtauthority" "go.ate.dev/substrate/internal/objectstoreplugin/actorlookup" @@ -40,7 +41,6 @@ import ( "go.ate.dev/substrate/internal/oidcjwt" exchangepb "go.ate.dev/substrate/internal/proto/objectstoreexchangepb" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) const ( @@ -103,11 +103,11 @@ func (s *signer) jwt(t *testing.T, kind actoridjwt.Kind, audience string, actorU // fakeLookup answers for one actor and records the claims it was asked for. type fakeLookup struct { - actor *ateapipb.Actor + actor *ateapi.Actor err error } -func (f *fakeLookup) Actor(_ context.Context, claims *actoridjwt.WireSubstrateClaims) (*ateapipb.Actor, error) { +func (f *fakeLookup) Actor(_ context.Context, claims *actoridjwt.WireSubstrateClaims) (*ateapi.Actor, error) { if f.err != nil { return nil, f.err } @@ -173,30 +173,30 @@ func (s *signer) rawClaims() map[string]any { // actorWithTag is a running actor on node-1 that still carries the tag // generation it was created from. -func actorWithTag() *ateapipb.Actor { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: name, Uid: uid}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING, AssignedNode: "node-1", Snapshots: []*ateapipb.Snapshot{{ - Generation: 1, Owner: ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, - DurableSnapshot: &ateapipb.SnapshotStorage{ - Status: ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, - Object: &ateapipb.ObjectSnapshot{SnapshotUri: tagURI}, +func actorWithTag() *ateapi.Actor { + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: name, Uid: uid}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING, AssignedNode: "node-1", Snapshots: []*ateapi.Snapshot{{ + Generation: 1, Owner: ateapi.SnapshotOwner_SNAPSHOT_OWNER_TAG, + DurableSnapshot: &ateapi.SnapshotStorage{ + Status: ateapi.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED, + Object: &ateapi.ObjectSnapshot{SnapshotUri: tagURI}, }, }}}, } } // actorLocalOnly is a suspended actor whose only snapshot is on node-1. -func actorLocalOnly() *ateapipb.Actor { - return &ateapipb.Actor{ - Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: name, Uid: uid}, - Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED, AssignedNode: "node-1", - Snapshots: []*ateapipb.Snapshot{{Generation: 1, Owner: ateapipb.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, Locality: "node-1"}}}, +func actorLocalOnly() *ateapi.Actor { + return &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: atespace, Name: name, Uid: uid}, + Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED, AssignedNode: "node-1", + Snapshots: []*ateapi.Snapshot{{Generation: 1, Owner: ateapi.SnapshotOwner_SNAPSHOT_OWNER_ACTOR, Locality: "node-1"}}}, } } // actorIn returns actorWithTag in the given state on the given node. -func actorIn(state ateapipb.ActorState, node string) *ateapipb.Actor { +func actorIn(state ateapi.ActorState, node string) *ateapi.Actor { a := actorWithTag() a.Status.State, a.Status.AssignedNode = state, node return a @@ -208,18 +208,18 @@ func TestExchangeActorJwt_NodeBinding(t *testing.T) { s, v := newSigner(t) for _, tc := range []struct { name string - actor *ateapipb.Actor + actor *ateapi.Actor want codes.Code }{ - {"resuming on the token's node", actorIn(ateapipb.ActorState_ACTOR_STATE_RESUMING, "node-1"), codes.OK}, - {"running on the token's node", actorIn(ateapipb.ActorState_ACTOR_STATE_RUNNING, "node-1"), codes.OK}, - {"suspending on the token's node", actorIn(ateapipb.ActorState_ACTOR_STATE_SUSPENDING, "node-1"), codes.OK}, - {"suspended with its snapshot on the token's node", actorIn(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), codes.OK}, - {"resumed on another node", actorIn(ateapipb.ActorState_ACTOR_STATE_RUNNING, "node-2"), codes.PermissionDenied}, - {"detached from the node", actorIn(ateapipb.ActorState_ACTOR_STATE_SUSPENDED, ""), codes.PermissionDenied}, - {"crashed on the token's node", actorIn(ateapipb.ActorState_ACTOR_STATE_CRASHED, "node-1"), codes.PermissionDenied}, - {"deleting on the token's node", actorIn(ateapipb.ActorState_ACTOR_STATE_DELETING, "node-1"), codes.PermissionDenied}, - {"reverting on the token's node", actorIn(ateapipb.ActorState_ACTOR_STATE_REVERTING, "node-1"), codes.PermissionDenied}, + {"resuming on the token's node", actorIn(ateapi.ActorState_ACTOR_STATE_RESUMING, "node-1"), codes.OK}, + {"running on the token's node", actorIn(ateapi.ActorState_ACTOR_STATE_RUNNING, "node-1"), codes.OK}, + {"suspending on the token's node", actorIn(ateapi.ActorState_ACTOR_STATE_SUSPENDING, "node-1"), codes.OK}, + {"suspended with its snapshot on the token's node", actorIn(ateapi.ActorState_ACTOR_STATE_SUSPENDED, "node-1"), codes.OK}, + {"resumed on another node", actorIn(ateapi.ActorState_ACTOR_STATE_RUNNING, "node-2"), codes.PermissionDenied}, + {"detached from the node", actorIn(ateapi.ActorState_ACTOR_STATE_SUSPENDED, ""), codes.PermissionDenied}, + {"crashed on the token's node", actorIn(ateapi.ActorState_ACTOR_STATE_CRASHED, "node-1"), codes.PermissionDenied}, + {"deleting on the token's node", actorIn(ateapi.ActorState_ACTOR_STATE_DELETING, "node-1"), codes.PermissionDenied}, + {"reverting on the token's node", actorIn(ateapi.ActorState_ACTOR_STATE_REVERTING, "node-1"), codes.PermissionDenied}, } { t.Run(tc.name, func(t *testing.T) { issuer := &fakeIssuer{expiry: s.now.Add(time.Hour)} diff --git a/internal/objectstoreplugin/node.go b/internal/objectstoreplugin/node.go index 8533d83897..7ff40f45cc 100644 --- a/internal/objectstoreplugin/node.go +++ b/internal/objectstoreplugin/node.go @@ -30,9 +30,9 @@ import ( "path/filepath" "slices" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/pkg/objectstorage" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "golang.org/x/sync/errgroup" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -45,7 +45,7 @@ const manifestFile = "manifest.json" // NodePlugin serves NodeProvider on an object storage client. type NodePlugin struct { - objectstorev1.UnimplementedNodeProviderServer + objectstore.UnimplementedNodeProviderServer // creds supplies the client each transfer runs with. creds Credentials @@ -84,7 +84,7 @@ func WithCredentials(creds Credentials) NodeOption { } // FetchSnapshot downloads the requested snapshot files into write_path. -func (p *NodePlugin) FetchSnapshot(ctx context.Context, req *objectstorev1.FetchSnapshotRequest) (*objectstorev1.FetchSnapshotResponse, error) { +func (p *NodePlugin) FetchSnapshot(ctx context.Context, req *objectstore.FetchSnapshotRequest) (*objectstore.FetchSnapshotResponse, error) { uri, dstDir, err := p.validate(req.GetSnapshotUri(), req.GetWritePath(), req.GetFiles()) if err != nil { return nil, err @@ -132,12 +132,12 @@ func (p *NodePlugin) FetchSnapshot(ctx context.Context, req *objectstorev1.Fetch if err := g.Wait(); err != nil { return nil, toStatus(err) } - return &objectstorev1.FetchSnapshotResponse{}, nil + return &objectstore.FetchSnapshotResponse{}, nil } // UploadSnapshot uploads the requested files from local_path into the // snapshot. -func (p *NodePlugin) UploadSnapshot(ctx context.Context, req *objectstorev1.UploadSnapshotRequest) (*objectstorev1.UploadSnapshotResponse, error) { +func (p *NodePlugin) UploadSnapshot(ctx context.Context, req *objectstore.UploadSnapshotRequest) (*objectstore.UploadSnapshotResponse, error) { uri, srcDir, err := p.validate(req.GetSnapshotUri(), req.GetLocalPath(), req.GetFiles()) if err != nil { return nil, err @@ -196,7 +196,7 @@ func (p *NodePlugin) UploadSnapshot(ctx context.Context, req *objectstorev1.Uplo return nil, toStatus(err) } } - return &objectstorev1.UploadSnapshotResponse{}, nil + return &objectstore.UploadSnapshotResponse{}, nil } // fetchManifest downloads the uncompressed manifest into root. diff --git a/internal/objectstoreplugin/objectstoreplugintest/objectstoreplugintest.go b/internal/objectstoreplugin/objectstoreplugintest/objectstoreplugintest.go index fa7a019d64..0edcad34ab 100644 --- a/internal/objectstoreplugin/objectstoreplugintest/objectstoreplugintest.go +++ b/internal/objectstoreplugin/objectstoreplugintest/objectstoreplugintest.go @@ -20,9 +20,9 @@ package objectstoreplugintest import ( "context" + objectstorev1 "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/internal/objectstore" "go.ate.dev/substrate/internal/objectstoreplugin" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "google.golang.org/grpc" ) diff --git a/internal/objectstoreplugin/plugin_test.go b/internal/objectstoreplugin/plugin_test.go index 855701e74b..27c21f5405 100644 --- a/internal/objectstoreplugin/plugin_test.go +++ b/internal/objectstoreplugin/plugin_test.go @@ -27,9 +27,9 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/internal/pluginsocket" "go.ate.dev/substrate/pkg/objectstorage" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/health" @@ -129,8 +129,8 @@ func serve(t *testing.T, backend *memObjects, root string) *grpc.ClientConn { t.Fatal(err) } srv := grpc.NewServer() - objectstorev1.RegisterNodeProviderServer(srv, node) - objectstorev1.RegisterControlProviderServer(srv, NewControlPlugin(backend)) + objectstore.RegisterNodeProviderServer(srv, node) + objectstore.RegisterControlProviderServer(srv, NewControlPlugin(backend)) healthpb.RegisterHealthServer(srv, health.NewServer()) go srv.Serve(lis) t.Cleanup(srv.Stop) @@ -155,7 +155,7 @@ func TestUploadFetchRoundTrip(t *testing.T) { ctx := context.Background() backend := newMemObjects() root := t.TempDir() - client := objectstorev1.NewNodeProviderClient(serve(t, backend, root)) + client := objectstore.NewNodeProviderClient(serve(t, backend, root)) src := filepath.Join(root, "src") dst := filepath.Join(root, "dst") @@ -179,12 +179,12 @@ func TestUploadFetchRoundTrip(t *testing.T) { } } - if _, err := client.UploadSnapshot(ctx, &objectstorev1.UploadSnapshotRequest{ + if _, err := client.UploadSnapshot(ctx, &objectstore.UploadSnapshotRequest{ SnapshotUri: testURI, LocalPath: src, Files: []string{"memory.img", "state.bin", "fs/fscheckpoint.pb"}, }); err != nil { t.Fatalf("UploadSnapshot(data) = %v", err) } - if _, err := client.UploadSnapshot(ctx, &objectstorev1.UploadSnapshotRequest{ + if _, err := client.UploadSnapshot(ctx, &objectstore.UploadSnapshotRequest{ SnapshotUri: testURI, LocalPath: src, Files: []string{manifestFile}, }); err != nil { t.Fatalf("UploadSnapshot(manifest) = %v", err) @@ -204,7 +204,7 @@ func TestUploadFetchRoundTrip(t *testing.T) { t.Errorf("stored manifest = %q, want it uncompressed", got) } - if _, err := client.FetchSnapshot(ctx, &objectstorev1.FetchSnapshotRequest{ + if _, err := client.FetchSnapshot(ctx, &objectstore.FetchSnapshotRequest{ SnapshotUri: testURI, WritePath: dst, Files: []string{manifestFile, "memory.img", "state.bin", "fs/fscheckpoint.pb"}, }); err != nil { t.Fatalf("FetchSnapshot = %v", err) @@ -222,9 +222,9 @@ func TestUploadFetchRoundTrip(t *testing.T) { func TestFetchMissingIsNotFound(t *testing.T) { root := t.TempDir() - client := objectstorev1.NewNodeProviderClient(serve(t, newMemObjects(), root)) + client := objectstore.NewNodeProviderClient(serve(t, newMemObjects(), root)) for _, file := range []string{manifestFile, "memory.img"} { - _, err := client.FetchSnapshot(context.Background(), &objectstorev1.FetchSnapshotRequest{ + _, err := client.FetchSnapshot(context.Background(), &objectstore.FetchSnapshotRequest{ SnapshotUri: testURI, WritePath: root, Files: []string{file}, }) if status.Code(err) != codes.NotFound { @@ -235,7 +235,7 @@ func TestFetchMissingIsNotFound(t *testing.T) { func TestNodeRequestValidation(t *testing.T) { root := t.TempDir() - client := objectstorev1.NewNodeProviderClient(serve(t, newMemObjects(), root)) + client := objectstore.NewNodeProviderClient(serve(t, newMemObjects(), root)) for _, tc := range []struct { name string uri string @@ -254,10 +254,10 @@ func TestNodeRequestValidation(t *testing.T) { {"duplicate file", testURI, root, []string{"a", "b", "a"}}, } { t.Run(tc.name, func(t *testing.T) { - _, fetchErr := client.FetchSnapshot(context.Background(), &objectstorev1.FetchSnapshotRequest{ + _, fetchErr := client.FetchSnapshot(context.Background(), &objectstore.FetchSnapshotRequest{ SnapshotUri: tc.uri, WritePath: tc.dir, Files: tc.files, }) - _, uploadErr := client.UploadSnapshot(context.Background(), &objectstorev1.UploadSnapshotRequest{ + _, uploadErr := client.UploadSnapshot(context.Background(), &objectstore.UploadSnapshotRequest{ SnapshotUri: tc.uri, LocalPath: tc.dir, Files: tc.files, }) for _, err := range []error{fetchErr, uploadErr} { @@ -274,7 +274,7 @@ func TestUploadRejectsSymlinkOutsideDir(t *testing.T) { t.Run(file, func(t *testing.T) { parent := t.TempDir() backend := newMemObjects() - client := objectstorev1.NewNodeProviderClient(serve(t, backend, parent)) + client := objectstore.NewNodeProviderClient(serve(t, backend, parent)) checkpointDir := filepath.Join(parent, "checkpoint-state") if err := os.Mkdir(checkpointDir, 0o700); err != nil { t.Fatal(err) @@ -287,7 +287,7 @@ func TestUploadRejectsSymlinkOutsideDir(t *testing.T) { t.Fatal(err) } - _, err := client.UploadSnapshot(context.Background(), &objectstorev1.UploadSnapshotRequest{ + _, err := client.UploadSnapshot(context.Background(), &objectstore.UploadSnapshotRequest{ SnapshotUri: testURI, LocalPath: checkpointDir, Files: []string{file}, }) if err == nil { @@ -306,7 +306,7 @@ func TestFetchRejectsSymlinkOutsideDir(t *testing.T) { ctx := context.Background() parent := t.TempDir() backend := newMemObjects() - client := objectstorev1.NewNodeProviderClient(serve(t, backend, parent)) + client := objectstore.NewNodeProviderClient(serve(t, backend, parent)) src := filepath.Join(parent, "src") restoreDir := filepath.Join(parent, "restore-state") for _, d := range []string{src, restoreDir} { @@ -317,7 +317,7 @@ func TestFetchRejectsSymlinkOutsideDir(t *testing.T) { if err := os.WriteFile(filepath.Join(src, file), []byte("replacement"), 0o600); err != nil { t.Fatal(err) } - if _, err := client.UploadSnapshot(ctx, &objectstorev1.UploadSnapshotRequest{ + if _, err := client.UploadSnapshot(ctx, &objectstore.UploadSnapshotRequest{ SnapshotUri: testURI, LocalPath: src, Files: []string{file}, }); err != nil { t.Fatal(err) @@ -330,7 +330,7 @@ func TestFetchRejectsSymlinkOutsideDir(t *testing.T) { t.Fatal(err) } - _, err := client.FetchSnapshot(ctx, &objectstorev1.FetchSnapshotRequest{ + _, err := client.FetchSnapshot(ctx, &objectstore.FetchSnapshotRequest{ SnapshotUri: testURI, WritePath: restoreDir, Files: []string{file}, }) if err == nil { @@ -363,9 +363,9 @@ func TestRejectsDirSymlinkOutsideRoot(t *testing.T) { t.Fatal(err) } backend := newMemObjects() - client := objectstorev1.NewNodeProviderClient(serve(t, backend, root)) + client := objectstore.NewNodeProviderClient(serve(t, backend, root)) - if _, err := client.UploadSnapshot(ctx, &objectstorev1.UploadSnapshotRequest{ + if _, err := client.UploadSnapshot(ctx, &objectstore.UploadSnapshotRequest{ SnapshotUri: testURI, LocalPath: link, Files: []string{"checkpoint.img"}, }); err == nil { t.Error("UploadSnapshot read through a directory symlink outside --root") @@ -375,7 +375,7 @@ func TestRejectsDirSymlinkOutsideRoot(t *testing.T) { } backend.m[testBucket+"/"+testPrefix+"/"+manifestFile] = []byte("m") - if _, err := client.FetchSnapshot(ctx, &objectstorev1.FetchSnapshotRequest{ + if _, err := client.FetchSnapshot(ctx, &objectstore.FetchSnapshotRequest{ SnapshotUri: testURI, WritePath: link, Files: []string{manifestFile}, }); err == nil { t.Error("FetchSnapshot succeeded through a directory symlink outside --root") @@ -388,7 +388,7 @@ func TestRejectsDirSymlinkOutsideRoot(t *testing.T) { func TestCleanupSnapshot(t *testing.T) { ctx := context.Background() backend := newMemObjects() - client := objectstorev1.NewControlProviderClient(serve(t, backend, t.TempDir())) + client := objectstore.NewControlProviderClient(serve(t, backend, t.TempDir())) // uid10 shares a string prefix with uid1, so it survives only if cleanup // stops at a path-segment boundary. keep := testBucket + "/root/atespaces/team-a/actors/uid10/snapshots/snap1/manifest.json" @@ -398,19 +398,19 @@ func TestCleanupSnapshot(t *testing.T) { // An owner prefix collects every snapshot below it, and nothing beside it. owner := "gs://" + testBucket + "/root/atespaces/team-a/actors/uid1" - if _, err := client.CleanupSnapshot(ctx, &objectstorev1.CleanupSnapshotRequest{SnapshotUri: owner}); err != nil { + if _, err := client.CleanupSnapshot(ctx, &objectstore.CleanupSnapshotRequest{SnapshotUri: owner}); err != nil { t.Fatalf("CleanupSnapshot = %v", err) } if got := backend.keys(); !equal(got, []string{keep}) { t.Errorf("objects left = %v, want only %s", got, keep) } // Cleaning up again is a no-op. - if _, err := client.CleanupSnapshot(ctx, &objectstorev1.CleanupSnapshotRequest{SnapshotUri: owner}); err != nil { + if _, err := client.CleanupSnapshot(ctx, &objectstore.CleanupSnapshotRequest{SnapshotUri: owner}); err != nil { t.Errorf("repeated CleanupSnapshot = %v", err) } // A bare bucket is never a valid prefix. for _, uri := range []string{"gs://" + testBucket, "gs://" + testBucket + "/", "not a uri?x=1"} { - _, err := client.CleanupSnapshot(ctx, &objectstorev1.CleanupSnapshotRequest{SnapshotUri: uri}) + _, err := client.CleanupSnapshot(ctx, &objectstore.CleanupSnapshotRequest{SnapshotUri: uri}) if status.Code(err) != codes.InvalidArgument { t.Errorf("CleanupSnapshot(%q) = %v, want InvalidArgument", uri, err) } @@ -420,11 +420,11 @@ func TestCleanupSnapshot(t *testing.T) { func TestCopySnapshot(t *testing.T) { ctx := context.Background() backend := newMemObjects() - client := objectstorev1.NewControlProviderClient(serve(t, backend, t.TempDir())) + client := objectstore.NewControlProviderClient(serve(t, backend, t.TempDir())) backend.m[testBucket+"/"+testPrefix+"/manifest.json"] = []byte("m") tag := "gs://" + testBucket + "/root/atespaces/team-a/tags/tag1" - if _, err := client.CopySnapshot(ctx, &objectstorev1.CopySnapshotRequest{SrcUri: testURI, DstUri: tag}); err != nil { + if _, err := client.CopySnapshot(ctx, &objectstore.CopySnapshotRequest{SrcUri: testURI, DstUri: tag}); err != nil { t.Fatalf("CopySnapshot = %v", err) } if got := backend.m[testBucket+"/root/atespaces/team-a/tags/tag1/manifest.json"]; string(got) != "m" { @@ -432,7 +432,7 @@ func TestCopySnapshot(t *testing.T) { } empty := "gs://" + testBucket + "/root/atespaces/team-a/actors/uid9/snapshots/none" - _, err := client.CopySnapshot(ctx, &objectstorev1.CopySnapshotRequest{SrcUri: empty, DstUri: tag}) + _, err := client.CopySnapshot(ctx, &objectstore.CopySnapshotRequest{SrcUri: empty, DstUri: tag}) if status.Code(err) != codes.FailedPrecondition { t.Errorf("CopySnapshot(empty source) = %v, want FailedPrecondition", err) } diff --git a/internal/objectstoreplugin/upload_test.go b/internal/objectstoreplugin/upload_test.go index 2fb8f19151..98dfafe29e 100644 --- a/internal/objectstoreplugin/upload_test.go +++ b/internal/objectstoreplugin/upload_test.go @@ -26,7 +26,7 @@ import ( "testing" "testing/synctest" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" + "go.ate.dev/substrate/api/objectstore/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -80,10 +80,10 @@ func snapshotUploadFiles(t *testing.T, dir string, n int) []string { func TestUploadBudgetSharedAcrossSnapshots(t *testing.T) { root := t.TempDir() const snapshots, filesPerSnapshot = 10, 8 - requests := make([]*objectstorev1.UploadSnapshotRequest, snapshots) + requests := make([]*objectstore.UploadSnapshotRequest, snapshots) for i := range snapshots { dir := filepath.Join(root, fmt.Sprintf("src%d", i)) - requests[i] = &objectstorev1.UploadSnapshotRequest{ + requests[i] = &objectstore.UploadSnapshotRequest{ SnapshotUri: fmt.Sprintf("%s%d", testURI, i), LocalPath: dir, Files: snapshotUploadFiles(t, dir, filesPerSnapshot), } @@ -127,7 +127,7 @@ func TestUploadBudgetSharedAcrossSnapshots(t *testing.T) { if err := os.Mkdir(dst, 0o700); err != nil { t.Fatal(err) } - if _, err := node.FetchSnapshot(t.Context(), &objectstorev1.FetchSnapshotRequest{ + if _, err := node.FetchSnapshot(t.Context(), &objectstore.FetchSnapshotRequest{ SnapshotUri: requests[0].SnapshotUri, WritePath: dst, Files: requests[0].Files, }); err != nil { t.Fatal(err) @@ -152,7 +152,7 @@ func TestUploadFailureDoesNotCommitManifest(t *testing.T) { if err != nil { t.Fatal(err) } - if _, err := node.UploadSnapshot(t.Context(), &objectstorev1.UploadSnapshotRequest{ + if _, err := node.UploadSnapshot(t.Context(), &objectstore.UploadSnapshotRequest{ SnapshotUri: testURI, LocalPath: dir, Files: files, }); status.Code(err) != codes.Internal { t.Fatalf("got %v, want upload error", err) @@ -161,7 +161,7 @@ func TestUploadFailureDoesNotCommitManifest(t *testing.T) { t.Fatalf("committed %d manifests after data failed", got) } store.fail = false - if _, err := node.UploadSnapshot(t.Context(), &objectstorev1.UploadSnapshotRequest{ + if _, err := node.UploadSnapshot(t.Context(), &objectstore.UploadSnapshotRequest{ SnapshotUri: testURI, LocalPath: dir, Files: files, }); err != nil { t.Fatalf("retry after failure: %v", err) @@ -179,7 +179,7 @@ func TestUploadCanceledWaiterReturnsCanceled(t *testing.T) { if err != nil { t.Fatal(err) } - req := &objectstorev1.UploadSnapshotRequest{SnapshotUri: testURI, LocalPath: dir, Files: files} + req := &objectstore.UploadSnapshotRequest{SnapshotUri: testURI, LocalPath: dir, Files: files} first := make(chan error, 1) go func() { _, err := node.UploadSnapshot(t.Context(), req); first <- err }() synctest.Wait() diff --git a/internal/plugins/README.md b/internal/plugins/README.md index 8a29e73b51..22bc10ebc1 100644 --- a/internal/plugins/README.md +++ b/internal/plugins/README.md @@ -13,7 +13,7 @@ own, and its path here goes away when it does. Until then: - **Do not import these packages.** Code outside a plugin must not import it. Go already refuses most such imports, since a plugin's packages sit under its own `internal/` or are `main` packages. -- **A plugin imports only substrate's public `pkg/` packages**, so it can move - out as it is. Its `go.mod` replaces the substrate module with this checkout, - so it builds against the current tree. +- **A plugin imports only substrate's public `api/` and `pkg/` packages**, so + it can move out as it is. Its `go.mod` replaces the substrate module with this + checkout, so it builds against the current tree. diff --git a/internal/plugins/gcp-secret-manager/README.md b/internal/plugins/gcp-secret-manager/README.md index a9b4016791..f58695f378 100644 --- a/internal/plugins/gcp-secret-manager/README.md +++ b/internal/plugins/gcp-secret-manager/README.md @@ -6,7 +6,7 @@ A [substrate](https://github.com/agent-substrate/substrate) credential provider backed by Google Cloud Secret Manager. It implements substrate's -`CredentialProvider` gRPC API (`pkg/proto/credproviderpb`) for egress +`CredentialProvider` gRPC API (`api/credprovider/v1`) for egress credential injection: given an `ate-secret://secretmanager.googleapis.com/...` URI, it reads the secret version from Secret Manager and returns its payload, so the secret stays in Secret Manager and substrate never stores it. @@ -22,7 +22,7 @@ namespace: |---|---| | Provider name | `secretmanager.googleapis.com`, the host of its `ate-secret://` credential URIs | | Address | `gsm-credential-provider.ate-system.svc:50051` | -| API | `credprovider.CredentialProvider/FetchSecret` over mutual TLS | +| API | `substrate.credprovider.v1.CredentialProvider/FetchSecret` over mutual TLS | The provider's serving certificate names the Service's DNS name, so callers must use exactly this address. @@ -267,14 +267,14 @@ make release-manifest # manifests with the image pinned by digest ``` `go.mod` replaces the substrate module with the enclosing checkout, so the -provider builds and tests against the current `credproviderpb` API. - -The module imports nothing of substrate's but its public `pkg/` packages, so -it can be copied out as it is; `TestImportsOnlySubstratePublicPackages` fails -on any other substrate import. For that reason, two packages are copies kept in -step by hand: `internal/credbundle` of substrate's `internal/credbundle`, and -`internal/mtls` of the server credentials in -`cmd/credential-provider/kubernetes-secrets`. +provider builds and tests against the current `credprovider` API. + +The module imports nothing of substrate's but its public `api/` and `pkg/` +packages, so it can be copied out as it is; +`TestImportsOnlySubstratePublicPackages` fails on any other substrate import. +For that reason, two packages are copies kept in step by hand: +`internal/credbundle` of substrate's `internal/credbundle`, and `internal/mtls` +of the server credentials in `cmd/credential-provider/kubernetes-secrets`. To move the module to its own repository, rename the module path in `go.mod`, in the Go imports, and in the `ko://` image of `config/deployment.yaml`, then diff --git a/internal/plugins/gcp-secret-manager/cmd/gsm-credential-provider/imports_test.go b/internal/plugins/gcp-secret-manager/cmd/gsm-credential-provider/imports_test.go index 60b57818b7..6703be0ce1 100644 --- a/internal/plugins/gcp-secret-manager/cmd/gsm-credential-provider/imports_test.go +++ b/internal/plugins/gcp-secret-manager/cmd/gsm-credential-provider/imports_test.go @@ -63,9 +63,9 @@ func TestImportsOnlySubstratePublicPackages(t *testing.T) { } switch { case imp == self || strings.HasPrefix(imp, self+"/"): - case strings.HasPrefix(imp, substrateModule+"/pkg/"): + case strings.HasPrefix(imp, substrateModule+"/api/"), strings.HasPrefix(imp, substrateModule+"/pkg/"): case imp == substrateModule || strings.HasPrefix(imp, substrateModule+"/"): - t.Errorf("%s imports %s; this module may import only %s/pkg/...", path, imp, substrateModule) + t.Errorf("%s imports %s; this module may import only %s/api/... and %s/pkg/...", path, imp, substrateModule, substrateModule) } } return nil diff --git a/internal/plugins/gcp-secret-manager/cmd/gsm-credential-provider/main.go b/internal/plugins/gcp-secret-manager/cmd/gsm-credential-provider/main.go index 77304c459a..94d46f8227 100644 --- a/internal/plugins/gcp-secret-manager/cmd/gsm-credential-provider/main.go +++ b/internal/plugins/gcp-secret-manager/cmd/gsm-credential-provider/main.go @@ -37,7 +37,7 @@ import ( "google.golang.org/api/option" "google.golang.org/grpc" - "go.ate.dev/substrate/pkg/proto/credproviderpb" + "go.ate.dev/substrate/api/credprovider/v1" "go.ate.dev/substrate/internal/plugins/gcp-secret-manager/internal/mtls" "go.ate.dev/substrate/internal/plugins/gcp-secret-manager/internal/provider" @@ -129,7 +129,7 @@ func run(ctx context.Context) error { defer clients.Close() srv := grpc.NewServer(grpc.Creds(creds)) - credproviderpb.RegisterCredentialProviderServer(srv, provider.NewServer(clients.For, authz, *fetchTimeout)) + credprovider.RegisterCredentialProviderServer(srv, provider.NewServer(clients.For, authz, *fetchTimeout)) grpcLis, err := (&net.ListenConfig{}).Listen(ctx, "tcp", *listenAddr) if err != nil { diff --git a/internal/plugins/gcp-secret-manager/cmd/gsm-credential-provider/main_test.go b/internal/plugins/gcp-secret-manager/cmd/gsm-credential-provider/main_test.go index 70102a1aa7..206d0f9c3c 100644 --- a/internal/plugins/gcp-secret-manager/cmd/gsm-credential-provider/main_test.go +++ b/internal/plugins/gcp-secret-manager/cmd/gsm-credential-provider/main_test.go @@ -32,7 +32,7 @@ import ( "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/test/bufconn" - "go.ate.dev/substrate/pkg/proto/credproviderpb" + "go.ate.dev/substrate/api/credprovider/v1" ) // /healthz passes regardless of readiness; /readyz follows the ready flag. @@ -135,16 +135,16 @@ func TestBuildVersionPrefersExplicitVersion(t *testing.T) { // blockingProvider blocks FetchSecret until release is closed or the call is // canceled, closing entered once the call starts. type blockingProvider struct { - credproviderpb.UnimplementedCredentialProviderServer + credprovider.UnimplementedCredentialProviderServer entered chan struct{} release chan struct{} } -func (p *blockingProvider) FetchSecret(ctx context.Context, _ *credproviderpb.FetchSecretRequest) (*credproviderpb.FetchSecretResponse, error) { +func (p *blockingProvider) FetchSecret(ctx context.Context, _ *credprovider.FetchSecretRequest) (*credprovider.FetchSecretResponse, error) { close(p.entered) select { case <-p.release: - return &credproviderpb.FetchSecretResponse{}, nil + return &credprovider.FetchSecretResponse{}, nil case <-ctx.Done(): return nil, ctx.Err() } @@ -156,7 +156,7 @@ func startBlockingServer(t *testing.T, p *blockingProvider) (*grpc.Server, <-cha t.Helper() lis := bufconn.Listen(1 << 20) srv := grpc.NewServer() - credproviderpb.RegisterCredentialProviderServer(srv, p) + credprovider.RegisterCredentialProviderServer(srv, p) go func() { _ = srv.Serve(lis) }() t.Cleanup(srv.Stop) @@ -170,7 +170,7 @@ func startBlockingServer(t *testing.T, p *blockingProvider) (*grpc.Server, <-cha result := make(chan error, 1) go func() { - _, err := credproviderpb.NewCredentialProviderClient(conn).FetchSecret(context.Background(), &credproviderpb.FetchSecretRequest{}) + _, err := credprovider.NewCredentialProviderClient(conn).FetchSecret(context.Background(), &credprovider.FetchSecretRequest{}) result <- err }() select { diff --git a/internal/plugins/gcp-secret-manager/internal/provider/provider.go b/internal/plugins/gcp-secret-manager/internal/provider/provider.go index 61fd97ac70..ef9e7d830b 100644 --- a/internal/plugins/gcp-secret-manager/internal/provider/provider.go +++ b/internal/plugins/gcp-secret-manager/internal/provider/provider.go @@ -34,7 +34,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "go.ate.dev/substrate/pkg/proto/credproviderpb" + "go.ate.dev/substrate/api/credprovider/v1" ) // providerName is the ate-secret:// URI host this backend serves. @@ -194,12 +194,12 @@ type SecretAccessor interface { // or a region. type Accessors func(location string) (SecretAccessor, error) -// Server implements credproviderpb.CredentialProviderServer over Secret +// Server implements credprovider.CredentialProviderServer over Secret // Manager. mTLS admits only the egress gateway, which names each request's // actor; a secret resolves only in a project the policy grants that actor's // atespace. type Server struct { - credproviderpb.UnimplementedCredentialProviderServer + credprovider.UnimplementedCredentialProviderServer clients Accessors authz *ProjectAuthorizer @@ -215,7 +215,7 @@ func NewServer(clients Accessors, authz *ProjectAuthorizer, fetchTimeout time.Du // FetchSecret resolves an ate-secret:// URI to its secret version's payload, or // to the string value of the URI's key in it, returned verbatim. -func (s *Server) FetchSecret(ctx context.Context, req *credproviderpb.FetchSecretRequest) (*credproviderpb.FetchSecretResponse, error) { +func (s *Server) FetchSecret(ctx context.Context, req *credprovider.FetchSecretRequest) (*credprovider.FetchSecretResponse, error) { ref, err := parseURI(req.GetUri()) if err != nil { return nil, status.Error(codes.InvalidArgument, err.Error()) @@ -258,13 +258,13 @@ func (s *Server) FetchSecret(ctx context.Context, req *credproviderpb.FetchSecre } } if ref.Key == "" { - return &credproviderpb.FetchSecretResponse{OpaqueBytes: payload.GetData()}, nil + return &credprovider.FetchSecretResponse{OpaqueBytes: payload.GetData()}, nil } value, err := keyValue(ref, payload.GetData()) if err != nil { return nil, err } - return &credproviderpb.FetchSecretResponse{OpaqueBytes: value}, nil + return &credprovider.FetchSecretResponse{OpaqueBytes: value}, nil } // authorize denies unless the policy grants project to the atespace of the diff --git a/internal/plugins/gcp-secret-manager/internal/provider/provider_test.go b/internal/plugins/gcp-secret-manager/internal/provider/provider_test.go index 4488769214..95bc1be8dd 100644 --- a/internal/plugins/gcp-secret-manager/internal/provider/provider_test.go +++ b/internal/plugins/gcp-secret-manager/internal/provider/provider_test.go @@ -28,7 +28,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "go.ate.dev/substrate/pkg/proto/credproviderpb" + "go.ate.dev/substrate/api/credprovider/v1" ) // fakeAccessor is a fake Secret Manager client serving payloads by resource @@ -431,7 +431,7 @@ func TestFetchSecret(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { srv := NewServer(only(tc.accessor), testAuthorizer(t), time.Second) - resp, err := srv.FetchSecret(context.Background(), &credproviderpb.FetchSecretRequest{Uri: tc.uri, ActorSpiffeId: testActor}) + resp, err := srv.FetchSecret(context.Background(), &credprovider.FetchSecretRequest{Uri: tc.uri, ActorSpiffeId: testActor}) if tc.wantCode != codes.OK { if status.Code(err) != tc.wantCode { t.Fatalf("FetchSecret(%q) code = %v, want %v (err=%v)", tc.uri, status.Code(err), tc.wantCode, err) @@ -452,7 +452,7 @@ func TestFetchSecret(t *testing.T) { func TestFetchSecretKeyErrorDoesNotQuotePayload(t *testing.T) { const name = "projects/proj-123/secrets/example-api/versions/1" accessor := &fakeAccessor{byName: map[string][]byte{name: []byte(`{"token": Xs3cr3t}`)}} - _, err := NewServer(only(accessor), testAuthorizer(t), time.Second).FetchSecret(context.Background(), &credproviderpb.FetchSecretRequest{ + _, err := NewServer(only(accessor), testAuthorizer(t), time.Second).FetchSecret(context.Background(), &credprovider.FetchSecretRequest{ Uri: "ate-secret://secretmanager.googleapis.com/" + name + "/keys/token", ActorSpiffeId: testActor, }) @@ -467,7 +467,7 @@ func TestFetchSecretKeyErrorDoesNotQuotePayload(t *testing.T) { // A URI that fails to parse is refused before Secret Manager is dialed. func TestFetchSecretDoesNotDialOnBadURI(t *testing.T) { accessor := &fakeAccessor{} - _, err := NewServer(only(accessor), testAuthorizer(t), time.Second).FetchSecret(context.Background(), &credproviderpb.FetchSecretRequest{ + _, err := NewServer(only(accessor), testAuthorizer(t), time.Second).FetchSecret(context.Background(), &credprovider.FetchSecretRequest{ Uri: "ate-secret://secretmanager.googleapis.com/nope", ActorSpiffeId: testActor, }) @@ -507,7 +507,7 @@ func TestFetchSecretAuthorization(t *testing.T) { } { t.Run(tc.name, func(t *testing.T) { accessor := &fakeAccessor{byName: map[string][]byte{name: []byte("s3cr3t")}} - resp, err := NewServer(only(accessor), tc.authz, time.Second).FetchSecret(context.Background(), &credproviderpb.FetchSecretRequest{Uri: uri, ActorSpiffeId: tc.actor}) + resp, err := NewServer(only(accessor), tc.authz, time.Second).FetchSecret(context.Background(), &credprovider.FetchSecretRequest{Uri: uri, ActorSpiffeId: tc.actor}) if status.Code(err) != tc.wantCode { t.Fatalf("code = %v, want %v (err=%v)", status.Code(err), tc.wantCode, err) } @@ -530,7 +530,7 @@ func TestFetchSecretTimesOut(t *testing.T) { const timeout = 50 * time.Millisecond accessor := &fakeAccessor{block: true} start := time.Now() - _, err := NewServer(only(accessor), testAuthorizer(t), timeout).FetchSecret(context.Background(), &credproviderpb.FetchSecretRequest{ + _, err := NewServer(only(accessor), testAuthorizer(t), timeout).FetchSecret(context.Background(), &credprovider.FetchSecretRequest{ Uri: "ate-secret://secretmanager.googleapis.com/projects/proj-123/secrets/example-api/versions/1", ActorSpiffeId: testActor, }) @@ -571,7 +571,7 @@ func TestFetchSecretRoutesByLocation(t *testing.T) { {name: "no client for the region", uri: "ate-secret://secretmanager.googleapis.com/projects/proj-123/locations/europe-west4/secrets/example-api/versions/1", wantCode: codes.Unavailable}, } { t.Run(tc.name, func(t *testing.T) { - resp, err := srv.FetchSecret(context.Background(), &credproviderpb.FetchSecretRequest{Uri: tc.uri, ActorSpiffeId: testActor}) + resp, err := srv.FetchSecret(context.Background(), &credprovider.FetchSecretRequest{Uri: tc.uri, ActorSpiffeId: testActor}) if status.Code(err) != tc.wantCode { t.Fatalf("code = %v, want %v (err=%v)", status.Code(err), tc.wantCode, err) } diff --git a/internal/pluginsocket/pluginsocket_test.go b/internal/pluginsocket/pluginsocket_test.go index 6b2d085045..9a51d37de7 100644 --- a/internal/pluginsocket/pluginsocket_test.go +++ b/internal/pluginsocket/pluginsocket_test.go @@ -22,7 +22,7 @@ import ( "testing" "time" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" + "go.ate.dev/substrate/api/objectstore/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/connectivity" @@ -34,7 +34,7 @@ import ( // slowControl is a ControlProvider whose CleanupSnapshot takes delay, and // closes started when a call arrives. type slowControl struct { - objectstorev1.UnimplementedControlProviderServer + objectstore.UnimplementedControlProviderServer delay time.Duration once sync.Once @@ -45,11 +45,11 @@ func newSlowControl(delay time.Duration) *slowControl { return &slowControl{delay: delay, started: make(chan struct{})} } -func (c *slowControl) CleanupSnapshot(ctx context.Context, _ *objectstorev1.CleanupSnapshotRequest) (*objectstorev1.CleanupSnapshotResponse, error) { +func (c *slowControl) CleanupSnapshot(ctx context.Context, _ *objectstore.CleanupSnapshotRequest) (*objectstore.CleanupSnapshotResponse, error) { c.once.Do(func() { close(c.started) }) select { case <-time.After(c.delay): - return &objectstorev1.CleanupSnapshotResponse{}, nil + return &objectstore.CleanupSnapshotResponse{}, nil case <-ctx.Done(): return nil, status.FromContextError(ctx.Err()).Err() } @@ -60,13 +60,13 @@ func (c *slowControl) CleanupSnapshot(ctx context.Context, _ *objectstorev1.Clea type sidecar struct { t *testing.T path string - control objectstorev1.ControlProviderServer + control objectstore.ControlProviderServer mu sync.Mutex srv *grpc.Server } -func newSidecar(t *testing.T, control objectstorev1.ControlProviderServer) *sidecar { +func newSidecar(t *testing.T, control objectstore.ControlProviderServer) *sidecar { t.Helper() // Unix socket paths are length-limited; t.TempDir can exceed that on macOS. dir, err := os.MkdirTemp("", "snapplug") @@ -87,7 +87,7 @@ func (s *sidecar) start() { return } srv := grpc.NewServer() - objectstorev1.RegisterControlProviderServer(srv, s.control) + objectstore.RegisterControlProviderServer(srv, s.control) healthpb.RegisterHealthServer(srv, health.NewServer()) go srv.Serve(lis) s.mu.Lock() @@ -109,7 +109,7 @@ func (s *sidecar) stop() { // dialReady connects to s with the given wait and passes the startup // readiness check. -func (s *sidecar) dialReady(wait time.Duration) (*grpc.ClientConn, objectstorev1.ControlProviderClient) { +func (s *sidecar) dialReady(wait time.Duration) (*grpc.ClientConn, objectstore.ControlProviderClient) { s.t.Helper() conn, err := Dial(s.path, wait) if err != nil { @@ -121,7 +121,7 @@ func (s *sidecar) dialReady(wait time.Duration) (*grpc.ClientConn, objectstorev1 if err := WaitReady(ctx, conn); err != nil { s.t.Fatalf("WaitReady = %v", err) } - return conn, objectstorev1.NewControlProviderClient(conn) + return conn, objectstore.NewControlProviderClient(conn) } // lose stops s and waits until conn has seen the plugin go, so the next call @@ -138,7 +138,7 @@ func (s *sidecar) lose(conn *grpc.ClientConn) { } } -var cleanupReq = &objectstorev1.CleanupSnapshotRequest{SnapshotUri: "gs://bucket/root/snap1"} +var cleanupReq = &objectstore.CleanupSnapshotRequest{SnapshotUri: "gs://bucket/root/snap1"} // A plugin lost after startup fails a call with Unavailable once the ready // wait runs out, not when the caller's deadline does. diff --git a/internal/proto/ateenv/v1alpha/guest.pb.go b/internal/proto/ateenv/v1alpha/guest.pb.go index eab5979d55..dbf3227963 100644 --- a/internal/proto/ateenv/v1alpha/guest.pb.go +++ b/internal/proto/ateenv/v1alpha/guest.pb.go @@ -26,7 +26,7 @@ // versions: // protoc-gen-go v1.36.11-devel // protoc v4.25.3 -// source: guest.proto +// source: internal/proto/ateenv/v1alpha/guest.proto package ateenvv1alpha @@ -83,11 +83,11 @@ func (x ProcessState) String() string { } func (ProcessState) Descriptor() protoreflect.EnumDescriptor { - return file_guest_proto_enumTypes[0].Descriptor() + return file_internal_proto_ateenv_v1alpha_guest_proto_enumTypes[0].Descriptor() } func (ProcessState) Type() protoreflect.EnumType { - return &file_guest_proto_enumTypes[0] + return &file_internal_proto_ateenv_v1alpha_guest_proto_enumTypes[0] } func (x ProcessState) Number() protoreflect.EnumNumber { @@ -96,7 +96,7 @@ func (x ProcessState) Number() protoreflect.EnumNumber { // Deprecated: Use ProcessState.Descriptor instead. func (ProcessState) EnumDescriptor() ([]byte, []int) { - return file_guest_proto_rawDescGZIP(), []int{0} + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP(), []int{0} } // POSIX signals that can be sent to a process. Values match the Linux signal @@ -215,11 +215,11 @@ func (x Signal) String() string { } func (Signal) Descriptor() protoreflect.EnumDescriptor { - return file_guest_proto_enumTypes[1].Descriptor() + return file_internal_proto_ateenv_v1alpha_guest_proto_enumTypes[1].Descriptor() } func (Signal) Type() protoreflect.EnumType { - return &file_guest_proto_enumTypes[1] + return &file_internal_proto_ateenv_v1alpha_guest_proto_enumTypes[1] } func (x Signal) Number() protoreflect.EnumNumber { @@ -228,7 +228,7 @@ func (x Signal) Number() protoreflect.EnumNumber { // Deprecated: Use Signal.Descriptor instead. func (Signal) EnumDescriptor() ([]byte, []int) { - return file_guest_proto_rawDescGZIP(), []int{1} + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP(), []int{1} } // The Process resource: identity, lifecycle state, and exit status. @@ -256,7 +256,7 @@ type Process struct { func (x *Process) Reset() { *x = Process{} - mi := &file_guest_proto_msgTypes[0] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -268,7 +268,7 @@ func (x *Process) String() string { func (*Process) ProtoMessage() {} func (x *Process) ProtoReflect() protoreflect.Message { - mi := &file_guest_proto_msgTypes[0] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -281,7 +281,7 @@ func (x *Process) ProtoReflect() protoreflect.Message { // Deprecated: Use Process.ProtoReflect.Descriptor instead. func (*Process) Descriptor() ([]byte, []int) { - return file_guest_proto_rawDescGZIP(), []int{0} + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP(), []int{0} } func (x *Process) GetProcessId() string { @@ -354,7 +354,7 @@ type StartProcessRequest struct { func (x *StartProcessRequest) Reset() { *x = StartProcessRequest{} - mi := &file_guest_proto_msgTypes[1] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -366,7 +366,7 @@ func (x *StartProcessRequest) String() string { func (*StartProcessRequest) ProtoMessage() {} func (x *StartProcessRequest) ProtoReflect() protoreflect.Message { - mi := &file_guest_proto_msgTypes[1] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -379,7 +379,7 @@ func (x *StartProcessRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StartProcessRequest.ProtoReflect.Descriptor instead. func (*StartProcessRequest) Descriptor() ([]byte, []int) { - return file_guest_proto_rawDescGZIP(), []int{1} + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP(), []int{1} } func (x *StartProcessRequest) GetCommand() []string { @@ -428,7 +428,7 @@ type GetProcessRequest struct { func (x *GetProcessRequest) Reset() { *x = GetProcessRequest{} - mi := &file_guest_proto_msgTypes[2] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -440,7 +440,7 @@ func (x *GetProcessRequest) String() string { func (*GetProcessRequest) ProtoMessage() {} func (x *GetProcessRequest) ProtoReflect() protoreflect.Message { - mi := &file_guest_proto_msgTypes[2] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -453,7 +453,7 @@ func (x *GetProcessRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProcessRequest.ProtoReflect.Descriptor instead. func (*GetProcessRequest) Descriptor() ([]byte, []int) { - return file_guest_proto_rawDescGZIP(), []int{2} + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP(), []int{2} } func (x *GetProcessRequest) GetProcessId() string { @@ -484,7 +484,7 @@ type StreamProcessOutputRequest struct { func (x *StreamProcessOutputRequest) Reset() { *x = StreamProcessOutputRequest{} - mi := &file_guest_proto_msgTypes[3] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -496,7 +496,7 @@ func (x *StreamProcessOutputRequest) String() string { func (*StreamProcessOutputRequest) ProtoMessage() {} func (x *StreamProcessOutputRequest) ProtoReflect() protoreflect.Message { - mi := &file_guest_proto_msgTypes[3] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -509,7 +509,7 @@ func (x *StreamProcessOutputRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StreamProcessOutputRequest.ProtoReflect.Descriptor instead. func (*StreamProcessOutputRequest) Descriptor() ([]byte, []int) { - return file_guest_proto_rawDescGZIP(), []int{3} + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP(), []int{3} } func (x *StreamProcessOutputRequest) GetProcessId() string { @@ -555,7 +555,7 @@ type ProcessOutput struct { func (x *ProcessOutput) Reset() { *x = ProcessOutput{} - mi := &file_guest_proto_msgTypes[4] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -567,7 +567,7 @@ func (x *ProcessOutput) String() string { func (*ProcessOutput) ProtoMessage() {} func (x *ProcessOutput) ProtoReflect() protoreflect.Message { - mi := &file_guest_proto_msgTypes[4] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -580,7 +580,7 @@ func (x *ProcessOutput) ProtoReflect() protoreflect.Message { // Deprecated: Use ProcessOutput.ProtoReflect.Descriptor instead. func (*ProcessOutput) Descriptor() ([]byte, []int) { - return file_guest_proto_rawDescGZIP(), []int{4} + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP(), []int{4} } func (x *ProcessOutput) GetOutput() isProcessOutput_Output { @@ -658,7 +658,7 @@ type WriteProcessInputRequest struct { func (x *WriteProcessInputRequest) Reset() { *x = WriteProcessInputRequest{} - mi := &file_guest_proto_msgTypes[5] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -670,7 +670,7 @@ func (x *WriteProcessInputRequest) String() string { func (*WriteProcessInputRequest) ProtoMessage() {} func (x *WriteProcessInputRequest) ProtoReflect() protoreflect.Message { - mi := &file_guest_proto_msgTypes[5] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -683,7 +683,7 @@ func (x *WriteProcessInputRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WriteProcessInputRequest.ProtoReflect.Descriptor instead. func (*WriteProcessInputRequest) Descriptor() ([]byte, []int) { - return file_guest_proto_rawDescGZIP(), []int{5} + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP(), []int{5} } func (x *WriteProcessInputRequest) GetProcessId() string { @@ -718,7 +718,7 @@ type WriteProcessInputResponse struct { func (x *WriteProcessInputResponse) Reset() { *x = WriteProcessInputResponse{} - mi := &file_guest_proto_msgTypes[6] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -730,7 +730,7 @@ func (x *WriteProcessInputResponse) String() string { func (*WriteProcessInputResponse) ProtoMessage() {} func (x *WriteProcessInputResponse) ProtoReflect() protoreflect.Message { - mi := &file_guest_proto_msgTypes[6] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -743,7 +743,7 @@ func (x *WriteProcessInputResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WriteProcessInputResponse.ProtoReflect.Descriptor instead. func (*WriteProcessInputResponse) Descriptor() ([]byte, []int) { - return file_guest_proto_rawDescGZIP(), []int{6} + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP(), []int{6} } func (x *WriteProcessInputResponse) GetBytesWritten() int64 { @@ -766,7 +766,7 @@ type SignalProcessRequest struct { func (x *SignalProcessRequest) Reset() { *x = SignalProcessRequest{} - mi := &file_guest_proto_msgTypes[7] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -778,7 +778,7 @@ func (x *SignalProcessRequest) String() string { func (*SignalProcessRequest) ProtoMessage() {} func (x *SignalProcessRequest) ProtoReflect() protoreflect.Message { - mi := &file_guest_proto_msgTypes[7] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -791,7 +791,7 @@ func (x *SignalProcessRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SignalProcessRequest.ProtoReflect.Descriptor instead. func (*SignalProcessRequest) Descriptor() ([]byte, []int) { - return file_guest_proto_rawDescGZIP(), []int{7} + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP(), []int{7} } func (x *SignalProcessRequest) GetProcessId() string { @@ -824,7 +824,7 @@ type ReadFileRequest struct { func (x *ReadFileRequest) Reset() { *x = ReadFileRequest{} - mi := &file_guest_proto_msgTypes[8] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -836,7 +836,7 @@ func (x *ReadFileRequest) String() string { func (*ReadFileRequest) ProtoMessage() {} func (x *ReadFileRequest) ProtoReflect() protoreflect.Message { - mi := &file_guest_proto_msgTypes[8] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -849,7 +849,7 @@ func (x *ReadFileRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReadFileRequest.ProtoReflect.Descriptor instead. func (*ReadFileRequest) Descriptor() ([]byte, []int) { - return file_guest_proto_rawDescGZIP(), []int{8} + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP(), []int{8} } func (x *ReadFileRequest) GetPath() string { @@ -877,7 +877,7 @@ type ReadFileResponse struct { func (x *ReadFileResponse) Reset() { *x = ReadFileResponse{} - mi := &file_guest_proto_msgTypes[9] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -889,7 +889,7 @@ func (x *ReadFileResponse) String() string { func (*ReadFileResponse) ProtoMessage() {} func (x *ReadFileResponse) ProtoReflect() protoreflect.Message { - mi := &file_guest_proto_msgTypes[9] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -902,7 +902,7 @@ func (x *ReadFileResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReadFileResponse.ProtoReflect.Descriptor instead. func (*ReadFileResponse) Descriptor() ([]byte, []int) { - return file_guest_proto_rawDescGZIP(), []int{9} + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP(), []int{9} } func (x *ReadFileResponse) GetChunk() []byte { @@ -936,7 +936,7 @@ type WriteFileRequest struct { func (x *WriteFileRequest) Reset() { *x = WriteFileRequest{} - mi := &file_guest_proto_msgTypes[10] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -948,7 +948,7 @@ func (x *WriteFileRequest) String() string { func (*WriteFileRequest) ProtoMessage() {} func (x *WriteFileRequest) ProtoReflect() protoreflect.Message { - mi := &file_guest_proto_msgTypes[10] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -961,7 +961,7 @@ func (x *WriteFileRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WriteFileRequest.ProtoReflect.Descriptor instead. func (*WriteFileRequest) Descriptor() ([]byte, []int) { - return file_guest_proto_rawDescGZIP(), []int{10} + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP(), []int{10} } func (x *WriteFileRequest) GetPath() string { @@ -1003,7 +1003,7 @@ type WriteFileResponse struct { func (x *WriteFileResponse) Reset() { *x = WriteFileResponse{} - mi := &file_guest_proto_msgTypes[11] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1015,7 +1015,7 @@ func (x *WriteFileResponse) String() string { func (*WriteFileResponse) ProtoMessage() {} func (x *WriteFileResponse) ProtoReflect() protoreflect.Message { - mi := &file_guest_proto_msgTypes[11] + mi := &file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1028,7 +1028,7 @@ func (x *WriteFileResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WriteFileResponse.ProtoReflect.Descriptor instead. func (*WriteFileResponse) Descriptor() ([]byte, []int) { - return file_guest_proto_rawDescGZIP(), []int{11} + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP(), []int{11} } func (x *WriteFileResponse) GetBytesWritten() int64 { @@ -1038,11 +1038,11 @@ func (x *WriteFileResponse) GetBytesWritten() int64 { return 0 } -var File_guest_proto protoreflect.FileDescriptor +var File_internal_proto_ateenv_v1alpha_guest_proto protoreflect.FileDescriptor -const file_guest_proto_rawDesc = "" + +const file_internal_proto_ateenv_v1alpha_guest_proto_rawDesc = "" + "\n" + - "\vguest.proto\x12\x0eateenv.v1alpha\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x9d\x02\n" + + ")internal/proto/ateenv/v1alpha/guest.proto\x12\x0eateenv.v1alpha\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x9d\x02\n" + "\aProcess\x12\x1d\n" + "\n" + "process_id\x18\x01 \x01(\tR\tprocessId\x12\x18\n" + @@ -1156,20 +1156,20 @@ const file_guest_proto_rawDesc = "" + "\tWriteFile\x12 .ateenv.v1alpha.WriteFileRequest\x1a!.ateenv.v1alpha.WriteFileResponse(\x01BBZ@go.ate.dev/substrate/internal/proto/ateenv/v1alpha;ateenvv1alphab\x06proto3" var ( - file_guest_proto_rawDescOnce sync.Once - file_guest_proto_rawDescData []byte + file_internal_proto_ateenv_v1alpha_guest_proto_rawDescOnce sync.Once + file_internal_proto_ateenv_v1alpha_guest_proto_rawDescData []byte ) -func file_guest_proto_rawDescGZIP() []byte { - file_guest_proto_rawDescOnce.Do(func() { - file_guest_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_guest_proto_rawDesc), len(file_guest_proto_rawDesc))) +func file_internal_proto_ateenv_v1alpha_guest_proto_rawDescGZIP() []byte { + file_internal_proto_ateenv_v1alpha_guest_proto_rawDescOnce.Do(func() { + file_internal_proto_ateenv_v1alpha_guest_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_internal_proto_ateenv_v1alpha_guest_proto_rawDesc), len(file_internal_proto_ateenv_v1alpha_guest_proto_rawDesc))) }) - return file_guest_proto_rawDescData + return file_internal_proto_ateenv_v1alpha_guest_proto_rawDescData } -var file_guest_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_guest_proto_msgTypes = make([]protoimpl.MessageInfo, 13) -var file_guest_proto_goTypes = []any{ +var file_internal_proto_ateenv_v1alpha_guest_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_internal_proto_ateenv_v1alpha_guest_proto_goTypes = []any{ (ProcessState)(0), // 0: ateenv.v1alpha.ProcessState (Signal)(0), // 1: ateenv.v1alpha.Signal (*Process)(nil), // 2: ateenv.v1alpha.Process @@ -1188,7 +1188,7 @@ var file_guest_proto_goTypes = []any{ (*timestamppb.Timestamp)(nil), // 15: google.protobuf.Timestamp (*durationpb.Duration)(nil), // 16: google.protobuf.Duration } -var file_guest_proto_depIdxs = []int32{ +var file_internal_proto_ateenv_v1alpha_guest_proto_depIdxs = []int32{ 0, // 0: ateenv.v1alpha.Process.state:type_name -> ateenv.v1alpha.ProcessState 15, // 1: ateenv.v1alpha.Process.started_at:type_name -> google.protobuf.Timestamp 15, // 2: ateenv.v1alpha.Process.finished_at:type_name -> google.protobuf.Timestamp @@ -1217,12 +1217,12 @@ var file_guest_proto_depIdxs = []int32{ 0, // [0:7] is the sub-list for field type_name } -func init() { file_guest_proto_init() } -func file_guest_proto_init() { - if File_guest_proto != nil { +func init() { file_internal_proto_ateenv_v1alpha_guest_proto_init() } +func file_internal_proto_ateenv_v1alpha_guest_proto_init() { + if File_internal_proto_ateenv_v1alpha_guest_proto != nil { return } - file_guest_proto_msgTypes[4].OneofWrappers = []any{ + file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes[4].OneofWrappers = []any{ (*ProcessOutput_Stdout)(nil), (*ProcessOutput_Stderr)(nil), (*ProcessOutput_Exit)(nil), @@ -1231,18 +1231,18 @@ func file_guest_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_guest_proto_rawDesc), len(file_guest_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_internal_proto_ateenv_v1alpha_guest_proto_rawDesc), len(file_internal_proto_ateenv_v1alpha_guest_proto_rawDesc)), NumEnums: 2, NumMessages: 13, NumExtensions: 0, NumServices: 2, }, - GoTypes: file_guest_proto_goTypes, - DependencyIndexes: file_guest_proto_depIdxs, - EnumInfos: file_guest_proto_enumTypes, - MessageInfos: file_guest_proto_msgTypes, + GoTypes: file_internal_proto_ateenv_v1alpha_guest_proto_goTypes, + DependencyIndexes: file_internal_proto_ateenv_v1alpha_guest_proto_depIdxs, + EnumInfos: file_internal_proto_ateenv_v1alpha_guest_proto_enumTypes, + MessageInfos: file_internal_proto_ateenv_v1alpha_guest_proto_msgTypes, }.Build() - File_guest_proto = out.File - file_guest_proto_goTypes = nil - file_guest_proto_depIdxs = nil + File_internal_proto_ateenv_v1alpha_guest_proto = out.File + file_internal_proto_ateenv_v1alpha_guest_proto_goTypes = nil + file_internal_proto_ateenv_v1alpha_guest_proto_depIdxs = nil } diff --git a/internal/proto/ateenv/v1alpha/guest_grpc.pb.go b/internal/proto/ateenv/v1alpha/guest_grpc.pb.go index 8e5e209f3c..c81e64d977 100644 --- a/internal/proto/ateenv/v1alpha/guest_grpc.pb.go +++ b/internal/proto/ateenv/v1alpha/guest_grpc.pb.go @@ -26,7 +26,7 @@ // versions: // - protoc-gen-go-grpc v1.6.2 // - protoc v4.25.3 -// source: guest.proto +// source: internal/proto/ateenv/v1alpha/guest.proto package ateenvv1alpha @@ -334,7 +334,7 @@ var ProcessService_ServiceDesc = grpc.ServiceDesc{ ClientStreams: true, }, }, - Metadata: "guest.proto", + Metadata: "internal/proto/ateenv/v1alpha/guest.proto", } const ( @@ -480,5 +480,5 @@ var FileSystemService_ServiceDesc = grpc.ServiceDesc{ ClientStreams: true, }, }, - Metadata: "guest.proto", + Metadata: "internal/proto/ateenv/v1alpha/guest.proto", } diff --git a/internal/proto/ateletpb/atelet.pb.go b/internal/proto/ateletpb/atelet.pb.go index 754fb1b093..70f40de83c 100644 --- a/internal/proto/ateletpb/atelet.pb.go +++ b/internal/proto/ateletpb/atelet.pb.go @@ -16,7 +16,7 @@ // versions: // protoc-gen-go v1.36.11-devel // protoc v4.25.3 -// source: atelet.proto +// source: internal/proto/ateletpb/atelet.proto package ateletpb @@ -73,11 +73,11 @@ func (x ActorMetadataField) String() string { } func (ActorMetadataField) Descriptor() protoreflect.EnumDescriptor { - return file_atelet_proto_enumTypes[0].Descriptor() + return file_internal_proto_ateletpb_atelet_proto_enumTypes[0].Descriptor() } func (ActorMetadataField) Type() protoreflect.EnumType { - return &file_atelet_proto_enumTypes[0] + return &file_internal_proto_ateletpb_atelet_proto_enumTypes[0] } func (x ActorMetadataField) Number() protoreflect.EnumNumber { @@ -86,7 +86,7 @@ func (x ActorMetadataField) Number() protoreflect.EnumNumber { // Deprecated: Use ActorMetadataField.Descriptor instead. func (ActorMetadataField) EnumDescriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{0} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{0} } // SnapshotFidelity mirrors the public ateapi enum: the state layers a @@ -134,11 +134,11 @@ func (x SnapshotFidelity) String() string { } func (SnapshotFidelity) Descriptor() protoreflect.EnumDescriptor { - return file_atelet_proto_enumTypes[1].Descriptor() + return file_internal_proto_ateletpb_atelet_proto_enumTypes[1].Descriptor() } func (SnapshotFidelity) Type() protoreflect.EnumType { - return &file_atelet_proto_enumTypes[1] + return &file_internal_proto_ateletpb_atelet_proto_enumTypes[1] } func (x SnapshotFidelity) Number() protoreflect.EnumNumber { @@ -147,7 +147,7 @@ func (x SnapshotFidelity) Number() protoreflect.EnumNumber { // Deprecated: Use SnapshotFidelity.Descriptor instead. func (SnapshotFidelity) EnumDescriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{1} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{1} } // SnapshotSharing is how a snapshot in object storage may be consumed, as @@ -190,11 +190,11 @@ func (x SnapshotSharing) String() string { } func (SnapshotSharing) Descriptor() protoreflect.EnumDescriptor { - return file_atelet_proto_enumTypes[2].Descriptor() + return file_internal_proto_ateletpb_atelet_proto_enumTypes[2].Descriptor() } func (SnapshotSharing) Type() protoreflect.EnumType { - return &file_atelet_proto_enumTypes[2] + return &file_internal_proto_ateletpb_atelet_proto_enumTypes[2] } func (x SnapshotSharing) Number() protoreflect.EnumNumber { @@ -203,7 +203,7 @@ func (x SnapshotSharing) Number() protoreflect.EnumNumber { // Deprecated: Use SnapshotSharing.Descriptor instead. func (SnapshotSharing) EnumDescriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{2} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{2} } // UploadMode is when a checkpoint's snapshot is uploaded. @@ -255,11 +255,11 @@ func (x UploadMode) String() string { } func (UploadMode) Descriptor() protoreflect.EnumDescriptor { - return file_atelet_proto_enumTypes[3].Descriptor() + return file_internal_proto_ateletpb_atelet_proto_enumTypes[3].Descriptor() } func (UploadMode) Type() protoreflect.EnumType { - return &file_atelet_proto_enumTypes[3] + return &file_internal_proto_ateletpb_atelet_proto_enumTypes[3] } func (x UploadMode) Number() protoreflect.EnumNumber { @@ -268,7 +268,7 @@ func (x UploadMode) Number() protoreflect.EnumNumber { // Deprecated: Use UploadMode.Descriptor instead. func (UploadMode) EnumDescriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{3} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{3} } type AcquireWorkerEpochRequest struct { @@ -279,7 +279,7 @@ type AcquireWorkerEpochRequest struct { func (x *AcquireWorkerEpochRequest) Reset() { *x = AcquireWorkerEpochRequest{} - mi := &file_atelet_proto_msgTypes[0] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -291,7 +291,7 @@ func (x *AcquireWorkerEpochRequest) String() string { func (*AcquireWorkerEpochRequest) ProtoMessage() {} func (x *AcquireWorkerEpochRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[0] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -304,7 +304,7 @@ func (x *AcquireWorkerEpochRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AcquireWorkerEpochRequest.ProtoReflect.Descriptor instead. func (*AcquireWorkerEpochRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{0} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{0} } type AcquireWorkerEpochResponse struct { @@ -317,7 +317,7 @@ type AcquireWorkerEpochResponse struct { func (x *AcquireWorkerEpochResponse) Reset() { *x = AcquireWorkerEpochResponse{} - mi := &file_atelet_proto_msgTypes[1] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -329,7 +329,7 @@ func (x *AcquireWorkerEpochResponse) String() string { func (*AcquireWorkerEpochResponse) ProtoMessage() {} func (x *AcquireWorkerEpochResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[1] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -342,7 +342,7 @@ func (x *AcquireWorkerEpochResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AcquireWorkerEpochResponse.ProtoReflect.Descriptor instead. func (*AcquireWorkerEpochResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{1} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{1} } func (x *AcquireWorkerEpochResponse) GetEpoch() int64 { @@ -377,7 +377,7 @@ type RegisterWorkerRequest struct { func (x *RegisterWorkerRequest) Reset() { *x = RegisterWorkerRequest{} - mi := &file_atelet_proto_msgTypes[2] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -389,7 +389,7 @@ func (x *RegisterWorkerRequest) String() string { func (*RegisterWorkerRequest) ProtoMessage() {} func (x *RegisterWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[2] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -402,7 +402,7 @@ func (x *RegisterWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterWorkerRequest.ProtoReflect.Descriptor instead. func (*RegisterWorkerRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{2} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{2} } func (x *RegisterWorkerRequest) GetEpoch() int64 { @@ -449,7 +449,7 @@ type SetWorkerSandboxRuntimesRequest struct { func (x *SetWorkerSandboxRuntimesRequest) Reset() { *x = SetWorkerSandboxRuntimesRequest{} - mi := &file_atelet_proto_msgTypes[3] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -461,7 +461,7 @@ func (x *SetWorkerSandboxRuntimesRequest) String() string { func (*SetWorkerSandboxRuntimesRequest) ProtoMessage() {} func (x *SetWorkerSandboxRuntimesRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[3] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -474,7 +474,7 @@ func (x *SetWorkerSandboxRuntimesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWorkerSandboxRuntimesRequest.ProtoReflect.Descriptor instead. func (*SetWorkerSandboxRuntimesRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{3} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{3} } func (x *SetWorkerSandboxRuntimesRequest) GetEpoch() int64 { @@ -499,7 +499,7 @@ type SetWorkerSandboxRuntimesResponse struct { func (x *SetWorkerSandboxRuntimesResponse) Reset() { *x = SetWorkerSandboxRuntimesResponse{} - mi := &file_atelet_proto_msgTypes[4] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -511,7 +511,7 @@ func (x *SetWorkerSandboxRuntimesResponse) String() string { func (*SetWorkerSandboxRuntimesResponse) ProtoMessage() {} func (x *SetWorkerSandboxRuntimesResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[4] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -524,7 +524,7 @@ func (x *SetWorkerSandboxRuntimesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWorkerSandboxRuntimesResponse.ProtoReflect.Descriptor instead. func (*SetWorkerSandboxRuntimesResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{4} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{4} } // WorkerSandboxClass is one sandbox class a worker runs, with the runtimes @@ -556,7 +556,7 @@ type WorkerSandboxClass struct { func (x *WorkerSandboxClass) Reset() { *x = WorkerSandboxClass{} - mi := &file_atelet_proto_msgTypes[5] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -568,7 +568,7 @@ func (x *WorkerSandboxClass) String() string { func (*WorkerSandboxClass) ProtoMessage() {} func (x *WorkerSandboxClass) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[5] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -581,7 +581,7 @@ func (x *WorkerSandboxClass) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerSandboxClass.ProtoReflect.Descriptor instead. func (*WorkerSandboxClass) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{5} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{5} } func (x *WorkerSandboxClass) GetSandboxClass() string { @@ -622,7 +622,7 @@ type WorkerSandboxRuntime struct { func (x *WorkerSandboxRuntime) Reset() { *x = WorkerSandboxRuntime{} - mi := &file_atelet_proto_msgTypes[6] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -634,7 +634,7 @@ func (x *WorkerSandboxRuntime) String() string { func (*WorkerSandboxRuntime) ProtoMessage() {} func (x *WorkerSandboxRuntime) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[6] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -647,7 +647,7 @@ func (x *WorkerSandboxRuntime) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerSandboxRuntime.ProtoReflect.Descriptor instead. func (*WorkerSandboxRuntime) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{6} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{6} } func (x *WorkerSandboxRuntime) GetVersion() *VersionedSandboxCompat { @@ -678,7 +678,7 @@ type ActorSandboxRuntime struct { func (x *ActorSandboxRuntime) Reset() { *x = ActorSandboxRuntime{} - mi := &file_atelet_proto_msgTypes[7] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -690,7 +690,7 @@ func (x *ActorSandboxRuntime) String() string { func (*ActorSandboxRuntime) ProtoMessage() {} func (x *ActorSandboxRuntime) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[7] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -703,7 +703,7 @@ func (x *ActorSandboxRuntime) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorSandboxRuntime.ProtoReflect.Descriptor instead. func (*ActorSandboxRuntime) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{7} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{7} } func (x *ActorSandboxRuntime) GetSandboxClass() string { @@ -753,7 +753,7 @@ type VersionedSandboxCompat struct { func (x *VersionedSandboxCompat) Reset() { *x = VersionedSandboxCompat{} - mi := &file_atelet_proto_msgTypes[8] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -765,7 +765,7 @@ func (x *VersionedSandboxCompat) String() string { func (*VersionedSandboxCompat) ProtoMessage() {} func (x *VersionedSandboxCompat) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[8] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -778,7 +778,7 @@ func (x *VersionedSandboxCompat) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionedSandboxCompat.ProtoReflect.Descriptor instead. func (*VersionedSandboxCompat) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{8} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{8} } func (x *VersionedSandboxCompat) GetSchemaVersion() string { @@ -814,7 +814,7 @@ type AttributeEntry struct { func (x *AttributeEntry) Reset() { *x = AttributeEntry{} - mi := &file_atelet_proto_msgTypes[9] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -826,7 +826,7 @@ func (x *AttributeEntry) String() string { func (*AttributeEntry) ProtoMessage() {} func (x *AttributeEntry) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[9] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -839,7 +839,7 @@ func (x *AttributeEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributeEntry.ProtoReflect.Descriptor instead. func (*AttributeEntry) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{9} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{9} } func (x *AttributeEntry) GetKey() string { @@ -886,7 +886,7 @@ type WorkerResources struct { func (x *WorkerResources) Reset() { *x = WorkerResources{} - mi := &file_atelet_proto_msgTypes[10] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -898,7 +898,7 @@ func (x *WorkerResources) String() string { func (*WorkerResources) ProtoMessage() {} func (x *WorkerResources) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[10] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -911,7 +911,7 @@ func (x *WorkerResources) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerResources.ProtoReflect.Descriptor instead. func (*WorkerResources) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{10} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{10} } func (x *WorkerResources) GetCpuMillicores() int64 { @@ -948,7 +948,7 @@ type ResourceRequirements struct { func (x *ResourceRequirements) Reset() { *x = ResourceRequirements{} - mi := &file_atelet_proto_msgTypes[11] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -960,7 +960,7 @@ func (x *ResourceRequirements) String() string { func (*ResourceRequirements) ProtoMessage() {} func (x *ResourceRequirements) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[11] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -973,7 +973,7 @@ func (x *ResourceRequirements) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceRequirements.ProtoReflect.Descriptor instead. func (*ResourceRequirements) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{11} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{11} } func (x *ResourceRequirements) GetLimits() *Resources { @@ -1003,7 +1003,7 @@ type Resources struct { func (x *Resources) Reset() { *x = Resources{} - mi := &file_atelet_proto_msgTypes[12] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1015,7 +1015,7 @@ func (x *Resources) String() string { func (*Resources) ProtoMessage() {} func (x *Resources) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[12] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1028,7 +1028,7 @@ func (x *Resources) ProtoReflect() protoreflect.Message { // Deprecated: Use Resources.ProtoReflect.Descriptor instead. func (*Resources) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{12} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{12} } func (x *Resources) GetCpuMillicores() int64 { @@ -1053,7 +1053,7 @@ type RegisterWorkerResponse struct { func (x *RegisterWorkerResponse) Reset() { *x = RegisterWorkerResponse{} - mi := &file_atelet_proto_msgTypes[13] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1065,7 +1065,7 @@ func (x *RegisterWorkerResponse) String() string { func (*RegisterWorkerResponse) ProtoMessage() {} func (x *RegisterWorkerResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[13] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1078,7 +1078,7 @@ func (x *RegisterWorkerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterWorkerResponse.ProtoReflect.Descriptor instead. func (*RegisterWorkerResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{13} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{13} } type RequestActorSuspendRequest struct { @@ -1105,7 +1105,7 @@ type RequestActorSuspendRequest struct { func (x *RequestActorSuspendRequest) Reset() { *x = RequestActorSuspendRequest{} - mi := &file_atelet_proto_msgTypes[14] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1117,7 +1117,7 @@ func (x *RequestActorSuspendRequest) String() string { func (*RequestActorSuspendRequest) ProtoMessage() {} func (x *RequestActorSuspendRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[14] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1130,7 +1130,7 @@ func (x *RequestActorSuspendRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestActorSuspendRequest.ProtoReflect.Descriptor instead. func (*RequestActorSuspendRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{14} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{14} } func (x *RequestActorSuspendRequest) GetActorAtespace() string { @@ -1162,7 +1162,7 @@ type RequestActorSuspendResponse struct { func (x *RequestActorSuspendResponse) Reset() { *x = RequestActorSuspendResponse{} - mi := &file_atelet_proto_msgTypes[15] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1174,7 +1174,7 @@ func (x *RequestActorSuspendResponse) String() string { func (*RequestActorSuspendResponse) ProtoMessage() {} func (x *RequestActorSuspendResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[15] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1187,7 +1187,7 @@ func (x *RequestActorSuspendResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestActorSuspendResponse.ProtoReflect.Descriptor instead. func (*RequestActorSuspendResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{15} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{15} } type ReportActorCrashedRequest struct { @@ -1214,7 +1214,7 @@ type ReportActorCrashedRequest struct { func (x *ReportActorCrashedRequest) Reset() { *x = ReportActorCrashedRequest{} - mi := &file_atelet_proto_msgTypes[16] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1226,7 +1226,7 @@ func (x *ReportActorCrashedRequest) String() string { func (*ReportActorCrashedRequest) ProtoMessage() {} func (x *ReportActorCrashedRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[16] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1239,7 +1239,7 @@ func (x *ReportActorCrashedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorCrashedRequest.ProtoReflect.Descriptor instead. func (*ReportActorCrashedRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{16} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{16} } func (x *ReportActorCrashedRequest) GetActorAtespace() string { @@ -1278,7 +1278,7 @@ type ReportActorCrashedResponse struct { func (x *ReportActorCrashedResponse) Reset() { *x = ReportActorCrashedResponse{} - mi := &file_atelet_proto_msgTypes[17] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1290,7 +1290,7 @@ func (x *ReportActorCrashedResponse) String() string { func (*ReportActorCrashedResponse) ProtoMessage() {} func (x *ReportActorCrashedResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[17] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1303,7 +1303,7 @@ func (x *ReportActorCrashedResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorCrashedResponse.ProtoReflect.Descriptor instead. func (*ReportActorCrashedResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{17} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{17} } type GetActorEgressPolicyRequest struct { @@ -1323,7 +1323,7 @@ type GetActorEgressPolicyRequest struct { func (x *GetActorEgressPolicyRequest) Reset() { *x = GetActorEgressPolicyRequest{} - mi := &file_atelet_proto_msgTypes[18] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1335,7 +1335,7 @@ func (x *GetActorEgressPolicyRequest) String() string { func (*GetActorEgressPolicyRequest) ProtoMessage() {} func (x *GetActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[18] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1348,7 +1348,7 @@ func (x *GetActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*GetActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{18} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{18} } func (x *GetActorEgressPolicyRequest) GetActorAtespace() string { @@ -1376,7 +1376,7 @@ type GetActorEgressPolicyResponse struct { func (x *GetActorEgressPolicyResponse) Reset() { *x = GetActorEgressPolicyResponse{} - mi := &file_atelet_proto_msgTypes[19] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1388,7 +1388,7 @@ func (x *GetActorEgressPolicyResponse) String() string { func (*GetActorEgressPolicyResponse) ProtoMessage() {} func (x *GetActorEgressPolicyResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[19] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1401,7 +1401,7 @@ func (x *GetActorEgressPolicyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorEgressPolicyResponse.ProtoReflect.Descriptor instead. func (*GetActorEgressPolicyResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{19} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{19} } func (x *GetActorEgressPolicyResponse) GetEgressPolicy() *EgressPolicy { @@ -1425,7 +1425,7 @@ type EgressPolicy struct { func (x *EgressPolicy) Reset() { *x = EgressPolicy{} - mi := &file_atelet_proto_msgTypes[20] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1437,7 +1437,7 @@ func (x *EgressPolicy) String() string { func (*EgressPolicy) ProtoMessage() {} func (x *EgressPolicy) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[20] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1450,7 +1450,7 @@ func (x *EgressPolicy) ProtoReflect() protoreflect.Message { // Deprecated: Use EgressPolicy.ProtoReflect.Descriptor instead. func (*EgressPolicy) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{20} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{20} } func (x *EgressPolicy) GetRules() []*EgressRule { @@ -1477,7 +1477,7 @@ type EgressRule struct { func (x *EgressRule) Reset() { *x = EgressRule{} - mi := &file_atelet_proto_msgTypes[21] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1489,7 +1489,7 @@ func (x *EgressRule) String() string { func (*EgressRule) ProtoMessage() {} func (x *EgressRule) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[21] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1502,7 +1502,7 @@ func (x *EgressRule) ProtoReflect() protoreflect.Message { // Deprecated: Use EgressRule.ProtoReflect.Descriptor instead. func (*EgressRule) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{21} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{21} } func (x *EgressRule) GetHttp() *EgressDestinations { @@ -1540,7 +1540,7 @@ type EgressDestinations struct { func (x *EgressDestinations) Reset() { *x = EgressDestinations{} - mi := &file_atelet_proto_msgTypes[22] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1552,7 +1552,7 @@ func (x *EgressDestinations) String() string { func (*EgressDestinations) ProtoMessage() {} func (x *EgressDestinations) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[22] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1565,7 +1565,7 @@ func (x *EgressDestinations) ProtoReflect() protoreflect.Message { // Deprecated: Use EgressDestinations.ProtoReflect.Descriptor instead. func (*EgressDestinations) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{22} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{22} } func (x *EgressDestinations) GetHostnames() []string { @@ -1596,7 +1596,7 @@ type EgressPorts struct { func (x *EgressPorts) Reset() { *x = EgressPorts{} - mi := &file_atelet_proto_msgTypes[23] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1608,7 +1608,7 @@ func (x *EgressPorts) String() string { func (*EgressPorts) ProtoMessage() {} func (x *EgressPorts) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[23] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1621,7 +1621,7 @@ func (x *EgressPorts) ProtoReflect() protoreflect.Message { // Deprecated: Use EgressPorts.ProtoReflect.Descriptor instead. func (*EgressPorts) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{23} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{23} } func (x *EgressPorts) GetAll() *EgressAllPorts { @@ -1647,7 +1647,7 @@ type EgressAllPorts struct { func (x *EgressAllPorts) Reset() { *x = EgressAllPorts{} - mi := &file_atelet_proto_msgTypes[24] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1659,7 +1659,7 @@ func (x *EgressAllPorts) String() string { func (*EgressAllPorts) ProtoMessage() {} func (x *EgressAllPorts) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[24] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1672,7 +1672,7 @@ func (x *EgressAllPorts) ProtoReflect() protoreflect.Message { // Deprecated: Use EgressAllPorts.ProtoReflect.Descriptor instead. func (*EgressAllPorts) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{24} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{24} } type MintActorCertificateRequest struct { @@ -1703,7 +1703,7 @@ type MintActorCertificateRequest struct { func (x *MintActorCertificateRequest) Reset() { *x = MintActorCertificateRequest{} - mi := &file_atelet_proto_msgTypes[25] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1715,7 +1715,7 @@ func (x *MintActorCertificateRequest) String() string { func (*MintActorCertificateRequest) ProtoMessage() {} func (x *MintActorCertificateRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[25] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1728,7 +1728,7 @@ func (x *MintActorCertificateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorCertificateRequest.ProtoReflect.Descriptor instead. func (*MintActorCertificateRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{25} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{25} } func (x *MintActorCertificateRequest) GetActorAtespace() string { @@ -1769,7 +1769,7 @@ type MintActorCertificateResponse struct { func (x *MintActorCertificateResponse) Reset() { *x = MintActorCertificateResponse{} - mi := &file_atelet_proto_msgTypes[26] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1781,7 +1781,7 @@ func (x *MintActorCertificateResponse) String() string { func (*MintActorCertificateResponse) ProtoMessage() {} func (x *MintActorCertificateResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[26] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1794,7 +1794,7 @@ func (x *MintActorCertificateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorCertificateResponse.ProtoReflect.Descriptor instead. func (*MintActorCertificateResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{26} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{26} } func (x *MintActorCertificateResponse) GetActorCertificates() [][]byte { @@ -1840,7 +1840,7 @@ type TerminateRequest struct { func (x *TerminateRequest) Reset() { *x = TerminateRequest{} - mi := &file_atelet_proto_msgTypes[27] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1852,7 +1852,7 @@ func (x *TerminateRequest) String() string { func (*TerminateRequest) ProtoMessage() {} func (x *TerminateRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[27] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1865,7 +1865,7 @@ func (x *TerminateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use TerminateRequest.ProtoReflect.Descriptor instead. func (*TerminateRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{27} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{27} } func (x *TerminateRequest) GetWorkerPodUid() string { @@ -1925,7 +1925,7 @@ type TerminateResponse struct { func (x *TerminateResponse) Reset() { *x = TerminateResponse{} - mi := &file_atelet_proto_msgTypes[28] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1937,7 +1937,7 @@ func (x *TerminateResponse) String() string { func (*TerminateResponse) ProtoMessage() {} func (x *TerminateResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[28] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1950,7 +1950,7 @@ func (x *TerminateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use TerminateResponse.ProtoReflect.Descriptor instead. func (*TerminateResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{28} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{28} } type RunRequest struct { @@ -2002,7 +2002,7 @@ type RunRequest struct { func (x *RunRequest) Reset() { *x = RunRequest{} - mi := &file_atelet_proto_msgTypes[29] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2014,7 +2014,7 @@ func (x *RunRequest) String() string { func (*RunRequest) ProtoMessage() {} func (x *RunRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[29] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2027,7 +2027,7 @@ func (x *RunRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RunRequest.ProtoReflect.Descriptor instead. func (*RunRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{29} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{29} } func (x *RunRequest) GetWorkerPodUid() string { @@ -2116,7 +2116,7 @@ type EgressGateway struct { func (x *EgressGateway) Reset() { *x = EgressGateway{} - mi := &file_atelet_proto_msgTypes[30] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2128,7 +2128,7 @@ func (x *EgressGateway) String() string { func (*EgressGateway) ProtoMessage() {} func (x *EgressGateway) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[30] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2141,7 +2141,7 @@ func (x *EgressGateway) ProtoReflect() protoreflect.Message { // Deprecated: Use EgressGateway.ProtoReflect.Descriptor instead. func (*EgressGateway) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{30} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{30} } func (x *EgressGateway) GetAddress() string { @@ -2172,7 +2172,7 @@ type WorkloadSpec struct { func (x *WorkloadSpec) Reset() { *x = WorkloadSpec{} - mi := &file_atelet_proto_msgTypes[31] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2184,7 +2184,7 @@ func (x *WorkloadSpec) String() string { func (*WorkloadSpec) ProtoMessage() {} func (x *WorkloadSpec) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[31] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2197,7 +2197,7 @@ func (x *WorkloadSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkloadSpec.ProtoReflect.Descriptor instead. func (*WorkloadSpec) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{31} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{31} } func (x *WorkloadSpec) GetContainers() []*Container { @@ -2222,7 +2222,7 @@ type DurableDirVolumeSource struct { func (x *DurableDirVolumeSource) Reset() { *x = DurableDirVolumeSource{} - mi := &file_atelet_proto_msgTypes[32] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2234,7 +2234,7 @@ func (x *DurableDirVolumeSource) String() string { func (*DurableDirVolumeSource) ProtoMessage() {} func (x *DurableDirVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[32] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2247,7 +2247,7 @@ func (x *DurableDirVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use DurableDirVolumeSource.ProtoReflect.Descriptor instead. func (*DurableDirVolumeSource) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{32} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{32} } type ExternalVolumeSource struct { @@ -2281,7 +2281,7 @@ type ExternalVolumeSource struct { func (x *ExternalVolumeSource) Reset() { *x = ExternalVolumeSource{} - mi := &file_atelet_proto_msgTypes[33] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2293,7 +2293,7 @@ func (x *ExternalVolumeSource) String() string { func (*ExternalVolumeSource) ProtoMessage() {} func (x *ExternalVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[33] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2306,7 +2306,7 @@ func (x *ExternalVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ExternalVolumeSource.ProtoReflect.Descriptor instead. func (*ExternalVolumeSource) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{33} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{33} } func (x *ExternalVolumeSource) GetStorageVolumeId() string { @@ -2351,7 +2351,7 @@ type ImageVolumeSource struct { func (x *ImageVolumeSource) Reset() { *x = ImageVolumeSource{} - mi := &file_atelet_proto_msgTypes[34] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2363,7 +2363,7 @@ func (x *ImageVolumeSource) String() string { func (*ImageVolumeSource) ProtoMessage() {} func (x *ImageVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[34] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2376,7 +2376,7 @@ func (x *ImageVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageVolumeSource.ProtoReflect.Descriptor instead. func (*ImageVolumeSource) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{34} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{34} } func (x *ImageVolumeSource) GetReference() string { @@ -2408,7 +2408,7 @@ type ActorMetadataItem struct { func (x *ActorMetadataItem) Reset() { *x = ActorMetadataItem{} - mi := &file_atelet_proto_msgTypes[35] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2420,7 +2420,7 @@ func (x *ActorMetadataItem) String() string { func (*ActorMetadataItem) ProtoMessage() {} func (x *ActorMetadataItem) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[35] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2433,7 +2433,7 @@ func (x *ActorMetadataItem) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorMetadataItem.ProtoReflect.Descriptor instead. func (*ActorMetadataItem) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{35} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{35} } func (x *ActorMetadataItem) GetField() ActorMetadataField { @@ -2469,7 +2469,7 @@ type ActorMetadataDataSource struct { func (x *ActorMetadataDataSource) Reset() { *x = ActorMetadataDataSource{} - mi := &file_atelet_proto_msgTypes[36] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2481,7 +2481,7 @@ func (x *ActorMetadataDataSource) String() string { func (*ActorMetadataDataSource) ProtoMessage() {} func (x *ActorMetadataDataSource) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[36] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2494,7 +2494,7 @@ func (x *ActorMetadataDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorMetadataDataSource.ProtoReflect.Descriptor instead. func (*ActorMetadataDataSource) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{36} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{36} } func (x *ActorMetadataDataSource) GetItems() []*ActorMetadataItem { @@ -2528,7 +2528,7 @@ type TrustBundleDataSource struct { func (x *TrustBundleDataSource) Reset() { *x = TrustBundleDataSource{} - mi := &file_atelet_proto_msgTypes[37] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2540,7 +2540,7 @@ func (x *TrustBundleDataSource) String() string { func (*TrustBundleDataSource) ProtoMessage() {} func (x *TrustBundleDataSource) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[37] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2553,7 +2553,7 @@ func (x *TrustBundleDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use TrustBundleDataSource.ProtoReflect.Descriptor instead. func (*TrustBundleDataSource) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{37} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{37} } func (x *TrustBundleDataSource) GetPath() string { @@ -2588,7 +2588,7 @@ type SystemInfoDataSource struct { func (x *SystemInfoDataSource) Reset() { *x = SystemInfoDataSource{} - mi := &file_atelet_proto_msgTypes[38] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2600,7 +2600,7 @@ func (x *SystemInfoDataSource) String() string { func (*SystemInfoDataSource) ProtoMessage() {} func (x *SystemInfoDataSource) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[38] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2613,7 +2613,7 @@ func (x *SystemInfoDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use SystemInfoDataSource.ProtoReflect.Descriptor instead. func (*SystemInfoDataSource) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{38} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{38} } func (x *SystemInfoDataSource) GetActorMetadata() *ActorMetadataDataSource { @@ -2646,7 +2646,7 @@ type SystemInfoVolumeSource struct { func (x *SystemInfoVolumeSource) Reset() { *x = SystemInfoVolumeSource{} - mi := &file_atelet_proto_msgTypes[39] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2658,7 +2658,7 @@ func (x *SystemInfoVolumeSource) String() string { func (*SystemInfoVolumeSource) ProtoMessage() {} func (x *SystemInfoVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[39] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2671,7 +2671,7 @@ func (x *SystemInfoVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use SystemInfoVolumeSource.ProtoReflect.Descriptor instead. func (*SystemInfoVolumeSource) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{39} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{39} } func (x *SystemInfoVolumeSource) GetDataSources() []*SystemInfoDataSource { @@ -2707,7 +2707,7 @@ type Volume struct { func (x *Volume) Reset() { *x = Volume{} - mi := &file_atelet_proto_msgTypes[40] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2719,7 +2719,7 @@ func (x *Volume) String() string { func (*Volume) ProtoMessage() {} func (x *Volume) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[40] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2732,7 +2732,7 @@ func (x *Volume) ProtoReflect() protoreflect.Message { // Deprecated: Use Volume.ProtoReflect.Descriptor instead. func (*Volume) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{40} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{40} } func (x *Volume) GetName() string { @@ -2789,7 +2789,7 @@ type VolumeMount struct { func (x *VolumeMount) Reset() { *x = VolumeMount{} - mi := &file_atelet_proto_msgTypes[41] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2801,7 +2801,7 @@ func (x *VolumeMount) String() string { func (*VolumeMount) ProtoMessage() {} func (x *VolumeMount) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[41] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2814,7 +2814,7 @@ func (x *VolumeMount) ProtoReflect() protoreflect.Message { // Deprecated: Use VolumeMount.ProtoReflect.Descriptor instead. func (*VolumeMount) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{41} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{41} } func (x *VolumeMount) GetName() string { @@ -2879,7 +2879,7 @@ type Container struct { func (x *Container) Reset() { *x = Container{} - mi := &file_atelet_proto_msgTypes[42] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2891,7 +2891,7 @@ func (x *Container) String() string { func (*Container) ProtoMessage() {} func (x *Container) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[42] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2904,7 +2904,7 @@ func (x *Container) ProtoReflect() protoreflect.Message { // Deprecated: Use Container.ProtoReflect.Descriptor instead. func (*Container) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{42} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{42} } func (x *Container) GetName() string { @@ -2981,7 +2981,7 @@ type SecurityContext struct { func (x *SecurityContext) Reset() { *x = SecurityContext{} - mi := &file_atelet_proto_msgTypes[43] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2993,7 +2993,7 @@ func (x *SecurityContext) String() string { func (*SecurityContext) ProtoMessage() {} func (x *SecurityContext) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[43] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3006,7 +3006,7 @@ func (x *SecurityContext) ProtoReflect() protoreflect.Message { // Deprecated: Use SecurityContext.ProtoReflect.Descriptor instead. func (*SecurityContext) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{43} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{43} } func (x *SecurityContext) GetCapabilities() *Capabilities { @@ -3036,7 +3036,7 @@ type Capabilities struct { func (x *Capabilities) Reset() { *x = Capabilities{} - mi := &file_atelet_proto_msgTypes[44] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3048,7 +3048,7 @@ func (x *Capabilities) String() string { func (*Capabilities) ProtoMessage() {} func (x *Capabilities) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[44] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3061,7 +3061,7 @@ func (x *Capabilities) ProtoReflect() protoreflect.Message { // Deprecated: Use Capabilities.ProtoReflect.Descriptor instead. func (*Capabilities) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{44} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{44} } func (x *Capabilities) GetAdd() []string { @@ -3095,7 +3095,7 @@ type EnvVar struct { func (x *EnvVar) Reset() { *x = EnvVar{} - mi := &file_atelet_proto_msgTypes[45] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3107,7 +3107,7 @@ func (x *EnvVar) String() string { func (*EnvVar) ProtoMessage() {} func (x *EnvVar) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[45] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3120,7 +3120,7 @@ func (x *EnvVar) ProtoReflect() protoreflect.Message { // Deprecated: Use EnvVar.ProtoReflect.Descriptor instead. func (*EnvVar) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{45} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{45} } func (x *EnvVar) GetName() string { @@ -3155,7 +3155,7 @@ type WakeupProbe struct { func (x *WakeupProbe) Reset() { *x = WakeupProbe{} - mi := &file_atelet_proto_msgTypes[46] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3167,7 +3167,7 @@ func (x *WakeupProbe) String() string { func (*WakeupProbe) ProtoMessage() {} func (x *WakeupProbe) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[46] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3180,7 +3180,7 @@ func (x *WakeupProbe) ProtoReflect() protoreflect.Message { // Deprecated: Use WakeupProbe.ProtoReflect.Descriptor instead. func (*WakeupProbe) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{46} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{46} } func (x *WakeupProbe) GetHttpGet() *HttpGetAction { @@ -3218,7 +3218,7 @@ type HttpGetAction struct { func (x *HttpGetAction) Reset() { *x = HttpGetAction{} - mi := &file_atelet_proto_msgTypes[47] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3230,7 +3230,7 @@ func (x *HttpGetAction) String() string { func (*HttpGetAction) ProtoMessage() {} func (x *HttpGetAction) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[47] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3243,7 +3243,7 @@ func (x *HttpGetAction) ProtoReflect() protoreflect.Message { // Deprecated: Use HttpGetAction.ProtoReflect.Descriptor instead. func (*HttpGetAction) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{47} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{47} } func (x *HttpGetAction) GetPath() string { @@ -3271,7 +3271,7 @@ type RunResponse struct { func (x *RunResponse) Reset() { *x = RunResponse{} - mi := &file_atelet_proto_msgTypes[48] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3283,7 +3283,7 @@ func (x *RunResponse) String() string { func (*RunResponse) ProtoMessage() {} func (x *RunResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[48] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3296,7 +3296,7 @@ func (x *RunResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RunResponse.ProtoReflect.Descriptor instead. func (*RunResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{48} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{48} } func (x *RunResponse) GetWorkerEpoch() int64 { @@ -3329,7 +3329,7 @@ type ObjectStorage struct { func (x *ObjectStorage) Reset() { *x = ObjectStorage{} - mi := &file_atelet_proto_msgTypes[49] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3341,7 +3341,7 @@ func (x *ObjectStorage) String() string { func (*ObjectStorage) ProtoMessage() {} func (x *ObjectStorage) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[49] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3354,7 +3354,7 @@ func (x *ObjectStorage) ProtoReflect() protoreflect.Message { // Deprecated: Use ObjectStorage.ProtoReflect.Descriptor instead. func (*ObjectStorage) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{49} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{49} } func (x *ObjectStorage) GetSnapshotUri() string { @@ -3415,7 +3415,7 @@ type Snapshot struct { func (x *Snapshot) Reset() { *x = Snapshot{} - mi := &file_atelet_proto_msgTypes[50] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3427,7 +3427,7 @@ func (x *Snapshot) String() string { func (*Snapshot) ProtoMessage() {} func (x *Snapshot) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[50] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3440,7 +3440,7 @@ func (x *Snapshot) ProtoReflect() protoreflect.Message { // Deprecated: Use Snapshot.ProtoReflect.Descriptor instead. func (*Snapshot) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{50} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{50} } func (x *Snapshot) GetSnapshotUuid() string { @@ -3487,7 +3487,7 @@ type SnapshotReport struct { func (x *SnapshotReport) Reset() { *x = SnapshotReport{} - mi := &file_atelet_proto_msgTypes[51] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3499,7 +3499,7 @@ func (x *SnapshotReport) String() string { func (*SnapshotReport) ProtoMessage() {} func (x *SnapshotReport) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[51] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3512,7 +3512,7 @@ func (x *SnapshotReport) ProtoReflect() protoreflect.Message { // Deprecated: Use SnapshotReport.ProtoReflect.Descriptor instead. func (*SnapshotReport) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{51} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{51} } func (x *SnapshotReport) GetSnapshot() *Snapshot { @@ -3569,7 +3569,7 @@ type ActorSnapshotState struct { func (x *ActorSnapshotState) Reset() { *x = ActorSnapshotState{} - mi := &file_atelet_proto_msgTypes[52] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3581,7 +3581,7 @@ func (x *ActorSnapshotState) String() string { func (*ActorSnapshotState) ProtoMessage() {} func (x *ActorSnapshotState) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[52] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3594,7 +3594,7 @@ func (x *ActorSnapshotState) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorSnapshotState.ProtoReflect.Descriptor instead. func (*ActorSnapshotState) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{52} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{52} } func (x *ActorSnapshotState) GetLatestLocal() *SnapshotReport { @@ -3638,7 +3638,7 @@ type UploadConfig struct { func (x *UploadConfig) Reset() { *x = UploadConfig{} - mi := &file_atelet_proto_msgTypes[53] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3650,7 +3650,7 @@ func (x *UploadConfig) String() string { func (*UploadConfig) ProtoMessage() {} func (x *UploadConfig) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[53] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3663,7 +3663,7 @@ func (x *UploadConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadConfig.ProtoReflect.Descriptor instead. func (*UploadConfig) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{53} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{53} } func (x *UploadConfig) GetMode() UploadMode { @@ -3725,7 +3725,7 @@ type CheckpointRequest struct { func (x *CheckpointRequest) Reset() { *x = CheckpointRequest{} - mi := &file_atelet_proto_msgTypes[54] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3737,7 +3737,7 @@ func (x *CheckpointRequest) String() string { func (*CheckpointRequest) ProtoMessage() {} func (x *CheckpointRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[54] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3750,7 +3750,7 @@ func (x *CheckpointRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckpointRequest.ProtoReflect.Descriptor instead. func (*CheckpointRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{54} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{54} } func (x *CheckpointRequest) GetWorkerPodUid() string { @@ -3834,7 +3834,7 @@ type CheckpointResponse struct { func (x *CheckpointResponse) Reset() { *x = CheckpointResponse{} - mi := &file_atelet_proto_msgTypes[55] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3846,7 +3846,7 @@ func (x *CheckpointResponse) String() string { func (*CheckpointResponse) ProtoMessage() {} func (x *CheckpointResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[55] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3859,7 +3859,7 @@ func (x *CheckpointResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckpointResponse.ProtoReflect.Descriptor instead. func (*CheckpointResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{55} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{55} } func (x *CheckpointResponse) GetState() *ActorSnapshotState { @@ -3933,7 +3933,7 @@ type RestoreRequest struct { func (x *RestoreRequest) Reset() { *x = RestoreRequest{} - mi := &file_atelet_proto_msgTypes[56] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3945,7 +3945,7 @@ func (x *RestoreRequest) String() string { func (*RestoreRequest) ProtoMessage() {} func (x *RestoreRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[56] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3958,7 +3958,7 @@ func (x *RestoreRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreRequest.ProtoReflect.Descriptor instead. func (*RestoreRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{56} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{56} } func (x *RestoreRequest) GetWorkerPodUid() string { @@ -4049,7 +4049,7 @@ type RestoreResponse struct { func (x *RestoreResponse) Reset() { *x = RestoreResponse{} - mi := &file_atelet_proto_msgTypes[57] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4061,7 +4061,7 @@ func (x *RestoreResponse) String() string { func (*RestoreResponse) ProtoMessage() {} func (x *RestoreResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[57] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4074,7 +4074,7 @@ func (x *RestoreResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreResponse.ProtoReflect.Descriptor instead. func (*RestoreResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{57} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{57} } func (x *RestoreResponse) GetWorkerEpoch() int64 { @@ -4114,7 +4114,7 @@ type PromoteSnapshotRequest struct { func (x *PromoteSnapshotRequest) Reset() { *x = PromoteSnapshotRequest{} - mi := &file_atelet_proto_msgTypes[58] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4126,7 +4126,7 @@ func (x *PromoteSnapshotRequest) String() string { func (*PromoteSnapshotRequest) ProtoMessage() {} func (x *PromoteSnapshotRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[58] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4139,7 +4139,7 @@ func (x *PromoteSnapshotRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PromoteSnapshotRequest.ProtoReflect.Descriptor instead. func (*PromoteSnapshotRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{58} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{58} } func (x *PromoteSnapshotRequest) GetAtespace() string { @@ -4195,7 +4195,7 @@ type PromoteSnapshotResponse struct { func (x *PromoteSnapshotResponse) Reset() { *x = PromoteSnapshotResponse{} - mi := &file_atelet_proto_msgTypes[59] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4207,7 +4207,7 @@ func (x *PromoteSnapshotResponse) String() string { func (*PromoteSnapshotResponse) ProtoMessage() {} func (x *PromoteSnapshotResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[59] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4220,7 +4220,7 @@ func (x *PromoteSnapshotResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PromoteSnapshotResponse.ProtoReflect.Descriptor instead. func (*PromoteSnapshotResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{59} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{59} } func (x *PromoteSnapshotResponse) GetState() *ActorSnapshotState { @@ -4249,7 +4249,7 @@ type DetachActorRequest struct { func (x *DetachActorRequest) Reset() { *x = DetachActorRequest{} - mi := &file_atelet_proto_msgTypes[60] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4261,7 +4261,7 @@ func (x *DetachActorRequest) String() string { func (*DetachActorRequest) ProtoMessage() {} func (x *DetachActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[60] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4274,7 +4274,7 @@ func (x *DetachActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DetachActorRequest.ProtoReflect.Descriptor instead. func (*DetachActorRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{60} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{60} } func (x *DetachActorRequest) GetAtespace() string { @@ -4310,7 +4310,7 @@ type DetachActorResponse struct { func (x *DetachActorResponse) Reset() { *x = DetachActorResponse{} - mi := &file_atelet_proto_msgTypes[61] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4322,7 +4322,7 @@ func (x *DetachActorResponse) String() string { func (*DetachActorResponse) ProtoMessage() {} func (x *DetachActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[61] + mi := &file_internal_proto_ateletpb_atelet_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4335,7 +4335,7 @@ func (x *DetachActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DetachActorResponse.ProtoReflect.Descriptor instead. func (*DetachActorResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{61} + return file_internal_proto_ateletpb_atelet_proto_rawDescGZIP(), []int{61} } func (x *DetachActorResponse) GetState() *ActorSnapshotState { @@ -4345,11 +4345,11 @@ func (x *DetachActorResponse) GetState() *ActorSnapshotState { return nil } -var File_atelet_proto protoreflect.FileDescriptor +var File_internal_proto_ateletpb_atelet_proto protoreflect.FileDescriptor -const file_atelet_proto_rawDesc = "" + +const file_internal_proto_ateletpb_atelet_proto_rawDesc = "" + "\n" + - "\fatelet.proto\x12\x06atelet\x1a\x1fgoogle/protobuf/timestamp.proto\"\x1b\n" + + "$internal/proto/ateletpb/atelet.proto\x12\x06atelet\x1a\x1fgoogle/protobuf/timestamp.proto\"\x1b\n" + "\x19AcquireWorkerEpochRequest\"2\n" + "\x1aAcquireWorkerEpochResponse\x12\x14\n" + "\x05epoch\x18\x01 \x01(\x03R\x05epoch\"t\n" + @@ -4632,20 +4632,20 @@ const file_atelet_proto_rawDesc = "" + "\tTerminate\x12\x18.atelet.TerminateRequest\x1a\x19.atelet.TerminateResponse\"\x00B.Z,go.ate.dev/substrate/internal/proto/ateletpbb\x06proto3" var ( - file_atelet_proto_rawDescOnce sync.Once - file_atelet_proto_rawDescData []byte + file_internal_proto_ateletpb_atelet_proto_rawDescOnce sync.Once + file_internal_proto_ateletpb_atelet_proto_rawDescData []byte ) -func file_atelet_proto_rawDescGZIP() []byte { - file_atelet_proto_rawDescOnce.Do(func() { - file_atelet_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_atelet_proto_rawDesc), len(file_atelet_proto_rawDesc))) +func file_internal_proto_ateletpb_atelet_proto_rawDescGZIP() []byte { + file_internal_proto_ateletpb_atelet_proto_rawDescOnce.Do(func() { + file_internal_proto_ateletpb_atelet_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_internal_proto_ateletpb_atelet_proto_rawDesc), len(file_internal_proto_ateletpb_atelet_proto_rawDesc))) }) - return file_atelet_proto_rawDescData + return file_internal_proto_ateletpb_atelet_proto_rawDescData } -var file_atelet_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_atelet_proto_msgTypes = make([]protoimpl.MessageInfo, 64) -var file_atelet_proto_goTypes = []any{ +var file_internal_proto_ateletpb_atelet_proto_enumTypes = make([]protoimpl.EnumInfo, 4) +var file_internal_proto_ateletpb_atelet_proto_msgTypes = make([]protoimpl.MessageInfo, 64) +var file_internal_proto_ateletpb_atelet_proto_goTypes = []any{ (ActorMetadataField)(0), // 0: atelet.ActorMetadataField (SnapshotFidelity)(0), // 1: atelet.SnapshotFidelity (SnapshotSharing)(0), // 2: atelet.SnapshotSharing @@ -4716,7 +4716,7 @@ var file_atelet_proto_goTypes = []any{ nil, // 67: atelet.ExternalVolumeSource.PublishContextEntry (*timestamppb.Timestamp)(nil), // 68: google.protobuf.Timestamp } -var file_atelet_proto_depIdxs = []int32{ +var file_internal_proto_ateletpb_atelet_proto_depIdxs = []int32{ 14, // 0: atelet.RegisterWorkerRequest.capacity:type_name -> atelet.WorkerResources 9, // 1: atelet.SetWorkerSandboxRuntimesRequest.sandbox_classes:type_name -> atelet.WorkerSandboxClass 10, // 2: atelet.WorkerSandboxClass.default_runtime:type_name -> atelet.WorkerSandboxRuntime @@ -4813,29 +4813,29 @@ var file_atelet_proto_depIdxs = []int32{ 0, // [0:63] is the sub-list for field type_name } -func init() { file_atelet_proto_init() } -func file_atelet_proto_init() { - if File_atelet_proto != nil { +func init() { file_internal_proto_ateletpb_atelet_proto_init() } +func file_internal_proto_ateletpb_atelet_proto_init() { + if File_internal_proto_ateletpb_atelet_proto != nil { return } - file_atelet_proto_msgTypes[29].OneofWrappers = []any{} - file_atelet_proto_msgTypes[56].OneofWrappers = []any{} + file_internal_proto_ateletpb_atelet_proto_msgTypes[29].OneofWrappers = []any{} + file_internal_proto_ateletpb_atelet_proto_msgTypes[56].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_atelet_proto_rawDesc), len(file_atelet_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_internal_proto_ateletpb_atelet_proto_rawDesc), len(file_internal_proto_ateletpb_atelet_proto_rawDesc)), NumEnums: 4, NumMessages: 64, NumExtensions: 0, NumServices: 2, }, - GoTypes: file_atelet_proto_goTypes, - DependencyIndexes: file_atelet_proto_depIdxs, - EnumInfos: file_atelet_proto_enumTypes, - MessageInfos: file_atelet_proto_msgTypes, + GoTypes: file_internal_proto_ateletpb_atelet_proto_goTypes, + DependencyIndexes: file_internal_proto_ateletpb_atelet_proto_depIdxs, + EnumInfos: file_internal_proto_ateletpb_atelet_proto_enumTypes, + MessageInfos: file_internal_proto_ateletpb_atelet_proto_msgTypes, }.Build() - File_atelet_proto = out.File - file_atelet_proto_goTypes = nil - file_atelet_proto_depIdxs = nil + File_internal_proto_ateletpb_atelet_proto = out.File + file_internal_proto_ateletpb_atelet_proto_goTypes = nil + file_internal_proto_ateletpb_atelet_proto_depIdxs = nil } diff --git a/internal/proto/ateletpb/atelet_grpc.pb.go b/internal/proto/ateletpb/atelet_grpc.pb.go index a3c2a54c82..9c3cec57a3 100644 --- a/internal/proto/ateletpb/atelet_grpc.pb.go +++ b/internal/proto/ateletpb/atelet_grpc.pb.go @@ -16,7 +16,7 @@ // versions: // - protoc-gen-go-grpc v1.6.2 // - protoc v4.25.3 -// source: atelet.proto +// source: internal/proto/ateletpb/atelet.proto package ateletpb @@ -429,7 +429,7 @@ var WorkerSupport_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "atelet.proto", + Metadata: "internal/proto/ateletpb/atelet.proto", } const ( @@ -823,5 +823,5 @@ var Atelet_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "atelet.proto", + Metadata: "internal/proto/ateletpb/atelet.proto", } diff --git a/internal/proto/ateworkerpb/ateworker.pb.go b/internal/proto/ateworkerpb/ateworker.pb.go index 66c5162b32..377afde916 100644 --- a/internal/proto/ateworkerpb/ateworker.pb.go +++ b/internal/proto/ateworkerpb/ateworker.pb.go @@ -16,7 +16,7 @@ // versions: // protoc-gen-go v1.36.11-devel // protoc v4.25.3 -// source: ateworker.proto +// source: internal/proto/ateworkerpb/ateworker.proto package ateworkerpb @@ -80,11 +80,11 @@ func (x SnapshotFidelity) String() string { } func (SnapshotFidelity) Descriptor() protoreflect.EnumDescriptor { - return file_ateworker_proto_enumTypes[0].Descriptor() + return file_internal_proto_ateworkerpb_ateworker_proto_enumTypes[0].Descriptor() } func (SnapshotFidelity) Type() protoreflect.EnumType { - return &file_ateworker_proto_enumTypes[0] + return &file_internal_proto_ateworkerpb_ateworker_proto_enumTypes[0] } func (x SnapshotFidelity) Number() protoreflect.EnumNumber { @@ -93,7 +93,7 @@ func (x SnapshotFidelity) Number() protoreflect.EnumNumber { // Deprecated: Use SnapshotFidelity.Descriptor instead. func (SnapshotFidelity) EnumDescriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{0} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{0} } // StatsSource is how a sample's measurements were obtained. The two are not @@ -140,11 +140,11 @@ func (x StatsSource) String() string { } func (StatsSource) Descriptor() protoreflect.EnumDescriptor { - return file_ateworker_proto_enumTypes[1].Descriptor() + return file_internal_proto_ateworkerpb_ateworker_proto_enumTypes[1].Descriptor() } func (StatsSource) Type() protoreflect.EnumType { - return &file_ateworker_proto_enumTypes[1] + return &file_internal_proto_ateworkerpb_ateworker_proto_enumTypes[1] } func (x StatsSource) Number() protoreflect.EnumNumber { @@ -153,7 +153,7 @@ func (x StatsSource) Number() protoreflect.EnumNumber { // Deprecated: Use StatsSource.Descriptor instead. func (StatsSource) EnumDescriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{1} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{1} } // ActorDirs is the set of per-actor directories atelet prepares on the volume @@ -216,7 +216,7 @@ type ActorDirs struct { func (x *ActorDirs) Reset() { *x = ActorDirs{} - mi := &file_ateworker_proto_msgTypes[0] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -228,7 +228,7 @@ func (x *ActorDirs) String() string { func (*ActorDirs) ProtoMessage() {} func (x *ActorDirs) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[0] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -241,7 +241,7 @@ func (x *ActorDirs) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorDirs.ProtoReflect.Descriptor instead. func (*ActorDirs) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{0} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{0} } func (x *ActorDirs) GetRootDir() string { @@ -334,7 +334,7 @@ type TerminateWorkloadRequest struct { func (x *TerminateWorkloadRequest) Reset() { *x = TerminateWorkloadRequest{} - mi := &file_ateworker_proto_msgTypes[1] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -346,7 +346,7 @@ func (x *TerminateWorkloadRequest) String() string { func (*TerminateWorkloadRequest) ProtoMessage() {} func (x *TerminateWorkloadRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[1] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -359,7 +359,7 @@ func (x *TerminateWorkloadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use TerminateWorkloadRequest.ProtoReflect.Descriptor instead. func (*TerminateWorkloadRequest) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{1} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{1} } func (x *TerminateWorkloadRequest) GetAtespace() string { @@ -426,7 +426,7 @@ type TerminateWorkloadResponse struct { func (x *TerminateWorkloadResponse) Reset() { *x = TerminateWorkloadResponse{} - mi := &file_ateworker_proto_msgTypes[2] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -438,7 +438,7 @@ func (x *TerminateWorkloadResponse) String() string { func (*TerminateWorkloadResponse) ProtoMessage() {} func (x *TerminateWorkloadResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[2] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -451,7 +451,7 @@ func (x *TerminateWorkloadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use TerminateWorkloadResponse.ProtoReflect.Descriptor instead. func (*TerminateWorkloadResponse) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{2} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{2} } type RunWorkloadRequest struct { @@ -509,7 +509,7 @@ type RunWorkloadRequest struct { func (x *RunWorkloadRequest) Reset() { *x = RunWorkloadRequest{} - mi := &file_ateworker_proto_msgTypes[3] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -521,7 +521,7 @@ func (x *RunWorkloadRequest) String() string { func (*RunWorkloadRequest) ProtoMessage() {} func (x *RunWorkloadRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[3] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -534,7 +534,7 @@ func (x *RunWorkloadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RunWorkloadRequest.ProtoReflect.Descriptor instead. func (*RunWorkloadRequest) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{3} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{3} } func (x *RunWorkloadRequest) GetAtespace() string { @@ -630,7 +630,7 @@ type EgressGateway struct { func (x *EgressGateway) Reset() { *x = EgressGateway{} - mi := &file_ateworker_proto_msgTypes[4] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -642,7 +642,7 @@ func (x *EgressGateway) String() string { func (*EgressGateway) ProtoMessage() {} func (x *EgressGateway) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[4] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -655,7 +655,7 @@ func (x *EgressGateway) ProtoReflect() protoreflect.Message { // Deprecated: Use EgressGateway.ProtoReflect.Descriptor instead. func (*EgressGateway) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{4} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{4} } func (x *EgressGateway) GetAddress() string { @@ -682,7 +682,7 @@ type WorkloadSpec struct { func (x *WorkloadSpec) Reset() { *x = WorkloadSpec{} - mi := &file_ateworker_proto_msgTypes[5] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -694,7 +694,7 @@ func (x *WorkloadSpec) String() string { func (*WorkloadSpec) ProtoMessage() {} func (x *WorkloadSpec) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[5] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -707,7 +707,7 @@ func (x *WorkloadSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkloadSpec.ProtoReflect.Descriptor instead. func (*WorkloadSpec) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{5} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{5} } func (x *WorkloadSpec) GetContainers() []*Container { @@ -779,7 +779,7 @@ type Container struct { func (x *Container) Reset() { *x = Container{} - mi := &file_ateworker_proto_msgTypes[6] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -791,7 +791,7 @@ func (x *Container) String() string { func (*Container) ProtoMessage() {} func (x *Container) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[6] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -804,7 +804,7 @@ func (x *Container) ProtoReflect() protoreflect.Message { // Deprecated: Use Container.ProtoReflect.Descriptor instead. func (*Container) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{6} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{6} } func (x *Container) GetName() string { @@ -877,7 +877,7 @@ type ContainerSpec struct { func (x *ContainerSpec) Reset() { *x = ContainerSpec{} - mi := &file_ateworker_proto_msgTypes[7] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -889,7 +889,7 @@ func (x *ContainerSpec) String() string { func (*ContainerSpec) ProtoMessage() {} func (x *ContainerSpec) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[7] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -902,7 +902,7 @@ func (x *ContainerSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerSpec.ProtoReflect.Descriptor instead. func (*ContainerSpec) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{7} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{7} } func (x *ContainerSpec) GetArgs() []string { @@ -946,7 +946,7 @@ type ResourceRequirements struct { func (x *ResourceRequirements) Reset() { *x = ResourceRequirements{} - mi := &file_ateworker_proto_msgTypes[8] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -958,7 +958,7 @@ func (x *ResourceRequirements) String() string { func (*ResourceRequirements) ProtoMessage() {} func (x *ResourceRequirements) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[8] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -971,7 +971,7 @@ func (x *ResourceRequirements) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceRequirements.ProtoReflect.Descriptor instead. func (*ResourceRequirements) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{8} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{8} } func (x *ResourceRequirements) GetLimits() *Resources { @@ -1001,7 +1001,7 @@ type Resources struct { func (x *Resources) Reset() { *x = Resources{} - mi := &file_ateworker_proto_msgTypes[9] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1013,7 +1013,7 @@ func (x *Resources) String() string { func (*Resources) ProtoMessage() {} func (x *Resources) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[9] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1026,7 +1026,7 @@ func (x *Resources) ProtoReflect() protoreflect.Message { // Deprecated: Use Resources.ProtoReflect.Descriptor instead. func (*Resources) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{9} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{9} } func (x *Resources) GetCpuMillicores() int64 { @@ -1065,7 +1065,7 @@ type VolumeMount struct { func (x *VolumeMount) Reset() { *x = VolumeMount{} - mi := &file_ateworker_proto_msgTypes[10] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1077,7 +1077,7 @@ func (x *VolumeMount) String() string { func (*VolumeMount) ProtoMessage() {} func (x *VolumeMount) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[10] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1090,7 +1090,7 @@ func (x *VolumeMount) ProtoReflect() protoreflect.Message { // Deprecated: Use VolumeMount.ProtoReflect.Descriptor instead. func (*VolumeMount) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{10} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{10} } func (x *VolumeMount) GetName() string { @@ -1125,7 +1125,7 @@ type WakeupProbe struct { func (x *WakeupProbe) Reset() { *x = WakeupProbe{} - mi := &file_ateworker_proto_msgTypes[11] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1137,7 +1137,7 @@ func (x *WakeupProbe) String() string { func (*WakeupProbe) ProtoMessage() {} func (x *WakeupProbe) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[11] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1150,7 +1150,7 @@ func (x *WakeupProbe) ProtoReflect() protoreflect.Message { // Deprecated: Use WakeupProbe.ProtoReflect.Descriptor instead. func (*WakeupProbe) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{11} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{11} } func (x *WakeupProbe) GetHttpGet() *HttpGetAction { @@ -1188,7 +1188,7 @@ type HttpGetAction struct { func (x *HttpGetAction) Reset() { *x = HttpGetAction{} - mi := &file_ateworker_proto_msgTypes[12] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1200,7 +1200,7 @@ func (x *HttpGetAction) String() string { func (*HttpGetAction) ProtoMessage() {} func (x *HttpGetAction) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[12] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1213,7 +1213,7 @@ func (x *HttpGetAction) ProtoReflect() protoreflect.Message { // Deprecated: Use HttpGetAction.ProtoReflect.Descriptor instead. func (*HttpGetAction) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{12} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{12} } func (x *HttpGetAction) GetPath() string { @@ -1240,7 +1240,7 @@ type RunWorkloadResponse struct { func (x *RunWorkloadResponse) Reset() { *x = RunWorkloadResponse{} - mi := &file_ateworker_proto_msgTypes[13] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1252,7 +1252,7 @@ func (x *RunWorkloadResponse) String() string { func (*RunWorkloadResponse) ProtoMessage() {} func (x *RunWorkloadResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[13] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1265,7 +1265,7 @@ func (x *RunWorkloadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RunWorkloadResponse.ProtoReflect.Descriptor instead. func (*RunWorkloadResponse) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{13} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{13} } func (x *RunWorkloadResponse) GetWorkerEpoch() int64 { @@ -1313,7 +1313,7 @@ type CheckpointWorkloadRequest struct { func (x *CheckpointWorkloadRequest) Reset() { *x = CheckpointWorkloadRequest{} - mi := &file_ateworker_proto_msgTypes[14] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1325,7 +1325,7 @@ func (x *CheckpointWorkloadRequest) String() string { func (*CheckpointWorkloadRequest) ProtoMessage() {} func (x *CheckpointWorkloadRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[14] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1338,7 +1338,7 @@ func (x *CheckpointWorkloadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckpointWorkloadRequest.ProtoReflect.Descriptor instead. func (*CheckpointWorkloadRequest) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{14} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{14} } func (x *CheckpointWorkloadRequest) GetAtespace() string { @@ -1419,7 +1419,7 @@ type CheckpointWorkloadResponse struct { func (x *CheckpointWorkloadResponse) Reset() { *x = CheckpointWorkloadResponse{} - mi := &file_ateworker_proto_msgTypes[15] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1431,7 +1431,7 @@ func (x *CheckpointWorkloadResponse) String() string { func (*CheckpointWorkloadResponse) ProtoMessage() {} func (x *CheckpointWorkloadResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[15] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1444,7 +1444,7 @@ func (x *CheckpointWorkloadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckpointWorkloadResponse.ProtoReflect.Descriptor instead. func (*CheckpointWorkloadResponse) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{15} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{15} } func (x *CheckpointWorkloadResponse) GetSnapshotFiles() []string { @@ -1524,7 +1524,7 @@ type RestoreWorkloadRequest struct { func (x *RestoreWorkloadRequest) Reset() { *x = RestoreWorkloadRequest{} - mi := &file_ateworker_proto_msgTypes[16] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1536,7 +1536,7 @@ func (x *RestoreWorkloadRequest) String() string { func (*RestoreWorkloadRequest) ProtoMessage() {} func (x *RestoreWorkloadRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[16] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1549,7 +1549,7 @@ func (x *RestoreWorkloadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreWorkloadRequest.ProtoReflect.Descriptor instead. func (*RestoreWorkloadRequest) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{16} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{16} } func (x *RestoreWorkloadRequest) GetAtespace() string { @@ -1653,7 +1653,7 @@ type RestoreWorkloadResponse struct { func (x *RestoreWorkloadResponse) Reset() { *x = RestoreWorkloadResponse{} - mi := &file_ateworker_proto_msgTypes[17] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1665,7 +1665,7 @@ func (x *RestoreWorkloadResponse) String() string { func (*RestoreWorkloadResponse) ProtoMessage() {} func (x *RestoreWorkloadResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[17] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1678,7 +1678,7 @@ func (x *RestoreWorkloadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreWorkloadResponse.ProtoReflect.Descriptor instead. func (*RestoreWorkloadResponse) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{17} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{17} } func (x *RestoreWorkloadResponse) GetWorkerEpoch() int64 { @@ -1704,7 +1704,7 @@ type GetWorkloadStatsRequest struct { func (x *GetWorkloadStatsRequest) Reset() { *x = GetWorkloadStatsRequest{} - mi := &file_ateworker_proto_msgTypes[18] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1716,7 +1716,7 @@ func (x *GetWorkloadStatsRequest) String() string { func (*GetWorkloadStatsRequest) ProtoMessage() {} func (x *GetWorkloadStatsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[18] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1729,7 +1729,7 @@ func (x *GetWorkloadStatsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkloadStatsRequest.ProtoReflect.Descriptor instead. func (*GetWorkloadStatsRequest) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{18} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{18} } func (x *GetWorkloadStatsRequest) GetActorUid() string { @@ -1758,7 +1758,7 @@ type WorkloadStatsSample struct { ActorTemplateAtespace string `protobuf:"bytes,4,opt,name=actor_template_atespace,json=actorTemplateAtespace,proto3" json:"actor_template_atespace,omitempty"` ActorTemplateName string `protobuf:"bytes,5,opt,name=actor_template_name,json=actorTemplateName,proto3" json:"actor_template_name,omitempty"` // The sandbox runtime family that produced this sample, in the - // ate.dev/v1alpha1 SandboxClass form: "gvisor" (cmd/ateworker-gvisor) or + // ate.dev/v1 SandboxClass form: "gvisor" (cmd/ateworker-gvisor) or // "microvm" (cmd/ateworker-microvm). A worker binary only ever reports its own. SandboxClass string `protobuf:"bytes,6,opt,name=sandbox_class,json=sandboxClass,proto3" json:"sandbox_class,omitempty"` // How the measurements below were obtained. @@ -1794,7 +1794,7 @@ type WorkloadStatsSample struct { func (x *WorkloadStatsSample) Reset() { *x = WorkloadStatsSample{} - mi := &file_ateworker_proto_msgTypes[19] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1806,7 +1806,7 @@ func (x *WorkloadStatsSample) String() string { func (*WorkloadStatsSample) ProtoMessage() {} func (x *WorkloadStatsSample) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[19] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1819,7 +1819,7 @@ func (x *WorkloadStatsSample) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkloadStatsSample.ProtoReflect.Descriptor instead. func (*WorkloadStatsSample) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{19} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{19} } func (x *WorkloadStatsSample) GetAtespace() string { @@ -1922,7 +1922,7 @@ type GetWorkloadStatsResponse struct { func (x *GetWorkloadStatsResponse) Reset() { *x = GetWorkloadStatsResponse{} - mi := &file_ateworker_proto_msgTypes[20] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1934,7 +1934,7 @@ func (x *GetWorkloadStatsResponse) String() string { func (*GetWorkloadStatsResponse) ProtoMessage() {} func (x *GetWorkloadStatsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[20] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1947,7 +1947,7 @@ func (x *GetWorkloadStatsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkloadStatsResponse.ProtoReflect.Descriptor instead. func (*GetWorkloadStatsResponse) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{20} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{20} } func (x *GetWorkloadStatsResponse) GetSample() *WorkloadStatsSample { @@ -1965,7 +1965,7 @@ type GetActiveWorkloadStatsRequest struct { func (x *GetActiveWorkloadStatsRequest) Reset() { *x = GetActiveWorkloadStatsRequest{} - mi := &file_ateworker_proto_msgTypes[21] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1977,7 +1977,7 @@ func (x *GetActiveWorkloadStatsRequest) String() string { func (*GetActiveWorkloadStatsRequest) ProtoMessage() {} func (x *GetActiveWorkloadStatsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[21] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1990,7 +1990,7 @@ func (x *GetActiveWorkloadStatsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActiveWorkloadStatsRequest.ProtoReflect.Descriptor instead. func (*GetActiveWorkloadStatsRequest) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{21} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{21} } type GetActiveWorkloadStatsResponse struct { @@ -2010,7 +2010,7 @@ type GetActiveWorkloadStatsResponse struct { func (x *GetActiveWorkloadStatsResponse) Reset() { *x = GetActiveWorkloadStatsResponse{} - mi := &file_ateworker_proto_msgTypes[22] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2022,7 +2022,7 @@ func (x *GetActiveWorkloadStatsResponse) String() string { func (*GetActiveWorkloadStatsResponse) ProtoMessage() {} func (x *GetActiveWorkloadStatsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateworker_proto_msgTypes[22] + mi := &file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2035,7 +2035,7 @@ func (x *GetActiveWorkloadStatsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActiveWorkloadStatsResponse.ProtoReflect.Descriptor instead. func (*GetActiveWorkloadStatsResponse) Descriptor() ([]byte, []int) { - return file_ateworker_proto_rawDescGZIP(), []int{22} + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP(), []int{22} } func (x *GetActiveWorkloadStatsResponse) GetSamples() []*WorkloadStatsSample { @@ -2045,11 +2045,11 @@ func (x *GetActiveWorkloadStatsResponse) GetSamples() []*WorkloadStatsSample { return nil } -var File_ateworker_proto protoreflect.FileDescriptor +var File_internal_proto_ateworkerpb_ateworker_proto protoreflect.FileDescriptor -const file_ateworker_proto_rawDesc = "" + +const file_internal_proto_ateworkerpb_ateworker_proto_rawDesc = "" + "\n" + - "\x0fateworker.proto\x12\tateworker\"\x81\x03\n" + + "*internal/proto/ateworkerpb/ateworker.proto\x12\tateworker\"\x81\x03\n" + "\tActorDirs\x12\x19\n" + "\broot_dir\x18\x01 \x01(\tR\arootDir\x12$\n" + "\x0eoci_bundle_dir\x18\x02 \x01(\tR\fociBundleDir\x12%\n" + @@ -2210,20 +2210,20 @@ const file_ateworker_proto_rawDesc = "" + "\x11TerminateWorkload\x12#.ateworker.TerminateWorkloadRequest\x1a$.ateworker.TerminateWorkloadResponse\"\x00B1Z/go.ate.dev/substrate/internal/proto/ateworkerpbb\x06proto3" var ( - file_ateworker_proto_rawDescOnce sync.Once - file_ateworker_proto_rawDescData []byte + file_internal_proto_ateworkerpb_ateworker_proto_rawDescOnce sync.Once + file_internal_proto_ateworkerpb_ateworker_proto_rawDescData []byte ) -func file_ateworker_proto_rawDescGZIP() []byte { - file_ateworker_proto_rawDescOnce.Do(func() { - file_ateworker_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ateworker_proto_rawDesc), len(file_ateworker_proto_rawDesc))) +func file_internal_proto_ateworkerpb_ateworker_proto_rawDescGZIP() []byte { + file_internal_proto_ateworkerpb_ateworker_proto_rawDescOnce.Do(func() { + file_internal_proto_ateworkerpb_ateworker_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_internal_proto_ateworkerpb_ateworker_proto_rawDesc), len(file_internal_proto_ateworkerpb_ateworker_proto_rawDesc))) }) - return file_ateworker_proto_rawDescData + return file_internal_proto_ateworkerpb_ateworker_proto_rawDescData } -var file_ateworker_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_ateworker_proto_msgTypes = make([]protoimpl.MessageInfo, 25) -var file_ateworker_proto_goTypes = []any{ +var file_internal_proto_ateworkerpb_ateworker_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_internal_proto_ateworkerpb_ateworker_proto_msgTypes = make([]protoimpl.MessageInfo, 25) +var file_internal_proto_ateworkerpb_ateworker_proto_goTypes = []any{ (SnapshotFidelity)(0), // 0: ateworker.SnapshotFidelity (StatsSource)(0), // 1: ateworker.StatsSource (*ActorDirs)(nil), // 2: ateworker.ActorDirs @@ -2252,7 +2252,7 @@ var file_ateworker_proto_goTypes = []any{ nil, // 25: ateworker.RunWorkloadRequest.RuntimeAssetPathsEntry nil, // 26: ateworker.RestoreWorkloadRequest.RuntimeAssetPathsEntry } -var file_ateworker_proto_depIdxs = []int32{ +var file_internal_proto_ateworkerpb_ateworker_proto_depIdxs = []int32{ 7, // 0: ateworker.TerminateWorkloadRequest.spec:type_name -> ateworker.WorkloadSpec 2, // 1: ateworker.TerminateWorkloadRequest.actor_dirs:type_name -> ateworker.ActorDirs 7, // 2: ateworker.RunWorkloadRequest.spec:type_name -> ateworker.WorkloadSpec @@ -2301,29 +2301,29 @@ var file_ateworker_proto_depIdxs = []int32{ 0, // [0:29] is the sub-list for field type_name } -func init() { file_ateworker_proto_init() } -func file_ateworker_proto_init() { - if File_ateworker_proto != nil { +func init() { file_internal_proto_ateworkerpb_ateworker_proto_init() } +func file_internal_proto_ateworkerpb_ateworker_proto_init() { + if File_internal_proto_ateworkerpb_ateworker_proto != nil { return } - file_ateworker_proto_msgTypes[3].OneofWrappers = []any{} - file_ateworker_proto_msgTypes[16].OneofWrappers = []any{} + file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[3].OneofWrappers = []any{} + file_internal_proto_ateworkerpb_ateworker_proto_msgTypes[16].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_ateworker_proto_rawDesc), len(file_ateworker_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_internal_proto_ateworkerpb_ateworker_proto_rawDesc), len(file_internal_proto_ateworkerpb_ateworker_proto_rawDesc)), NumEnums: 2, NumMessages: 25, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_ateworker_proto_goTypes, - DependencyIndexes: file_ateworker_proto_depIdxs, - EnumInfos: file_ateworker_proto_enumTypes, - MessageInfos: file_ateworker_proto_msgTypes, + GoTypes: file_internal_proto_ateworkerpb_ateworker_proto_goTypes, + DependencyIndexes: file_internal_proto_ateworkerpb_ateworker_proto_depIdxs, + EnumInfos: file_internal_proto_ateworkerpb_ateworker_proto_enumTypes, + MessageInfos: file_internal_proto_ateworkerpb_ateworker_proto_msgTypes, }.Build() - File_ateworker_proto = out.File - file_ateworker_proto_goTypes = nil - file_ateworker_proto_depIdxs = nil + File_internal_proto_ateworkerpb_ateworker_proto = out.File + file_internal_proto_ateworkerpb_ateworker_proto_goTypes = nil + file_internal_proto_ateworkerpb_ateworker_proto_depIdxs = nil } diff --git a/internal/proto/ateworkerpb/ateworker.proto b/internal/proto/ateworkerpb/ateworker.proto index cc868f6223..3477738279 100644 --- a/internal/proto/ateworkerpb/ateworker.proto +++ b/internal/proto/ateworkerpb/ateworker.proto @@ -609,7 +609,7 @@ message WorkloadStatsSample { string actor_template_name = 5; // The sandbox runtime family that produced this sample, in the - // ate.dev/v1alpha1 SandboxClass form: "gvisor" (cmd/ateworker-gvisor) or + // ate.dev/v1 SandboxClass form: "gvisor" (cmd/ateworker-gvisor) or // "microvm" (cmd/ateworker-microvm). A worker binary only ever reports its own. string sandbox_class = 6; diff --git a/internal/proto/ateworkerpb/ateworker_grpc.pb.go b/internal/proto/ateworkerpb/ateworker_grpc.pb.go index 2c4854e5a4..a32e2d794b 100644 --- a/internal/proto/ateworkerpb/ateworker_grpc.pb.go +++ b/internal/proto/ateworkerpb/ateworker_grpc.pb.go @@ -16,7 +16,7 @@ // versions: // - protoc-gen-go-grpc v1.6.2 // - protoc v4.25.3 -// source: ateworker.proto +// source: internal/proto/ateworkerpb/ateworker.proto package ateworkerpb @@ -469,5 +469,5 @@ var Worker_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "ateworker.proto", + Metadata: "internal/proto/ateworkerpb/ateworker.proto", } diff --git a/internal/proto/glutton/glutton.pb.go b/internal/proto/glutton/glutton.pb.go index 490941706a..93fa8ca566 100644 --- a/internal/proto/glutton/glutton.pb.go +++ b/internal/proto/glutton/glutton.pb.go @@ -16,7 +16,7 @@ // versions: // protoc-gen-go v1.36.11-devel // protoc v4.25.3 -// source: glutton.proto +// source: internal/proto/glutton/glutton.proto package glutton @@ -73,11 +73,11 @@ func (x WriteMode) String() string { } func (WriteMode) Descriptor() protoreflect.EnumDescriptor { - return file_glutton_proto_enumTypes[0].Descriptor() + return file_internal_proto_glutton_glutton_proto_enumTypes[0].Descriptor() } func (WriteMode) Type() protoreflect.EnumType { - return &file_glutton_proto_enumTypes[0] + return &file_internal_proto_glutton_glutton_proto_enumTypes[0] } func (x WriteMode) Number() protoreflect.EnumNumber { @@ -86,7 +86,7 @@ func (x WriteMode) Number() protoreflect.EnumNumber { // Deprecated: Use WriteMode.Descriptor instead. func (WriteMode) EnumDescriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{0} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{0} } // ReadMode selects how much of the file ReadDisk sends back. @@ -123,11 +123,11 @@ func (x ReadMode) String() string { } func (ReadMode) Descriptor() protoreflect.EnumDescriptor { - return file_glutton_proto_enumTypes[1].Descriptor() + return file_internal_proto_glutton_glutton_proto_enumTypes[1].Descriptor() } func (ReadMode) Type() protoreflect.EnumType { - return &file_glutton_proto_enumTypes[1] + return &file_internal_proto_glutton_glutton_proto_enumTypes[1] } func (x ReadMode) Number() protoreflect.EnumNumber { @@ -136,7 +136,7 @@ func (x ReadMode) Number() protoreflect.EnumNumber { // Deprecated: Use ReadMode.Descriptor instead. func (ReadMode) EnumDescriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{1} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{1} } type WriteRAMRequest struct { @@ -152,7 +152,7 @@ type WriteRAMRequest struct { func (x *WriteRAMRequest) Reset() { *x = WriteRAMRequest{} - mi := &file_glutton_proto_msgTypes[0] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -164,7 +164,7 @@ func (x *WriteRAMRequest) String() string { func (*WriteRAMRequest) ProtoMessage() {} func (x *WriteRAMRequest) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[0] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -177,7 +177,7 @@ func (x *WriteRAMRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WriteRAMRequest.ProtoReflect.Descriptor instead. func (*WriteRAMRequest) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{0} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{0} } func (x *WriteRAMRequest) GetKey() string { @@ -209,7 +209,7 @@ type WriteRAMResponse struct { func (x *WriteRAMResponse) Reset() { *x = WriteRAMResponse{} - mi := &file_glutton_proto_msgTypes[1] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -221,7 +221,7 @@ func (x *WriteRAMResponse) String() string { func (*WriteRAMResponse) ProtoMessage() {} func (x *WriteRAMResponse) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[1] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -234,7 +234,7 @@ func (x *WriteRAMResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WriteRAMResponse.ProtoReflect.Descriptor instead. func (*WriteRAMResponse) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{1} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{1} } type ReadRAMRequest struct { @@ -250,7 +250,7 @@ type ReadRAMRequest struct { func (x *ReadRAMRequest) Reset() { *x = ReadRAMRequest{} - mi := &file_glutton_proto_msgTypes[2] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -262,7 +262,7 @@ func (x *ReadRAMRequest) String() string { func (*ReadRAMRequest) ProtoMessage() {} func (x *ReadRAMRequest) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[2] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -275,7 +275,7 @@ func (x *ReadRAMRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReadRAMRequest.ProtoReflect.Descriptor instead. func (*ReadRAMRequest) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{2} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{2} } func (x *ReadRAMRequest) GetKey() string { @@ -304,7 +304,7 @@ type ReadRAMResponse struct { func (x *ReadRAMResponse) Reset() { *x = ReadRAMResponse{} - mi := &file_glutton_proto_msgTypes[3] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -316,7 +316,7 @@ func (x *ReadRAMResponse) String() string { func (*ReadRAMResponse) ProtoMessage() {} func (x *ReadRAMResponse) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[3] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -329,7 +329,7 @@ func (x *ReadRAMResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReadRAMResponse.ProtoReflect.Descriptor instead. func (*ReadRAMResponse) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{3} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{3} } func (x *ReadRAMResponse) GetSize() int64 { @@ -359,7 +359,7 @@ type WriteDiskRequest struct { func (x *WriteDiskRequest) Reset() { *x = WriteDiskRequest{} - mi := &file_glutton_proto_msgTypes[4] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -371,7 +371,7 @@ func (x *WriteDiskRequest) String() string { func (*WriteDiskRequest) ProtoMessage() {} func (x *WriteDiskRequest) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[4] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -384,7 +384,7 @@ func (x *WriteDiskRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WriteDiskRequest.ProtoReflect.Descriptor instead. func (*WriteDiskRequest) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{4} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{4} } func (x *WriteDiskRequest) GetKey() string { @@ -420,7 +420,7 @@ type WriteDiskResponse struct { func (x *WriteDiskResponse) Reset() { *x = WriteDiskResponse{} - mi := &file_glutton_proto_msgTypes[5] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -432,7 +432,7 @@ func (x *WriteDiskResponse) String() string { func (*WriteDiskResponse) ProtoMessage() {} func (x *WriteDiskResponse) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[5] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -445,7 +445,7 @@ func (x *WriteDiskResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WriteDiskResponse.ProtoReflect.Descriptor instead. func (*WriteDiskResponse) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{5} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{5} } func (x *WriteDiskResponse) GetSize() int64 { @@ -473,7 +473,7 @@ type ReadDiskRequest struct { func (x *ReadDiskRequest) Reset() { *x = ReadDiskRequest{} - mi := &file_glutton_proto_msgTypes[6] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -485,7 +485,7 @@ func (x *ReadDiskRequest) String() string { func (*ReadDiskRequest) ProtoMessage() {} func (x *ReadDiskRequest) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[6] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -498,7 +498,7 @@ func (x *ReadDiskRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReadDiskRequest.ProtoReflect.Descriptor instead. func (*ReadDiskRequest) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{6} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{6} } func (x *ReadDiskRequest) GetKey() string { @@ -529,7 +529,7 @@ type ReadDiskResponse struct { func (x *ReadDiskResponse) Reset() { *x = ReadDiskResponse{} - mi := &file_glutton_proto_msgTypes[7] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -541,7 +541,7 @@ func (x *ReadDiskResponse) String() string { func (*ReadDiskResponse) ProtoMessage() {} func (x *ReadDiskResponse) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[7] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -554,7 +554,7 @@ func (x *ReadDiskResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReadDiskResponse.ProtoReflect.Descriptor instead. func (*ReadDiskResponse) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{7} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{7} } func (x *ReadDiskResponse) GetSize() int64 { @@ -588,7 +588,7 @@ type OpenFDRequest struct { func (x *OpenFDRequest) Reset() { *x = OpenFDRequest{} - mi := &file_glutton_proto_msgTypes[8] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -600,7 +600,7 @@ func (x *OpenFDRequest) String() string { func (*OpenFDRequest) ProtoMessage() {} func (x *OpenFDRequest) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[8] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -613,7 +613,7 @@ func (x *OpenFDRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use OpenFDRequest.ProtoReflect.Descriptor instead. func (*OpenFDRequest) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{8} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{8} } func (x *OpenFDRequest) GetCount() int32 { @@ -631,7 +631,7 @@ type OpenFDResponse struct { func (x *OpenFDResponse) Reset() { *x = OpenFDResponse{} - mi := &file_glutton_proto_msgTypes[9] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -643,7 +643,7 @@ func (x *OpenFDResponse) String() string { func (*OpenFDResponse) ProtoMessage() {} func (x *OpenFDResponse) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[9] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -656,7 +656,7 @@ func (x *OpenFDResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use OpenFDResponse.ProtoReflect.Descriptor instead. func (*OpenFDResponse) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{9} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{9} } type PingRequest struct { @@ -669,7 +669,7 @@ type PingRequest struct { func (x *PingRequest) Reset() { *x = PingRequest{} - mi := &file_glutton_proto_msgTypes[10] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -681,7 +681,7 @@ func (x *PingRequest) String() string { func (*PingRequest) ProtoMessage() {} func (x *PingRequest) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[10] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -694,7 +694,7 @@ func (x *PingRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PingRequest.ProtoReflect.Descriptor instead. func (*PingRequest) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{10} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{10} } func (x *PingRequest) GetMessage() string { @@ -714,7 +714,7 @@ type PingResponse struct { func (x *PingResponse) Reset() { *x = PingResponse{} - mi := &file_glutton_proto_msgTypes[11] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -726,7 +726,7 @@ func (x *PingResponse) String() string { func (*PingResponse) ProtoMessage() {} func (x *PingResponse) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[11] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -739,7 +739,7 @@ func (x *PingResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PingResponse.ProtoReflect.Descriptor instead. func (*PingResponse) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{11} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{11} } func (x *PingResponse) GetMessage() string { @@ -758,7 +758,7 @@ type GossipRequest struct { func (x *GossipRequest) Reset() { *x = GossipRequest{} - mi := &file_glutton_proto_msgTypes[12] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -770,7 +770,7 @@ func (x *GossipRequest) String() string { func (*GossipRequest) ProtoMessage() {} func (x *GossipRequest) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[12] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -783,7 +783,7 @@ func (x *GossipRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GossipRequest.ProtoReflect.Descriptor instead. func (*GossipRequest) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{12} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{12} } func (x *GossipRequest) GetPeers() []*Peer { @@ -801,7 +801,7 @@ type GossipResponse struct { func (x *GossipResponse) Reset() { *x = GossipResponse{} - mi := &file_glutton_proto_msgTypes[13] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -813,7 +813,7 @@ func (x *GossipResponse) String() string { func (*GossipResponse) ProtoMessage() {} func (x *GossipResponse) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[13] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -826,7 +826,7 @@ func (x *GossipResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GossipResponse.ProtoReflect.Descriptor instead. func (*GossipResponse) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{13} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{13} } type Peer struct { @@ -839,7 +839,7 @@ type Peer struct { func (x *Peer) Reset() { *x = Peer{} - mi := &file_glutton_proto_msgTypes[14] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -851,7 +851,7 @@ func (x *Peer) String() string { func (*Peer) ProtoMessage() {} func (x *Peer) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[14] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -864,7 +864,7 @@ func (x *Peer) ProtoReflect() protoreflect.Message { // Deprecated: Use Peer.ProtoReflect.Descriptor instead. func (*Peer) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{14} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{14} } func (x *Peer) GetHost() string { @@ -893,7 +893,7 @@ type BurnCPURequest struct { func (x *BurnCPURequest) Reset() { *x = BurnCPURequest{} - mi := &file_glutton_proto_msgTypes[15] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -905,7 +905,7 @@ func (x *BurnCPURequest) String() string { func (*BurnCPURequest) ProtoMessage() {} func (x *BurnCPURequest) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[15] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -918,7 +918,7 @@ func (x *BurnCPURequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BurnCPURequest.ProtoReflect.Descriptor instead. func (*BurnCPURequest) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{15} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{15} } func (x *BurnCPURequest) GetDurationMs() int64 { @@ -946,7 +946,7 @@ type BurnCPUResponse struct { func (x *BurnCPUResponse) Reset() { *x = BurnCPUResponse{} - mi := &file_glutton_proto_msgTypes[16] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -958,7 +958,7 @@ func (x *BurnCPUResponse) String() string { func (*BurnCPUResponse) ProtoMessage() {} func (x *BurnCPUResponse) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[16] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -971,7 +971,7 @@ func (x *BurnCPUResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BurnCPUResponse.ProtoReflect.Descriptor instead. func (*BurnCPUResponse) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{16} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{16} } func (x *BurnCPUResponse) GetIterations() int64 { @@ -995,7 +995,7 @@ type IngestRequest struct { func (x *IngestRequest) Reset() { *x = IngestRequest{} - mi := &file_glutton_proto_msgTypes[17] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1007,7 +1007,7 @@ func (x *IngestRequest) String() string { func (*IngestRequest) ProtoMessage() {} func (x *IngestRequest) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[17] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1020,7 +1020,7 @@ func (x *IngestRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use IngestRequest.ProtoReflect.Descriptor instead. func (*IngestRequest) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{17} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{17} } func (x *IngestRequest) GetKey() string { @@ -1056,7 +1056,7 @@ type IngestResponse struct { func (x *IngestResponse) Reset() { *x = IngestResponse{} - mi := &file_glutton_proto_msgTypes[18] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1068,7 +1068,7 @@ func (x *IngestResponse) String() string { func (*IngestResponse) ProtoMessage() {} func (x *IngestResponse) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[18] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1081,7 +1081,7 @@ func (x *IngestResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use IngestResponse.ProtoReflect.Descriptor instead. func (*IngestResponse) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{18} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{18} } func (x *IngestResponse) GetSize() int64 { @@ -1120,7 +1120,7 @@ type UseCPURequest struct { func (x *UseCPURequest) Reset() { *x = UseCPURequest{} - mi := &file_glutton_proto_msgTypes[19] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1132,7 +1132,7 @@ func (x *UseCPURequest) String() string { func (*UseCPURequest) ProtoMessage() {} func (x *UseCPURequest) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[19] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1145,7 +1145,7 @@ func (x *UseCPURequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UseCPURequest.ProtoReflect.Descriptor instead. func (*UseCPURequest) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{19} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{19} } func (x *UseCPURequest) GetNumCores() int32 { @@ -1187,7 +1187,7 @@ type UseCPUResponse struct { func (x *UseCPUResponse) Reset() { *x = UseCPUResponse{} - mi := &file_glutton_proto_msgTypes[20] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1199,7 +1199,7 @@ func (x *UseCPUResponse) String() string { func (*UseCPUResponse) ProtoMessage() {} func (x *UseCPUResponse) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[20] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1212,7 +1212,7 @@ func (x *UseCPUResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UseCPUResponse.ProtoReflect.Descriptor instead. func (*UseCPUResponse) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{20} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{20} } func (x *UseCPUResponse) GetNumCores() int32 { @@ -1241,7 +1241,7 @@ type Block struct { func (x *Block) Reset() { *x = Block{} - mi := &file_glutton_proto_msgTypes[21] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1253,7 +1253,7 @@ func (x *Block) String() string { func (*Block) ProtoMessage() {} func (x *Block) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[21] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1266,7 +1266,7 @@ func (x *Block) ProtoReflect() protoreflect.Message { // Deprecated: Use Block.ProtoReflect.Descriptor instead. func (*Block) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{21} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{21} } func (x *Block) GetSteps() []*Step { @@ -1297,7 +1297,7 @@ type Step struct { func (x *Step) Reset() { *x = Step{} - mi := &file_glutton_proto_msgTypes[22] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1309,7 +1309,7 @@ func (x *Step) String() string { func (*Step) ProtoMessage() {} func (x *Step) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[22] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1322,7 +1322,7 @@ func (x *Step) ProtoReflect() protoreflect.Message { // Deprecated: Use Step.ProtoReflect.Descriptor instead. func (*Step) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{22} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{22} } func (x *Step) GetKind() isStep_Kind { @@ -1380,7 +1380,7 @@ type Operation struct { func (x *Operation) Reset() { *x = Operation{} - mi := &file_glutton_proto_msgTypes[23] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1392,7 +1392,7 @@ func (x *Operation) String() string { func (*Operation) ProtoMessage() {} func (x *Operation) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[23] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1405,7 +1405,7 @@ func (x *Operation) ProtoReflect() protoreflect.Message { // Deprecated: Use Operation.ProtoReflect.Descriptor instead. func (*Operation) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{23} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{23} } func (x *Operation) GetRequests() []*Request { @@ -1436,7 +1436,7 @@ type Request struct { func (x *Request) Reset() { *x = Request{} - mi := &file_glutton_proto_msgTypes[24] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1448,7 +1448,7 @@ func (x *Request) String() string { func (*Request) ProtoMessage() {} func (x *Request) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[24] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1461,7 +1461,7 @@ func (x *Request) ProtoReflect() protoreflect.Message { // Deprecated: Use Request.ProtoReflect.Descriptor instead. func (*Request) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{24} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{24} } func (x *Request) GetKind() isRequest_Kind { @@ -1591,7 +1591,7 @@ type SleepRequest struct { func (x *SleepRequest) Reset() { *x = SleepRequest{} - mi := &file_glutton_proto_msgTypes[25] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1603,7 +1603,7 @@ func (x *SleepRequest) String() string { func (*SleepRequest) ProtoMessage() {} func (x *SleepRequest) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[25] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1616,7 +1616,7 @@ func (x *SleepRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SleepRequest.ProtoReflect.Descriptor instead. func (*SleepRequest) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{25} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{25} } func (x *SleepRequest) GetDurationMs() int64 { @@ -1635,7 +1635,7 @@ type RunScriptRequest struct { func (x *RunScriptRequest) Reset() { *x = RunScriptRequest{} - mi := &file_glutton_proto_msgTypes[26] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1647,7 +1647,7 @@ func (x *RunScriptRequest) String() string { func (*RunScriptRequest) ProtoMessage() {} func (x *RunScriptRequest) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[26] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1660,7 +1660,7 @@ func (x *RunScriptRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RunScriptRequest.ProtoReflect.Descriptor instead. func (*RunScriptRequest) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{26} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{26} } func (x *RunScriptRequest) GetScript() *Block { @@ -1680,7 +1680,7 @@ type RunScriptResponse struct { func (x *RunScriptResponse) Reset() { *x = RunScriptResponse{} - mi := &file_glutton_proto_msgTypes[27] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1692,7 +1692,7 @@ func (x *RunScriptResponse) String() string { func (*RunScriptResponse) ProtoMessage() {} func (x *RunScriptResponse) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[27] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1705,7 +1705,7 @@ func (x *RunScriptResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RunScriptResponse.ProtoReflect.Descriptor instead. func (*RunScriptResponse) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{27} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{27} } func (x *RunScriptResponse) GetResult() *StepResult { @@ -1730,7 +1730,7 @@ type StepResult struct { func (x *StepResult) Reset() { *x = StepResult{} - mi := &file_glutton_proto_msgTypes[28] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1742,7 +1742,7 @@ func (x *StepResult) String() string { func (*StepResult) ProtoMessage() {} func (x *StepResult) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[28] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1755,7 +1755,7 @@ func (x *StepResult) ProtoReflect() protoreflect.Message { // Deprecated: Use StepResult.ProtoReflect.Descriptor instead. func (*StepResult) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{28} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{28} } func (x *StepResult) GetStats() *Stats { @@ -1801,7 +1801,7 @@ type Stats struct { func (x *Stats) Reset() { *x = Stats{} - mi := &file_glutton_proto_msgTypes[29] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1813,7 +1813,7 @@ func (x *Stats) String() string { func (*Stats) ProtoMessage() {} func (x *Stats) ProtoReflect() protoreflect.Message { - mi := &file_glutton_proto_msgTypes[29] + mi := &file_internal_proto_glutton_glutton_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1826,7 +1826,7 @@ func (x *Stats) ProtoReflect() protoreflect.Message { // Deprecated: Use Stats.ProtoReflect.Descriptor instead. func (*Stats) Descriptor() ([]byte, []int) { - return file_glutton_proto_rawDescGZIP(), []int{29} + return file_internal_proto_glutton_glutton_proto_rawDescGZIP(), []int{29} } func (x *Stats) GetElapsedMs() int64 { @@ -1892,11 +1892,11 @@ func (x *Stats) GetSleptMs() int64 { return 0 } -var File_glutton_proto protoreflect.FileDescriptor +var File_internal_proto_glutton_glutton_proto protoreflect.FileDescriptor -const file_glutton_proto_rawDesc = "" + +const file_internal_proto_glutton_glutton_proto_rawDesc = "" + "\n" + - "\rglutton.proto\x12\aglutton\"j\n" + + "$internal/proto/glutton/glutton.proto\x12\aglutton\"j\n" + "\x0fWriteRAMRequest\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x12\n" + "\x04size\x18\x02 \x01(\tR\x04size\x121\n" + @@ -2023,20 +2023,20 @@ const file_glutton_proto_rawDesc = "" + "\tRunScript\x12\x19.glutton.RunScriptRequest\x1a\x1a.glutton.RunScriptResponse\"\x00B-Z+go.ate.dev/substrate/internal/proto/gluttonb\x06proto3" var ( - file_glutton_proto_rawDescOnce sync.Once - file_glutton_proto_rawDescData []byte + file_internal_proto_glutton_glutton_proto_rawDescOnce sync.Once + file_internal_proto_glutton_glutton_proto_rawDescData []byte ) -func file_glutton_proto_rawDescGZIP() []byte { - file_glutton_proto_rawDescOnce.Do(func() { - file_glutton_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_glutton_proto_rawDesc), len(file_glutton_proto_rawDesc))) +func file_internal_proto_glutton_glutton_proto_rawDescGZIP() []byte { + file_internal_proto_glutton_glutton_proto_rawDescOnce.Do(func() { + file_internal_proto_glutton_glutton_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_internal_proto_glutton_glutton_proto_rawDesc), len(file_internal_proto_glutton_glutton_proto_rawDesc))) }) - return file_glutton_proto_rawDescData + return file_internal_proto_glutton_glutton_proto_rawDescData } -var file_glutton_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_glutton_proto_msgTypes = make([]protoimpl.MessageInfo, 30) -var file_glutton_proto_goTypes = []any{ +var file_internal_proto_glutton_glutton_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_internal_proto_glutton_glutton_proto_msgTypes = make([]protoimpl.MessageInfo, 30) +var file_internal_proto_glutton_glutton_proto_goTypes = []any{ (WriteMode)(0), // 0: glutton.WriteMode (ReadMode)(0), // 1: glutton.ReadMode (*WriteRAMRequest)(nil), // 2: glutton.WriteRAMRequest @@ -2070,7 +2070,7 @@ var file_glutton_proto_goTypes = []any{ (*StepResult)(nil), // 30: glutton.StepResult (*Stats)(nil), // 31: glutton.Stats } -var file_glutton_proto_depIdxs = []int32{ +var file_internal_proto_glutton_glutton_proto_depIdxs = []int32{ 0, // 0: glutton.WriteRAMRequest.write_mode:type_name -> glutton.WriteMode 0, // 1: glutton.WriteDiskRequest.write_mode:type_name -> glutton.WriteMode 1, // 2: glutton.ReadDiskRequest.read_mode:type_name -> glutton.ReadMode @@ -2119,17 +2119,17 @@ var file_glutton_proto_depIdxs = []int32{ 0, // [0:19] is the sub-list for field type_name } -func init() { file_glutton_proto_init() } -func file_glutton_proto_init() { - if File_glutton_proto != nil { +func init() { file_internal_proto_glutton_glutton_proto_init() } +func file_internal_proto_glutton_glutton_proto_init() { + if File_internal_proto_glutton_glutton_proto != nil { return } - file_glutton_proto_msgTypes[19].OneofWrappers = []any{} - file_glutton_proto_msgTypes[22].OneofWrappers = []any{ + file_internal_proto_glutton_glutton_proto_msgTypes[19].OneofWrappers = []any{} + file_internal_proto_glutton_glutton_proto_msgTypes[22].OneofWrappers = []any{ (*Step_Block)(nil), (*Step_Operation)(nil), } - file_glutton_proto_msgTypes[24].OneofWrappers = []any{ + file_internal_proto_glutton_glutton_proto_msgTypes[24].OneofWrappers = []any{ (*Request_WriteRam)(nil), (*Request_ReadRam)(nil), (*Request_WriteDisk)(nil), @@ -2142,18 +2142,18 @@ func file_glutton_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_glutton_proto_rawDesc), len(file_glutton_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_internal_proto_glutton_glutton_proto_rawDesc), len(file_internal_proto_glutton_glutton_proto_rawDesc)), NumEnums: 2, NumMessages: 30, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_glutton_proto_goTypes, - DependencyIndexes: file_glutton_proto_depIdxs, - EnumInfos: file_glutton_proto_enumTypes, - MessageInfos: file_glutton_proto_msgTypes, + GoTypes: file_internal_proto_glutton_glutton_proto_goTypes, + DependencyIndexes: file_internal_proto_glutton_glutton_proto_depIdxs, + EnumInfos: file_internal_proto_glutton_glutton_proto_enumTypes, + MessageInfos: file_internal_proto_glutton_glutton_proto_msgTypes, }.Build() - File_glutton_proto = out.File - file_glutton_proto_goTypes = nil - file_glutton_proto_depIdxs = nil + File_internal_proto_glutton_glutton_proto = out.File + file_internal_proto_glutton_glutton_proto_goTypes = nil + file_internal_proto_glutton_glutton_proto_depIdxs = nil } diff --git a/internal/proto/glutton/glutton_grpc.pb.go b/internal/proto/glutton/glutton_grpc.pb.go index 5952f01960..115314de43 100644 --- a/internal/proto/glutton/glutton_grpc.pb.go +++ b/internal/proto/glutton/glutton_grpc.pb.go @@ -16,7 +16,7 @@ // versions: // - protoc-gen-go-grpc v1.6.2 // - protoc v4.25.3 -// source: glutton.proto +// source: internal/proto/glutton/glutton.proto package glutton @@ -585,5 +585,5 @@ var Glutton_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "glutton.proto", + Metadata: "internal/proto/glutton/glutton.proto", } diff --git a/internal/proto/grpcechopb/grpcecho.pb.go b/internal/proto/grpcechopb/grpcecho.pb.go index 8ba5112683..36d395c508 100644 --- a/internal/proto/grpcechopb/grpcecho.pb.go +++ b/internal/proto/grpcechopb/grpcecho.pb.go @@ -16,7 +16,7 @@ // versions: // protoc-gen-go v1.36.11-devel // protoc v4.25.3 -// source: grpcecho.proto +// source: internal/proto/grpcechopb/grpcecho.proto package grpcechopb @@ -45,7 +45,7 @@ type EchoRequest struct { func (x *EchoRequest) Reset() { *x = EchoRequest{} - mi := &file_grpcecho_proto_msgTypes[0] + mi := &file_internal_proto_grpcechopb_grpcecho_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -57,7 +57,7 @@ func (x *EchoRequest) String() string { func (*EchoRequest) ProtoMessage() {} func (x *EchoRequest) ProtoReflect() protoreflect.Message { - mi := &file_grpcecho_proto_msgTypes[0] + mi := &file_internal_proto_grpcechopb_grpcecho_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -70,7 +70,7 @@ func (x *EchoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EchoRequest.ProtoReflect.Descriptor instead. func (*EchoRequest) Descriptor() ([]byte, []int) { - return file_grpcecho_proto_rawDescGZIP(), []int{0} + return file_internal_proto_grpcechopb_grpcecho_proto_rawDescGZIP(), []int{0} } func (x *EchoRequest) GetMessage() string { @@ -92,7 +92,7 @@ type EchoStreamRequest struct { func (x *EchoStreamRequest) Reset() { *x = EchoStreamRequest{} - mi := &file_grpcecho_proto_msgTypes[1] + mi := &file_internal_proto_grpcechopb_grpcecho_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -104,7 +104,7 @@ func (x *EchoStreamRequest) String() string { func (*EchoStreamRequest) ProtoMessage() {} func (x *EchoStreamRequest) ProtoReflect() protoreflect.Message { - mi := &file_grpcecho_proto_msgTypes[1] + mi := &file_internal_proto_grpcechopb_grpcecho_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -117,7 +117,7 @@ func (x *EchoStreamRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EchoStreamRequest.ProtoReflect.Descriptor instead. func (*EchoStreamRequest) Descriptor() ([]byte, []int) { - return file_grpcecho_proto_rawDescGZIP(), []int{1} + return file_internal_proto_grpcechopb_grpcecho_proto_rawDescGZIP(), []int{1} } func (x *EchoStreamRequest) GetMessage() string { @@ -147,7 +147,7 @@ type EchoResponse struct { func (x *EchoResponse) Reset() { *x = EchoResponse{} - mi := &file_grpcecho_proto_msgTypes[2] + mi := &file_internal_proto_grpcechopb_grpcecho_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -159,7 +159,7 @@ func (x *EchoResponse) String() string { func (*EchoResponse) ProtoMessage() {} func (x *EchoResponse) ProtoReflect() protoreflect.Message { - mi := &file_grpcecho_proto_msgTypes[2] + mi := &file_internal_proto_grpcechopb_grpcecho_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -172,7 +172,7 @@ func (x *EchoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EchoResponse.ProtoReflect.Descriptor instead. func (*EchoResponse) Descriptor() ([]byte, []int) { - return file_grpcecho_proto_rawDescGZIP(), []int{2} + return file_internal_proto_grpcechopb_grpcecho_proto_rawDescGZIP(), []int{2} } func (x *EchoResponse) GetMessage() string { @@ -189,11 +189,11 @@ func (x *EchoResponse) GetIndex() int32 { return 0 } -var File_grpcecho_proto protoreflect.FileDescriptor +var File_internal_proto_grpcechopb_grpcecho_proto protoreflect.FileDescriptor -const file_grpcecho_proto_rawDesc = "" + +const file_internal_proto_grpcechopb_grpcecho_proto_rawDesc = "" + "\n" + - "\x0egrpcecho.proto\x12\bgrpcecho\"'\n" + + "(internal/proto/grpcechopb/grpcecho.proto\x12\bgrpcecho\"'\n" + "\vEchoRequest\x12\x18\n" + "\amessage\x18\x01 \x01(\tR\amessage\"C\n" + "\x11EchoStreamRequest\x12\x18\n" + @@ -209,24 +209,24 @@ const file_grpcecho_proto_rawDesc = "" + "\bEchoBidi\x12\x15.grpcecho.EchoRequest\x1a\x16.grpcecho.EchoResponse\"\x00(\x010\x01B0Z.go.ate.dev/substrate/internal/proto/grpcechopbb\x06proto3" var ( - file_grpcecho_proto_rawDescOnce sync.Once - file_grpcecho_proto_rawDescData []byte + file_internal_proto_grpcechopb_grpcecho_proto_rawDescOnce sync.Once + file_internal_proto_grpcechopb_grpcecho_proto_rawDescData []byte ) -func file_grpcecho_proto_rawDescGZIP() []byte { - file_grpcecho_proto_rawDescOnce.Do(func() { - file_grpcecho_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_grpcecho_proto_rawDesc), len(file_grpcecho_proto_rawDesc))) +func file_internal_proto_grpcechopb_grpcecho_proto_rawDescGZIP() []byte { + file_internal_proto_grpcechopb_grpcecho_proto_rawDescOnce.Do(func() { + file_internal_proto_grpcechopb_grpcecho_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_internal_proto_grpcechopb_grpcecho_proto_rawDesc), len(file_internal_proto_grpcechopb_grpcecho_proto_rawDesc))) }) - return file_grpcecho_proto_rawDescData + return file_internal_proto_grpcechopb_grpcecho_proto_rawDescData } -var file_grpcecho_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_grpcecho_proto_goTypes = []any{ +var file_internal_proto_grpcechopb_grpcecho_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_internal_proto_grpcechopb_grpcecho_proto_goTypes = []any{ (*EchoRequest)(nil), // 0: grpcecho.EchoRequest (*EchoStreamRequest)(nil), // 1: grpcecho.EchoStreamRequest (*EchoResponse)(nil), // 2: grpcecho.EchoResponse } -var file_grpcecho_proto_depIdxs = []int32{ +var file_internal_proto_grpcechopb_grpcecho_proto_depIdxs = []int32{ 0, // 0: grpcecho.Echo.Echo:input_type -> grpcecho.EchoRequest 1, // 1: grpcecho.Echo.EchoStream:input_type -> grpcecho.EchoStreamRequest 0, // 2: grpcecho.Echo.EchoBidi:input_type -> grpcecho.EchoRequest @@ -240,26 +240,26 @@ var file_grpcecho_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for field type_name } -func init() { file_grpcecho_proto_init() } -func file_grpcecho_proto_init() { - if File_grpcecho_proto != nil { +func init() { file_internal_proto_grpcechopb_grpcecho_proto_init() } +func file_internal_proto_grpcechopb_grpcecho_proto_init() { + if File_internal_proto_grpcechopb_grpcecho_proto != nil { return } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_grpcecho_proto_rawDesc), len(file_grpcecho_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_internal_proto_grpcechopb_grpcecho_proto_rawDesc), len(file_internal_proto_grpcechopb_grpcecho_proto_rawDesc)), NumEnums: 0, NumMessages: 3, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_grpcecho_proto_goTypes, - DependencyIndexes: file_grpcecho_proto_depIdxs, - MessageInfos: file_grpcecho_proto_msgTypes, + GoTypes: file_internal_proto_grpcechopb_grpcecho_proto_goTypes, + DependencyIndexes: file_internal_proto_grpcechopb_grpcecho_proto_depIdxs, + MessageInfos: file_internal_proto_grpcechopb_grpcecho_proto_msgTypes, }.Build() - File_grpcecho_proto = out.File - file_grpcecho_proto_goTypes = nil - file_grpcecho_proto_depIdxs = nil + File_internal_proto_grpcechopb_grpcecho_proto = out.File + file_internal_proto_grpcechopb_grpcecho_proto_goTypes = nil + file_internal_proto_grpcechopb_grpcecho_proto_depIdxs = nil } diff --git a/internal/proto/grpcechopb/grpcecho_grpc.pb.go b/internal/proto/grpcechopb/grpcecho_grpc.pb.go index a551bfd859..4d5e27993f 100644 --- a/internal/proto/grpcechopb/grpcecho_grpc.pb.go +++ b/internal/proto/grpcechopb/grpcecho_grpc.pb.go @@ -16,7 +16,7 @@ // versions: // - protoc-gen-go-grpc v1.6.2 // - protoc v4.25.3 -// source: grpcecho.proto +// source: internal/proto/grpcechopb/grpcecho.proto package grpcechopb @@ -255,5 +255,5 @@ var Echo_ServiceDesc = grpc.ServiceDesc{ ClientStreams: true, }, }, - Metadata: "grpcecho.proto", + Metadata: "internal/proto/grpcechopb/grpcecho.proto", } diff --git a/internal/proto/objectstoreexchangepb/exchange.pb.go b/internal/proto/objectstoreexchangepb/exchange.pb.go index 4c4973ad1e..7b87ce657e 100644 --- a/internal/proto/objectstoreexchangepb/exchange.pb.go +++ b/internal/proto/objectstoreexchangepb/exchange.pb.go @@ -16,7 +16,7 @@ // versions: // protoc-gen-go v1.36.11-devel // protoc v4.25.3 -// source: exchange.proto +// source: internal/proto/objectstoreexchangepb/exchange.proto package objectstoreexchangepb @@ -52,7 +52,7 @@ type ExchangeActorJwtRequest struct { func (x *ExchangeActorJwtRequest) Reset() { *x = ExchangeActorJwtRequest{} - mi := &file_exchange_proto_msgTypes[0] + mi := &file_internal_proto_objectstoreexchangepb_exchange_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -64,7 +64,7 @@ func (x *ExchangeActorJwtRequest) String() string { func (*ExchangeActorJwtRequest) ProtoMessage() {} func (x *ExchangeActorJwtRequest) ProtoReflect() protoreflect.Message { - mi := &file_exchange_proto_msgTypes[0] + mi := &file_internal_proto_objectstoreexchangepb_exchange_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -77,7 +77,7 @@ func (x *ExchangeActorJwtRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExchangeActorJwtRequest.ProtoReflect.Descriptor instead. func (*ExchangeActorJwtRequest) Descriptor() ([]byte, []int) { - return file_exchange_proto_rawDescGZIP(), []int{0} + return file_internal_proto_objectstoreexchangepb_exchange_proto_rawDescGZIP(), []int{0} } func (x *ExchangeActorJwtRequest) GetActorJwt() string { @@ -106,7 +106,7 @@ type ExchangeActorJwtResponse struct { func (x *ExchangeActorJwtResponse) Reset() { *x = ExchangeActorJwtResponse{} - mi := &file_exchange_proto_msgTypes[1] + mi := &file_internal_proto_objectstoreexchangepb_exchange_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -118,7 +118,7 @@ func (x *ExchangeActorJwtResponse) String() string { func (*ExchangeActorJwtResponse) ProtoMessage() {} func (x *ExchangeActorJwtResponse) ProtoReflect() protoreflect.Message { - mi := &file_exchange_proto_msgTypes[1] + mi := &file_internal_proto_objectstoreexchangepb_exchange_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -131,7 +131,7 @@ func (x *ExchangeActorJwtResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ExchangeActorJwtResponse.ProtoReflect.Descriptor instead. func (*ExchangeActorJwtResponse) Descriptor() ([]byte, []int) { - return file_exchange_proto_rawDescGZIP(), []int{1} + return file_internal_proto_objectstoreexchangepb_exchange_proto_rawDescGZIP(), []int{1} } func (x *ExchangeActorJwtResponse) GetAccessToken() string { @@ -148,11 +148,11 @@ func (x *ExchangeActorJwtResponse) GetExpireTime() *timestamppb.Timestamp { return nil } -var File_exchange_proto protoreflect.FileDescriptor +var File_internal_proto_objectstoreexchangepb_exchange_proto protoreflect.FileDescriptor -const file_exchange_proto_rawDesc = "" + +const file_internal_proto_objectstoreexchangepb_exchange_proto_rawDesc = "" + "\n" + - "\x0eexchange.proto\x12\x13objectstoreexchange\x1a\x1fgoogle/protobuf/timestamp.proto\"Q\n" + + "3internal/proto/objectstoreexchangepb/exchange.proto\x12\x13objectstoreexchange\x1a\x1fgoogle/protobuf/timestamp.proto\"Q\n" + "\x17ExchangeActorJwtRequest\x12 \n" + "\tactor_jwt\x18\x01 \x01(\tB\x03\x80\x01\x01R\bactorJwt\x12\x14\n" + "\x05force\x18\x02 \x01(\bR\x05force\"\x7f\n" + @@ -164,24 +164,24 @@ const file_exchange_proto_rawDesc = "" + "\x10ExchangeActorJwt\x12,.objectstoreexchange.ExchangeActorJwtRequest\x1a-.objectstoreexchange.ExchangeActorJwtResponseB;Z9go.ate.dev/substrate/internal/proto/objectstoreexchangepbb\x06proto3" var ( - file_exchange_proto_rawDescOnce sync.Once - file_exchange_proto_rawDescData []byte + file_internal_proto_objectstoreexchangepb_exchange_proto_rawDescOnce sync.Once + file_internal_proto_objectstoreexchangepb_exchange_proto_rawDescData []byte ) -func file_exchange_proto_rawDescGZIP() []byte { - file_exchange_proto_rawDescOnce.Do(func() { - file_exchange_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_exchange_proto_rawDesc), len(file_exchange_proto_rawDesc))) +func file_internal_proto_objectstoreexchangepb_exchange_proto_rawDescGZIP() []byte { + file_internal_proto_objectstoreexchangepb_exchange_proto_rawDescOnce.Do(func() { + file_internal_proto_objectstoreexchangepb_exchange_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_internal_proto_objectstoreexchangepb_exchange_proto_rawDesc), len(file_internal_proto_objectstoreexchangepb_exchange_proto_rawDesc))) }) - return file_exchange_proto_rawDescData + return file_internal_proto_objectstoreexchangepb_exchange_proto_rawDescData } -var file_exchange_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_exchange_proto_goTypes = []any{ +var file_internal_proto_objectstoreexchangepb_exchange_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_internal_proto_objectstoreexchangepb_exchange_proto_goTypes = []any{ (*ExchangeActorJwtRequest)(nil), // 0: objectstoreexchange.ExchangeActorJwtRequest (*ExchangeActorJwtResponse)(nil), // 1: objectstoreexchange.ExchangeActorJwtResponse (*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp } -var file_exchange_proto_depIdxs = []int32{ +var file_internal_proto_objectstoreexchangepb_exchange_proto_depIdxs = []int32{ 2, // 0: objectstoreexchange.ExchangeActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp 0, // 1: objectstoreexchange.CredentialExchange.ExchangeActorJwt:input_type -> objectstoreexchange.ExchangeActorJwtRequest 1, // 2: objectstoreexchange.CredentialExchange.ExchangeActorJwt:output_type -> objectstoreexchange.ExchangeActorJwtResponse @@ -192,26 +192,26 @@ var file_exchange_proto_depIdxs = []int32{ 0, // [0:1] is the sub-list for field type_name } -func init() { file_exchange_proto_init() } -func file_exchange_proto_init() { - if File_exchange_proto != nil { +func init() { file_internal_proto_objectstoreexchangepb_exchange_proto_init() } +func file_internal_proto_objectstoreexchangepb_exchange_proto_init() { + if File_internal_proto_objectstoreexchangepb_exchange_proto != nil { return } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_exchange_proto_rawDesc), len(file_exchange_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_internal_proto_objectstoreexchangepb_exchange_proto_rawDesc), len(file_internal_proto_objectstoreexchangepb_exchange_proto_rawDesc)), NumEnums: 0, NumMessages: 2, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_exchange_proto_goTypes, - DependencyIndexes: file_exchange_proto_depIdxs, - MessageInfos: file_exchange_proto_msgTypes, + GoTypes: file_internal_proto_objectstoreexchangepb_exchange_proto_goTypes, + DependencyIndexes: file_internal_proto_objectstoreexchangepb_exchange_proto_depIdxs, + MessageInfos: file_internal_proto_objectstoreexchangepb_exchange_proto_msgTypes, }.Build() - File_exchange_proto = out.File - file_exchange_proto_goTypes = nil - file_exchange_proto_depIdxs = nil + File_internal_proto_objectstoreexchangepb_exchange_proto = out.File + file_internal_proto_objectstoreexchangepb_exchange_proto_goTypes = nil + file_internal_proto_objectstoreexchangepb_exchange_proto_depIdxs = nil } diff --git a/internal/proto/objectstoreexchangepb/exchange_grpc.pb.go b/internal/proto/objectstoreexchangepb/exchange_grpc.pb.go index 696d42a354..9af13dcf1a 100644 --- a/internal/proto/objectstoreexchangepb/exchange_grpc.pb.go +++ b/internal/proto/objectstoreexchangepb/exchange_grpc.pb.go @@ -16,7 +16,7 @@ // versions: // - protoc-gen-go-grpc v1.6.2 // - protoc v4.25.3 -// source: exchange.proto +// source: internal/proto/objectstoreexchangepb/exchange.proto package objectstoreexchangepb @@ -169,5 +169,5 @@ var CredentialExchange_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "exchange.proto", + Metadata: "internal/proto/objectstoreexchangepb/exchange.proto", } diff --git a/internal/protoredact/protoredact_test.go b/internal/protoredact/protoredact_test.go index 928b601961..ebf7de2705 100644 --- a/internal/protoredact/protoredact_test.go +++ b/internal/protoredact/protoredact_test.go @@ -23,6 +23,9 @@ import ( "sync" "testing" + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/api/credprovider/v1" + "go.ate.dev/substrate/api/objectstore/v1" ateenvv1alpha "go.ate.dev/substrate/internal/proto/ateenv/v1alpha" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/proto/ateworkerpb" @@ -30,10 +33,7 @@ import ( "go.ate.dev/substrate/internal/proto/grpcechopb" "go.ate.dev/substrate/internal/proto/objectstoreexchangepb" "go.ate.dev/substrate/internal/protoredact" - "go.ate.dev/substrate/pkg/proto/ateapipb" "go.ate.dev/substrate/pkg/proto/ateconfigpb" - "go.ate.dev/substrate/pkg/proto/credproviderpb" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protodesc" "google.golang.org/protobuf/reflect/protoreflect" @@ -260,16 +260,16 @@ func TestRedactedHandlesTypedNilWithoutPanicking(t *testing.T) { // A typed nil proto pointer, as a handler returns alongside an error and // the interceptor then logs, must come back as a nil message of the same // type, for a redactable type and for a clean one alike. - var jwt *ateapipb.MintActorJwtResponse + var jwt *ateapi.MintActorJwtResponse if r, changed := protoredact.Redacted(jwt); changed { t.Errorf("typed nil redactable: reported changed, got %#v", r) - } else if m, ok := r.(*ateapipb.MintActorJwtResponse); !ok || m != nil { + } else if m, ok := r.(*ateapi.MintActorJwtResponse); !ok || m != nil { t.Errorf("typed nil redactable: got %#v", r) } - var ref *ateapipb.ObjectRef + var ref *ateapi.ObjectRef if r, changed := protoredact.Redacted(ref); changed { t.Errorf("typed nil clean: reported changed, got %#v", r) - } else if m, ok := r.(*ateapipb.ObjectRef); !ok || m != nil { + } else if m, ok := r.(*ateapi.ObjectRef); !ok || m != nil { t.Errorf("typed nil clean: got %#v", r) } } @@ -279,12 +279,12 @@ func TestRedactedReturnsMessagesWithNothingToMaskWithoutCopying(t *testing.T) { // type whose labeled fields are all unset, come back as the same pointer: // nothing to mask, nothing to copy. for _, m := range []proto.Message{ - &ateapipb.ListActorsResponse{Actors: []*ateapipb.Actor{{Metadata: &ateapipb.ResourceMetadata{Name: "a"}}}}, - &ateapipb.ObjectRef{Atespace: "s", Name: "n"}, - &ateapipb.Worker{}, - &ateapipb.ActorTemplate{Containers: []*ateapipb.Container{{Name: "c", Image: "img"}}}, - &ateapipb.ListActorTemplatesResponse{ActorTemplates: []*ateapipb.ActorTemplate{{Containers: []*ateapipb.Container{{Name: "c"}}}}}, - &ateapipb.MintActorJwtResponse{}, + &ateapi.ListActorsResponse{Actors: []*ateapi.Actor{{Metadata: &ateapi.ResourceMetadata{Name: "a"}}}}, + &ateapi.ObjectRef{Atespace: "s", Name: "n"}, + &ateapi.Worker{}, + &ateapi.ActorTemplate{Containers: []*ateapi.Container{{Name: "c", Image: "img"}}}, + &ateapi.ListActorTemplatesResponse{ActorTemplates: []*ateapi.ActorTemplate{{Containers: []*ateapi.Container{{Name: "c"}}}}}, + &ateapi.MintActorJwtResponse{}, &ateletpb.RunRequest{Spec: &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Env: []*ateletpb.EnvVar{{Name: "K"}}}}}}, } { if protoredact.NeedsRedaction(m) { @@ -296,9 +296,9 @@ func TestRedactedReturnsMessagesWithNothingToMaskWithoutCopying(t *testing.T) { } // A populated labeled field, however deep, forces a masked copy. for _, m := range []proto.Message{ - &ateapipb.MintActorJwtResponse{ActorJwt: "t"}, - &ateapipb.ActorTemplate{Containers: []*ateapipb.Container{{Env: []*ateapipb.EnvVar{{Name: "K", Value: "v"}}}}}, - &ateapipb.ListActorTemplatesResponse{ActorTemplates: []*ateapipb.ActorTemplate{{}, {Containers: []*ateapipb.Container{{}, {Env: []*ateapipb.EnvVar{{Name: "K", Value: "v"}}}}}}}, + &ateapi.MintActorJwtResponse{ActorJwt: "t"}, + &ateapi.ActorTemplate{Containers: []*ateapi.Container{{Env: []*ateapi.EnvVar{{Name: "K", Value: "v"}}}}}, + &ateapi.ListActorTemplatesResponse{ActorTemplates: []*ateapi.ActorTemplate{{}, {Containers: []*ateapi.Container{{}, {Env: []*ateapi.EnvVar{{Name: "K", Value: "v"}}}}}}}, &ateletpb.RunRequest{Spec: &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Env: []*ateletpb.EnvVar{{Name: "K", Value: "v"}}}}}}, } { if !protoredact.NeedsRedaction(m) { @@ -317,7 +317,7 @@ func TestNeedsRedactionToleratesTypedNilOfAnyImplementation(t *testing.T) { // A typed nil generated message answers ProtoReflect safely; a typed nil // dynamicpb.Message returns the nil receiver, which faults on use. Both // must be reported clean and returned unchanged. - var gen *ateapipb.MintActorJwtResponse + var gen *ateapi.MintActorJwtResponse var dyn *dynamicpb.Message for _, m := range []proto.Message{gen, dyn} { if protoredact.NeedsRedaction(m) { @@ -333,10 +333,10 @@ func TestNeedsRedactionIsSafeUnderConcurrentFirstUse(t *testing.T) { // The per-type answer is memoized on first sight; many goroutines // meeting several types at once must agree and not race. msgs := []proto.Message{ - &ateapipb.MintActorJwtResponse{ActorJwt: "t"}, - &ateapipb.ListActorsResponse{}, - &ateapipb.ActorTemplate{Containers: []*ateapipb.Container{{Env: []*ateapipb.EnvVar{{Name: "K", Value: "v"}}}}}, - &ateapipb.Worker{}, + &ateapi.MintActorJwtResponse{ActorJwt: "t"}, + &ateapi.ListActorsResponse{}, + &ateapi.ActorTemplate{Containers: []*ateapi.Container{{Env: []*ateapi.EnvVar{{Name: "K", Value: "v"}}}}}, + &ateapi.Worker{}, &ateletpb.RunRequest{Spec: &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Env: []*ateletpb.EnvVar{{Name: "K", Value: "v"}}}}}}, } want := []bool{true, false, true, false, true} @@ -359,16 +359,16 @@ func TestNeedsRedactionIsSafeUnderConcurrentFirstUse(t *testing.T) { // handler can be handed. TestOurProtoFilesAreAllListed keeps it in step with // the .proto files on disk. var ourProtoFiles = []protoreflect.FileDescriptor{ - ateapipb.File_ateapi_proto, - ateenvv1alpha.File_guest_proto, - ateletpb.File_atelet_proto, - ateworkerpb.File_ateworker_proto, - ateconfigpb.File_apiconfig_proto, - credproviderpb.File_credprovider_proto, - glutton.File_glutton_proto, - grpcechopb.File_grpcecho_proto, - objectstoreexchangepb.File_exchange_proto, - objectstorev1.File_objectstore_proto, + ateapi.File_api_ateapi_v1_ateapi_proto, + ateenvv1alpha.File_internal_proto_ateenv_v1alpha_guest_proto, + ateletpb.File_internal_proto_ateletpb_atelet_proto, + ateworkerpb.File_internal_proto_ateworkerpb_ateworker_proto, + ateconfigpb.File_pkg_proto_ateconfigpb_apiconfig_proto, + credprovider.File_api_credprovider_v1_credprovider_proto, + glutton.File_internal_proto_glutton_glutton_proto, + grpcechopb.File_internal_proto_grpcechopb_grpcecho_proto, + objectstoreexchangepb.File_internal_proto_objectstoreexchangepb_exchange_proto, + objectstore.File_api_objectstore_v1_objectstore_proto, } // forEachField calls fn for every field of every message in ourProtoFiles, @@ -400,17 +400,17 @@ func isDebugRedact(fd protoreflect.FieldDescriptor) bool { // change is reviewed as a deliberate decision about what the logs may show. func TestDebugRedactFieldsArePinned(t *testing.T) { want := map[string]bool{ - "ateapi.EnvVar.value": true, - "ateapi.MintActorJwtResponse.actor_jwt": true, - "ateapi.MintWorkerActorJwtResponse.actor_jwt": true, - "atelet.EnvVar.value": true, - "ateworker.ContainerSpec.env": true, - "credprovider.FetchSecretResponse.opaque_bytes": true, - "objectstore.v1.FetchAssetRequest.asset_uri": true, - "objectstore.v1.FetchSnapshotRequest.actor_jwt": true, - "objectstore.v1.UploadSnapshotRequest.actor_jwt": true, - "objectstoreexchange.ExchangeActorJwtRequest.actor_jwt": true, - "objectstoreexchange.ExchangeActorJwtResponse.access_token": true, + "substrate.ateapi.v1.EnvVar.value": true, + "substrate.ateapi.v1.MintActorJwtResponse.actor_jwt": true, + "substrate.ateapi.v1.MintWorkerActorJwtResponse.actor_jwt": true, + "atelet.EnvVar.value": true, + "ateworker.ContainerSpec.env": true, + "substrate.credprovider.v1.FetchSecretResponse.opaque_bytes": true, + "substrate.objectstore.v1.FetchAssetRequest.asset_uri": true, + "substrate.objectstore.v1.FetchSnapshotRequest.actor_jwt": true, + "substrate.objectstore.v1.UploadSnapshotRequest.actor_jwt": true, + "objectstoreexchange.ExchangeActorJwtRequest.actor_jwt": true, + "objectstoreexchange.ExchangeActorJwtResponse.access_token": true, } got := map[string]bool{} forEachField(func(fd protoreflect.FieldDescriptor) { @@ -439,10 +439,10 @@ var secretLikeName = regexp.MustCompile(`(?i)jwt|token|secret|passw|credential|p // credential goes in notSecret with the reason. func TestSecretLikeFieldsAreLabeled(t *testing.T) { notSecret := map[string]string{ - "page_token": "opaque list cursor", - "next_page_token": "opaque list cursor", - "ateapi.CredentialHeader.credential_uri": "ate-secret:// reference to a credential, not the value", - "ateapi.CredentialHeader.actor_jwt": "ActorJwtSource: audiences and lifetime for minting, not a token", + "page_token": "opaque list cursor", + "next_page_token": "opaque list cursor", + "substrate.ateapi.v1.CredentialHeader.credential_uri": "ate-secret:// reference to a credential, not the value", + "substrate.ateapi.v1.CredentialHeader.actor_jwt": "ActorJwtSource: audiences and lifetime for minting, not a token", } forEachField(func(fd protoreflect.FieldDescriptor) { if !secretLikeName.MatchString(string(fd.Name())) || isDebugRedact(fd) { diff --git a/internal/resources/actorattribution.go b/internal/resources/actorattribution.go index 4704bb9311..db01f615fe 100644 --- a/internal/resources/actorattribution.go +++ b/internal/resources/actorattribution.go @@ -14,7 +14,7 @@ package resources -import "go.ate.dev/substrate/pkg/proto/ateapipb" +import "go.ate.dev/substrate/api/ateapi/v1" // ActorAttribution is what telemetry about an actor is attributed to: an // ActorRef plus the two things a ref does not carry, the server-assigned uid and @@ -33,7 +33,7 @@ type ActorAttribution struct { // ActorAttributionFromActor builds the attribution for a loaded Actor. Nil-safe; // a nil Actor yields zero-valued fields. -func ActorAttributionFromActor(a *ateapipb.Actor) ActorAttribution { +func ActorAttributionFromActor(a *ateapi.Actor) ActorAttribution { return ActorAttribution{ Ref: ActorRefFromActor(a), UID: a.GetMetadata().GetUid(), diff --git a/internal/resources/actorstate.go b/internal/resources/actorstate.go index fd5028a9ee..ead15c0a1b 100644 --- a/internal/resources/actorstate.go +++ b/internal/resources/actorstate.go @@ -14,7 +14,7 @@ package resources -import "go.ate.dev/substrate/pkg/proto/ateapipb" +import "go.ate.dev/substrate/api/ateapi/v1" // TransferStates are the states in which a node may be moving the actor's // snapshot between itself and object storage: @@ -27,9 +27,9 @@ import "go.ate.dev/substrate/pkg/proto/ateapipb" // credential for its snapshots. The mint's host check and the objectstore // plugin's credential exchange both refuse the other states, and read the // list here so they cannot disagree. -var TransferStates = []ateapipb.ActorState{ - ateapipb.ActorState_ACTOR_STATE_RESUMING, - ateapipb.ActorState_ACTOR_STATE_RUNNING, - ateapipb.ActorState_ACTOR_STATE_SUSPENDING, - ateapipb.ActorState_ACTOR_STATE_SUSPENDED, +var TransferStates = []ateapi.ActorState{ + ateapi.ActorState_ACTOR_STATE_RESUMING, + ateapi.ActorState_ACTOR_STATE_RUNNING, + ateapi.ActorState_ACTOR_STATE_SUSPENDING, + ateapi.ActorState_ACTOR_STATE_SUSPENDED, } diff --git a/internal/resources/actorstate_test.go b/internal/resources/actorstate_test.go index f96fa385f9..190110b12a 100644 --- a/internal/resources/actorstate_test.go +++ b/internal/resources/actorstate_test.go @@ -18,25 +18,25 @@ import ( "slices" "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) // TestTransferStatesClassifyEveryState fails when a state is added to the // enum without deciding whether a node transfers snapshots in it, since the // mint's host check and the credential exchange both refuse unlisted states. func TestTransferStatesClassifyEveryState(t *testing.T) { - want := map[ateapipb.ActorState]bool{ - ateapipb.ActorState_ACTOR_STATE_UNSPECIFIED: false, - ateapipb.ActorState_ACTOR_STATE_RESUMING: true, - ateapipb.ActorState_ACTOR_STATE_RUNNING: true, - ateapipb.ActorState_ACTOR_STATE_SUSPENDING: true, - ateapipb.ActorState_ACTOR_STATE_SUSPENDED: true, - ateapipb.ActorState_ACTOR_STATE_CRASHED: false, - ateapipb.ActorState_ACTOR_STATE_REVERTING: false, - ateapipb.ActorState_ACTOR_STATE_DELETING: false, + want := map[ateapi.ActorState]bool{ + ateapi.ActorState_ACTOR_STATE_UNSPECIFIED: false, + ateapi.ActorState_ACTOR_STATE_RESUMING: true, + ateapi.ActorState_ACTOR_STATE_RUNNING: true, + ateapi.ActorState_ACTOR_STATE_SUSPENDING: true, + ateapi.ActorState_ACTOR_STATE_SUSPENDED: true, + ateapi.ActorState_ACTOR_STATE_CRASHED: false, + ateapi.ActorState_ACTOR_STATE_REVERTING: false, + ateapi.ActorState_ACTOR_STATE_DELETING: false, } - for value, name := range ateapipb.ActorState_name { - state := ateapipb.ActorState(value) + for value, name := range ateapi.ActorState_name { + state := ateapi.ActorState(value) transfers, classified := want[state] if !classified { t.Errorf("%s is not classified: decide whether a node transfers snapshots in it and add it to this test", name) diff --git a/internal/resources/compute.go b/internal/resources/compute.go index 4a854ede25..07bec63a25 100644 --- a/internal/resources/compute.go +++ b/internal/resources/compute.go @@ -15,10 +15,10 @@ package resources import ( - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) -// The same ateapipb.Resources is what an Actor's limits ask for, what a Worker +// The same ateapi.Resources is what an Actor's limits ask for, what a Worker // supplies, and the sum of what a Worker's Actors hold, so they subtract. // // A zero dimension is none of that resource. A Worker reports every dimension @@ -26,15 +26,15 @@ import ( // CPUMemory returns the Resources for cpuMilli and memoryBytes, or nil when // both are zero, so an emptied total compares equal to an absent one. -func CPUMemory(cpuMilli, memoryBytes int64) *ateapipb.Resources { +func CPUMemory(cpuMilli, memoryBytes int64) *ateapi.Resources { if cpuMilli == 0 && memoryBytes == 0 { return nil } - return &ateapipb.Resources{CpuMillicores: cpuMilli, MemoryBytes: memoryBytes} + return &ateapi.Resources{CpuMillicores: cpuMilli, MemoryBytes: memoryBytes} } // Covers reports whether have leaves room for want in every dimension. A // dimension want leaves at zero asks for nothing. -func Covers(have, want *ateapipb.Resources) bool { +func Covers(have, want *ateapi.Resources) bool { return have.GetCpuMillicores() >= want.GetCpuMillicores() && have.GetMemoryBytes() >= want.GetMemoryBytes() } diff --git a/internal/resources/compute_test.go b/internal/resources/compute_test.go index c6aa605015..7d5f0007f1 100644 --- a/internal/resources/compute_test.go +++ b/internal/resources/compute_test.go @@ -17,14 +17,14 @@ package resources import ( "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) func TestCovers(t *testing.T) { tests := []struct { name string - have *ateapipb.Resources - want *ateapipb.Resources + have *ateapi.Resources + want *ateapi.Resources ok bool }{ { diff --git a/internal/resources/resourceref.go b/internal/resources/resourceref.go index 3c27bd12f0..adea6c78d5 100644 --- a/internal/resources/resourceref.go +++ b/internal/resources/resourceref.go @@ -18,12 +18,12 @@ import ( "log/slog" "reflect" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) // Resource is any Atespaced resource message carrying the common metadata. type Resource interface { - GetMetadata() *ateapipb.ResourceMetadata + GetMetadata() *ateapi.ResourceMetadata } // ResourceRef identifies an Atespaced resource by the (atespace, name). @@ -50,25 +50,25 @@ func (r ResourceRef[R]) LogValue() slog.Value { } // ToObjectRef converts the reference to its wire form. -func (r ResourceRef[R]) ToObjectRef() *ateapipb.ObjectRef { - return &ateapipb.ObjectRef{Atespace: r.Atespace, Name: r.Name} +func (r ResourceRef[R]) ToObjectRef() *ateapi.ObjectRef { + return &ateapi.ObjectRef{Atespace: r.Atespace, Name: r.Name} } // resourceRefFromObjectRef converts a wire reference to the in-process form. -func resourceRefFromObjectRef[R Resource](ref *ateapipb.ObjectRef) ResourceRef[R] { +func resourceRefFromObjectRef[R Resource](ref *ateapi.ObjectRef) ResourceRef[R] { return ResourceRef[R]{Atespace: ref.GetAtespace(), Name: ref.GetName()} } // ActorRef identifies an actor by the (atespace, name). -type ActorRef = ResourceRef[*ateapipb.Actor] +type ActorRef = ResourceRef[*ateapi.Actor] // ActorRefFromObjectRef converts a wire reference to an ActorRef. -func ActorRefFromObjectRef(ref *ateapipb.ObjectRef) ActorRef { - return resourceRefFromObjectRef[*ateapipb.Actor](ref) +func ActorRefFromObjectRef(ref *ateapi.ObjectRef) ActorRef { + return resourceRefFromObjectRef[*ateapi.Actor](ref) } // ActorRefFromActor returns the reference addressing the given actor. -func ActorRefFromActor(a *ateapipb.Actor) ActorRef { +func ActorRefFromActor(a *ateapi.Actor) ActorRef { return ActorRef{ Atespace: a.GetMetadata().GetAtespace(), Name: a.GetMetadata().GetName(), @@ -76,16 +76,16 @@ func ActorRefFromActor(a *ateapipb.Actor) ActorRef { } // ActorTemplateRef identifies an ActorTemplate by the (atespace, name). -type ActorTemplateRef = ResourceRef[*ateapipb.ActorTemplate] +type ActorTemplateRef = ResourceRef[*ateapi.ActorTemplate] // ActorTemplateRefFromObjectRef converts a wire reference to an ActorTemplateRef. -func ActorTemplateRefFromObjectRef(ref *ateapipb.ObjectRef) ActorTemplateRef { - return resourceRefFromObjectRef[*ateapipb.ActorTemplate](ref) +func ActorTemplateRefFromObjectRef(ref *ateapi.ObjectRef) ActorTemplateRef { + return resourceRefFromObjectRef[*ateapi.ActorTemplate](ref) } // ActorTemplateRefFromActorTemplate returns the reference addressing the given // template. -func ActorTemplateRefFromActorTemplate(t *ateapipb.ActorTemplate) ActorTemplateRef { +func ActorTemplateRefFromActorTemplate(t *ateapi.ActorTemplate) ActorTemplateRef { return ActorTemplateRef{ Atespace: t.GetMetadata().GetAtespace(), Name: t.GetMetadata().GetName(), @@ -93,15 +93,15 @@ func ActorTemplateRefFromActorTemplate(t *ateapipb.ActorTemplate) ActorTemplateR } // TagRef identifies a Tag by the (atespace, name). -type TagRef = ResourceRef[*ateapipb.Tag] +type TagRef = ResourceRef[*ateapi.Tag] // TagRefFromObjectRef converts an ObjectRef to a TagRef. -func TagRefFromObjectRef(ref *ateapipb.ObjectRef) TagRef { - return resourceRefFromObjectRef[*ateapipb.Tag](ref) +func TagRefFromObjectRef(ref *ateapi.ObjectRef) TagRef { + return resourceRefFromObjectRef[*ateapi.Tag](ref) } // TagRefFromTag returns the reference addressing the given tag. -func TagRefFromTag(t *ateapipb.Tag) TagRef { +func TagRefFromTag(t *ateapi.Tag) TagRef { return TagRef{ Atespace: t.GetMetadata().GetAtespace(), Name: t.GetMetadata().GetName(), diff --git a/internal/resources/resourceref_test.go b/internal/resources/resourceref_test.go index 47eeaa9b6e..13d2e6a244 100644 --- a/internal/resources/resourceref_test.go +++ b/internal/resources/resourceref_test.go @@ -19,7 +19,7 @@ import ( "reflect" "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) // The ref aliases must stay distinct types: the phantom ResourceRef kind is @@ -52,17 +52,17 @@ func TestResourceRefLogValue(t *testing.T) { { name: "zero actor ref", val: ActorRef{}.LogValue(), - want: map[string]string{"type": "*ateapipb.Actor", "atespace": "", "name": ""}, + want: map[string]string{"type": "*ateapi.Actor", "atespace": "", "name": ""}, }, { name: "zero template ref", val: ActorTemplateRef{}.LogValue(), - want: map[string]string{"type": "*ateapipb.ActorTemplate", "atespace": "", "name": ""}, + want: map[string]string{"type": "*ateapi.ActorTemplate", "atespace": "", "name": ""}, }, { name: "populated actor ref", val: ActorRef{Atespace: "team-a", Name: "act-1"}.LogValue(), - want: map[string]string{"type": "*ateapipb.Actor", "atespace": "team-a", "name": "act-1"}, + want: map[string]string{"type": "*ateapi.Actor", "atespace": "team-a", "name": "act-1"}, }, } for _, tt := range tests { @@ -103,19 +103,19 @@ func TestActorRefObjectRefRoundTrip(t *testing.T) { func TestActorRefFromActor(t *testing.T) { tests := []struct { name string - actor *ateapipb.Actor + actor *ateapi.Actor want ActorRef }{ { name: "populated", - actor: &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{ + actor: &ateapi.Actor{Metadata: &ateapi.ResourceMetadata{ Atespace: "team-a", Name: "act-1", }}, want: ActorRef{Atespace: "team-a", Name: "act-1"}, }, {"nil actor", nil, ActorRef{}}, - {"nil metadata", &ateapipb.Actor{}, ActorRef{}}, + {"nil metadata", &ateapi.Actor{}, ActorRef{}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -148,19 +148,19 @@ func TestActorTemplateRefObjectRefRoundTrip(t *testing.T) { func TestActorTemplateRefFromActorTemplate(t *testing.T) { tests := []struct { name string - template *ateapipb.ActorTemplate + template *ateapi.ActorTemplate want ActorTemplateRef }{ { name: "populated", - template: &ateapipb.ActorTemplate{Metadata: &ateapipb.ResourceMetadata{ + template: &ateapi.ActorTemplate{Metadata: &ateapi.ResourceMetadata{ Atespace: "team-a", Name: "tmpl-1", }}, want: ActorTemplateRef{Atespace: "team-a", Name: "tmpl-1"}, }, {"nil template", nil, ActorTemplateRef{}}, - {"nil metadata", &ateapipb.ActorTemplate{}, ActorTemplateRef{}}, + {"nil metadata", &ateapi.ActorTemplate{}, ActorTemplateRef{}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -193,19 +193,19 @@ func TestTagRefObjectRefRoundTrip(t *testing.T) { func TestTagRefFromTag(t *testing.T) { tests := []struct { name string - tag *ateapipb.Tag + tag *ateapi.Tag want TagRef }{ { name: "populated", - tag: &ateapipb.Tag{Metadata: &ateapipb.ResourceMetadata{ + tag: &ateapi.Tag{Metadata: &ateapi.ResourceMetadata{ Atespace: "team-a", Name: "tag-1", }}, want: TagRef{Atespace: "team-a", Name: "tag-1"}, }, {"nil tag", nil, TagRef{}}, - {"nil metadata", &ateapipb.Tag{}, TagRef{}}, + {"nil metadata", &ateapi.Tag{}, TagRef{}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/resources/validate_test.go b/internal/resources/validate_test.go index 9ca3d54077..6d103bf75c 100644 --- a/internal/resources/validate_test.go +++ b/internal/resources/validate_test.go @@ -23,10 +23,10 @@ import ( "strings" "testing" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/nodepath" "go.ate.dev/substrate/internal/proto/ateworkerpb" - "go.ate.dev/substrate/pkg/proto/ateapipb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "k8s.io/apimachinery/pkg/api/operation" @@ -77,8 +77,8 @@ func TestToAPIErrorEmpty(t *testing.T) { func TestDeepEqual(t *testing.T) { // Proto messages carry internal state that reflect.DeepEqual would // compare; proto.Equal compares only field values. - a := &ateapipb.ObjectRef{Atespace: "a", Name: "x"} - b := &ateapipb.ObjectRef{Atespace: "a", Name: "x"} + a := &ateapi.ObjectRef{Atespace: "a", Name: "x"} + b := &ateapi.ObjectRef{Atespace: "a", Name: "x"} _ = a.String() // populates a's internal state, not b's tests := []struct { @@ -87,8 +87,8 @@ func TestDeepEqual(t *testing.T) { want bool }{ {name: "equal protos", got: DeepEqual(a, b), want: true}, - {name: "different protos", got: DeepEqual(a, &ateapipb.ObjectRef{Atespace: "a", Name: "y"}), want: false}, - {name: "nil protos", got: DeepEqual[*ateapipb.ObjectRef](nil, nil), want: true}, + {name: "different protos", got: DeepEqual(a, &ateapi.ObjectRef{Atespace: "a", Name: "y"}), want: false}, + {name: "nil protos", got: DeepEqual[*ateapi.ObjectRef](nil, nil), want: true}, {name: "equal non-protos", got: DeepEqual([]string{"a"}, []string{"a"}), want: true}, {name: "different non-protos", got: DeepEqual(1, 2), want: false}, } @@ -668,13 +668,13 @@ func TestValidateSandboxAssetsDir(t *testing.T) { // be masked before the text is built. func TestValidationErrorsRedactDebugRedactFields(t *testing.T) { const secret = "sk-do-not-log" - env := []*ateapipb.EnvVar{ + env := []*ateapi.EnvVar{ {Name: "API_KEY", Value: secret}, {Name: "API_KEY", Value: secret}, } errs := validate.PtrSliceUnique(context.Background(), operation.Operation{Type: operation.Create}, field.NewPath("env"), env, nil, - func(a, b *ateapipb.EnvVar) bool { return a.Name == b.Name }) + func(a, b *ateapi.EnvVar) bool { return a.Name == b.Name }) if len(errs) == 0 { t.Fatal("PtrSliceUnique found no duplicate") } @@ -700,7 +700,7 @@ func TestValidationErrorsRedactDebugRedactFields(t *testing.T) { t.Errorf("%s: message for a nil-only list = %q", name, msg) } } - if got := errs[0].BadValue.(*ateapipb.EnvVar).GetValue(); got != secret { + if got := errs[0].BadValue.(*ateapi.EnvVar).GetValue(); got != secret { t.Errorf("caller's error list was modified: value = %q", got) } } diff --git a/internal/resources/worker.go b/internal/resources/worker.go index fe949f23e3..85ba891f7c 100644 --- a/internal/resources/worker.go +++ b/internal/resources/worker.go @@ -15,14 +15,14 @@ package resources import ( - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) // AddToAllocated adjusts allocation by an assignment; sign is 1 or -1. // It returns nil when allocation reaches zero. -func AddToAllocated(total *ateapipb.WorkerResources, assignment *ateapipb.ActorAssignment, sign int64) *ateapipb.WorkerResources { +func AddToAllocated(total *ateapi.WorkerResources, assignment *ateapi.ActorAssignment, sign int64) *ateapi.WorkerResources { booked := assignment.GetResources() - out := &ateapipb.WorkerResources{ + out := &ateapi.WorkerResources{ CpuMillicores: total.GetCpuMillicores() + sign*booked.GetCpuMillicores(), MemoryBytes: total.GetMemoryBytes() + sign*booked.GetMemoryBytes(), Actors: total.GetActors() + int32(sign), @@ -36,11 +36,11 @@ func AddToAllocated(total *ateapipb.WorkerResources, assignment *ateapipb.ActorA // SumAllocated is what a set of assignments takes from a Worker, or nil for // none. Rebuilds the total rather than adjusting it, which is what the checks // holding AddToAllocated to the assignments it counts compare against. -func SumAllocated(assignments []*ateapipb.ActorAssignment) *ateapipb.WorkerResources { +func SumAllocated(assignments []*ateapi.ActorAssignment) *ateapi.WorkerResources { if len(assignments) == 0 { return nil } - total := &ateapipb.WorkerResources{Actors: int32(len(assignments))} + total := &ateapi.WorkerResources{Actors: int32(len(assignments))} for _, assignment := range assignments { total.CpuMillicores += assignment.GetResources().GetCpuMillicores() total.MemoryBytes += assignment.GetResources().GetMemoryBytes() @@ -50,8 +50,8 @@ func SumAllocated(assignments []*ateapipb.ActorAssignment) *ateapipb.WorkerResou // Free is what a Worker has left after what its Actors hold. It goes negative // once a Worker is overcommitted. -func Free(capacity, allocated *ateapipb.WorkerResources) *ateapipb.Resources { - return &ateapipb.Resources{ +func Free(capacity, allocated *ateapi.WorkerResources) *ateapi.Resources { + return &ateapi.Resources{ CpuMillicores: capacity.GetCpuMillicores() - allocated.GetCpuMillicores(), MemoryBytes: capacity.GetMemoryBytes() - allocated.GetMemoryBytes(), } diff --git a/internal/resources/worker_test.go b/internal/resources/worker_test.go index 55f0aad869..a4b33c6ecd 100644 --- a/internal/resources/worker_test.go +++ b/internal/resources/worker_test.go @@ -17,15 +17,15 @@ package resources import ( "testing" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "google.golang.org/protobuf/testing/protocmp" "github.com/google/go-cmp/cmp" ) -func assignment(uid string, cpu, mem int64) *ateapipb.ActorAssignment { - return &ateapipb.ActorAssignment{ - Actor: &ateapipb.ObjectRef{Atespace: "demo", Name: uid}, +func assignment(uid string, cpu, mem int64) *ateapi.ActorAssignment { + return &ateapi.ActorAssignment{ + Actor: &ateapi.ObjectRef{Atespace: "demo", Name: uid}, ActorUid: uid, Resources: CPUMemory(cpu, mem), } @@ -35,17 +35,17 @@ func assignment(uid string, cpu, mem int64) *ateapipb.ActorAssignment { // back to holding nothing carries no allocation at all rather than a zeroed // message: emptied and never-filled have to be the same record. func TestAddToAllocated(t *testing.T) { - var total *ateapipb.WorkerResources + var total *ateapi.WorkerResources total = AddToAllocated(total, assignment("a", 1000, 1<<30), +1) total = AddToAllocated(total, assignment("b", 500, 2<<30), +1) - want := &ateapipb.WorkerResources{Actors: 2, CpuMillicores: 1500, MemoryBytes: 3 << 30} + want := &ateapi.WorkerResources{Actors: 2, CpuMillicores: 1500, MemoryBytes: 3 << 30} if diff := cmp.Diff(want, total, protocmp.Transform()); diff != "" { t.Errorf("allocated mismatch (-want +got):\n%s", diff) } total = AddToAllocated(total, assignment("b", 500, 2<<30), -1) - want = &ateapipb.WorkerResources{Actors: 1, CpuMillicores: 1000, MemoryBytes: 1 << 30} + want = &ateapi.WorkerResources{Actors: 1, CpuMillicores: 1000, MemoryBytes: 1 << 30} if diff := cmp.Diff(want, total, protocmp.Transform()); diff != "" { t.Errorf("allocated after release mismatch (-want +got):\n%s", diff) } @@ -57,8 +57,8 @@ func TestAddToAllocated(t *testing.T) { // An Actor that declared no limits reserves nothing but still costs a slot. func TestAddToAllocatedCountsAnActorWithoutResources(t *testing.T) { - total := AddToAllocated(nil, &ateapipb.ActorAssignment{ActorUid: "a"}, +1) - want := &ateapipb.WorkerResources{Actors: 1} + total := AddToAllocated(nil, &ateapi.ActorAssignment{ActorUid: "a"}, +1) + want := &ateapi.WorkerResources{Actors: 1} if diff := cmp.Diff(want, total, protocmp.Transform()); diff != "" { t.Errorf("allocated mismatch (-want +got):\n%s", diff) } @@ -71,8 +71,8 @@ func TestSumAllocated(t *testing.T) { t.Errorf("SumAllocated(nil) = %v, want nil", got) } - got := SumAllocated([]*ateapipb.ActorAssignment{assignment("a", 1000, 1<<30), assignment("b", 500, 0)}) - want := &ateapipb.WorkerResources{Actors: 2, CpuMillicores: 1500, MemoryBytes: 1 << 30} + got := SumAllocated([]*ateapi.ActorAssignment{assignment("a", 1000, 1<<30), assignment("b", 500, 0)}) + want := &ateapi.WorkerResources{Actors: 2, CpuMillicores: 1500, MemoryBytes: 1 << 30} if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" { t.Errorf("SumAllocated() mismatch (-want +got):\n%s", diff) } diff --git a/internal/serverboot/logging_test.go b/internal/serverboot/logging_test.go index e41df9551a..eeac8cd314 100644 --- a/internal/serverboot/logging_test.go +++ b/internal/serverboot/logging_test.go @@ -27,10 +27,10 @@ import ( "go.opentelemetry.io/otel/sdk/resource" "google.golang.org/grpc" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/actorevent" "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/contextlogging" - "go.ate.dev/substrate/pkg/proto/ateapipb" ) // TestResolveLogsExporter pins the logs names on top of the shared rules: otlp @@ -284,7 +284,7 @@ func TestInitLoggerInstallsRedactingHandler(t *testing.T) { } const token = "eyJhbGciOiJSUzI1NiJ9.secret-token" - slog.Info("Handle RPC", slog.Any("resp", &ateapipb.MintActorJwtResponse{ActorJwt: token})) + slog.Info("Handle RPC", slog.Any("resp", &ateapi.MintActorJwtResponse{ActorJwt: token})) got := buf.String() if strings.Contains(got, token) { t.Fatalf("default logger wrote a debug_redact field: %s", got) diff --git a/internal/testenv/testenv.go b/internal/testenv/testenv.go index 3c0e2c8d67..eaf1ba7e9c 100644 --- a/internal/testenv/testenv.go +++ b/internal/testenv/testenv.go @@ -83,7 +83,7 @@ func fatal(err error) { // // The setup is guarded by a cross-process file lock. `go test ./...` runs the // envtest-backed packages (cmd/ateapi/internal/controlapi, -// cmd/atecontroller/internal/controllers, pkg/api/v1alpha1) as separate test +// cmd/atecontroller/internal/controllers, api/infra/k8s/ate/v1) as separate test // binaries in parallel, and each one calls this during TestMain. On a cold // cache, concurrent `setup-envtest use` invocations would otherwise race to // download, extract, and exec the *shared* kubebuilder binaries — intermittently diff --git a/internal/volume/csi/plugin.go b/internal/volume/csi/plugin.go index 49f6e9601a..c75f119bc4 100644 --- a/internal/volume/csi/plugin.go +++ b/internal/volume/csi/plugin.go @@ -25,10 +25,10 @@ import ( "sync" "github.com/container-storage-interface/spec/lib/go/csi" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" "go.ate.dev/substrate/internal/credbundle" "go.ate.dev/substrate/internal/nodepath" "go.ate.dev/substrate/internal/volume" - v1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -376,9 +376,9 @@ func getStandardCapabilities() []*csi.VolumeCapability { } // CSIDriverConfigGetter provides access to retrieve a CSIDriverConfig by name. -// Both listersv1alpha1.CSIDriverConfigLister and direct client getters implement this interface. +// Both atelisters.CSIDriverConfigLister and direct client getters implement this interface. type CSIDriverConfigGetter interface { - Get(name string) (*v1alpha1.CSIDriverConfig, error) + Get(name string) (*atev1.CSIDriverConfig, error) } // NewCSIPlugin establishes a CSI client and returns a verified Plugin instance. @@ -443,7 +443,7 @@ func newCSIPlugin(ctx context.Context, getter CSIDriverConfigGetter, driverName return csiPlugin, nil } -func resolveTLSConfig(cfg *v1alpha1.CSIDriverConfig, paths tlsPaths) (*tls.Config, error) { +func resolveTLSConfig(cfg *atev1.CSIDriverConfig, paths tlsPaths) (*tls.Config, error) { if cfg == nil || cfg.Spec.TLS == nil || !cfg.Spec.TLS.Enabled { return nil, nil } diff --git a/internal/volume/csi/tls_test.go b/internal/volume/csi/tls_test.go index 5a4060b648..7e04e562a8 100644 --- a/internal/volume/csi/tls_test.go +++ b/internal/volume/csi/tls_test.go @@ -33,8 +33,8 @@ import ( "time" "github.com/container-storage-interface/spec/lib/go/csi" - "go.ate.dev/substrate/pkg/api/v1alpha1" - listersv1alpha1 "go.ate.dev/substrate/pkg/client/listers/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" + atelisters "go.ate.dev/substrate/pkg/client/listers/ate/v1" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "k8s.io/apimachinery/pkg/labels" @@ -179,9 +179,9 @@ func startTLSServer(t *testing.T, serverCert tls.Certificate, clientCAs *x509.Ce return lis.Addr().String() } -func driverConfig(endpoint string, tlsCfg *v1alpha1.CSIDriverTLSConfig) *v1alpha1.CSIDriverConfig { - return &v1alpha1.CSIDriverConfig{ - Spec: v1alpha1.CSIDriverConfigSpec{ +func driverConfig(endpoint string, tlsCfg *atev1.CSIDriverTLSConfig) *atev1.CSIDriverConfig { + return &atev1.CSIDriverConfig{ + Spec: atev1.CSIDriverConfigSpec{ DriverName: mockDriverName, ControllerEndpoint: endpoint, TLS: tlsCfg, @@ -194,7 +194,7 @@ func driverConfig(endpoint string, tlsCfg *v1alpha1.CSIDriverTLSConfig) *v1alpha // and a real call both succeeded. func dialPlugin(t *testing.T, addr, serverName string, paths tlsPaths) (*Plugin, error) { t.Helper() - cfg := driverConfig("tcp://"+addr, &v1alpha1.CSIDriverTLSConfig{ + cfg := driverConfig("tcp://"+addr, &atev1.CSIDriverTLSConfig{ Enabled: true, UsePodIdentity: true, ServerName: serverName, @@ -203,20 +203,20 @@ func dialPlugin(t *testing.T, addr, serverName string, paths tlsPaths) (*Plugin, } // mockLister serves a single CSIDriverConfig under mockDriverName. -type mockLister struct{ cfg *v1alpha1.CSIDriverConfig } +type mockLister struct{ cfg *atev1.CSIDriverConfig } -func (m *mockLister) List(labels.Selector) ([]*v1alpha1.CSIDriverConfig, error) { - return []*v1alpha1.CSIDriverConfig{m.cfg}, nil +func (m *mockLister) List(labels.Selector) ([]*atev1.CSIDriverConfig, error) { + return []*atev1.CSIDriverConfig{m.cfg}, nil } -func (m *mockLister) Get(name string) (*v1alpha1.CSIDriverConfig, error) { +func (m *mockLister) Get(name string) (*atev1.CSIDriverConfig, error) { if name != mockDriverName { return nil, fmt.Errorf("no CSIDriverConfig named %q", name) } return m.cfg, nil } -var _ listersv1alpha1.CSIDriverConfigLister = (*mockLister)(nil) +var _ atelisters.CSIDriverConfigLister = (*mockLister)(nil) func TestMTLSSucceeds(t *testing.T) { t.Parallel() @@ -272,11 +272,11 @@ func TestResolveTLSConfigDisabled(t *testing.T) { t.Parallel() for _, tc := range []struct { name string - cfg *v1alpha1.CSIDriverConfig + cfg *atev1.CSIDriverConfig }{ {"nil config", nil}, {"no TLS block", driverConfig("", nil)}, - {"TLS disabled", driverConfig("", &v1alpha1.CSIDriverTLSConfig{Enabled: false})}, + {"TLS disabled", driverConfig("", &atev1.CSIDriverTLSConfig{Enabled: false})}, } { t.Run(tc.name, func(t *testing.T) { got, err := resolveTLSConfig(tc.cfg, defaultTLSPaths) @@ -292,7 +292,7 @@ func TestResolveTLSConfigDisabled(t *testing.T) { func TestResolveTLSConfigRejectsManualCerts(t *testing.T) { t.Parallel() - cfg := driverConfig("", &v1alpha1.CSIDriverTLSConfig{Enabled: true, UsePodIdentity: false}) + cfg := driverConfig("", &atev1.CSIDriverTLSConfig{Enabled: true, UsePodIdentity: false}) if _, err := resolveTLSConfig(cfg, defaultTLSPaths); err == nil { t.Fatal("resolveTLSConfig accepted usePodIdentity=false; manual certificates are unsupported") @@ -301,7 +301,7 @@ func TestResolveTLSConfigRejectsManualCerts(t *testing.T) { func TestResolveTLSConfigRejectsEmptyServerName(t *testing.T) { t.Parallel() - cfg := driverConfig("", &v1alpha1.CSIDriverTLSConfig{Enabled: true, UsePodIdentity: true}) + cfg := driverConfig("", &atev1.CSIDriverTLSConfig{Enabled: true, UsePodIdentity: true}) _, err := resolveTLSConfig(cfg, defaultTLSPaths) if err == nil { t.Fatal("resolveTLSConfig accepted empty serverName when TLS is enabled") @@ -317,7 +317,7 @@ func TestResolveTLSConfigFields(t *testing.T) { ca := newTestCA(t) paths := writeCreds(t, ca.clientBundle(t), ca.certPEM()) - got, err := resolveTLSConfig(driverConfig("", &v1alpha1.CSIDriverTLSConfig{ + got, err := resolveTLSConfig(driverConfig("", &atev1.CSIDriverTLSConfig{ Enabled: true, UsePodIdentity: true, ServerName: serverName, diff --git a/manifests/ate-install/components/agentgateway/kustomization.yaml b/manifests/ate-install/components/agentgateway/kustomization.yaml index 93b88aae80..1de3a53f00 100644 --- a/manifests/ate-install/components/agentgateway/kustomization.yaml +++ b/manifests/ate-install/components/agentgateway/kustomization.yaml @@ -42,7 +42,7 @@ patches: path: /spec/template/spec/containers/0 value: name: agentgateway - image: ghcr.io/kagent-dev/substrate/agentgateway:cd65181fd52e@sha256:ebebf5a7fa2a54fb524ccce1f6f74ee6e7ef22d661f22e212717fd0a68dadb33 + image: ghcr.io/kagent-dev/substrate/agentgateway:c8550278b2f2@sha256:5703311439f92a898603e2abed32edcbaf6ec659dbb4d617568cef6d9c6fc789 args: - -f - /etc/agentgateway/config.yaml @@ -118,7 +118,7 @@ patches: path: /spec/template/spec/containers/0 value: name: agentgateway - image: ghcr.io/kagent-dev/substrate/agentgateway:cd65181fd52e@sha256:ebebf5a7fa2a54fb524ccce1f6f74ee6e7ef22d661f22e212717fd0a68dadb33 + image: ghcr.io/kagent-dev/substrate/agentgateway:c8550278b2f2@sha256:5703311439f92a898603e2abed32edcbaf6ec659dbb4d617568cef6d9c6fc789 args: - -f - /etc/agentgateway/config.yaml diff --git a/manifests/ate-install/generated/ate.dev_csidriverconfigs.yaml b/manifests/ate-install/generated/ate.dev_csidriverconfigs.yaml index 492ba5c6ec..624304bee2 100644 --- a/manifests/ate-install/generated/ate.dev_csidriverconfigs.yaml +++ b/manifests/ate-install/generated/ate.dev_csidriverconfigs.yaml @@ -37,7 +37,7 @@ spec: - jsonPath: .metadata.creationTimestamp name: Age type: date - name: v1alpha1 + name: v1 schema: openAPIV3Schema: description: CSIDriverConfig is the Schema for the csidriverconfigs API diff --git a/manifests/ate-install/generated/ate.dev_sandboxconfigs.yaml b/manifests/ate-install/generated/ate.dev_sandboxconfigs.yaml index 9e0c24cfc0..89c792cb4e 100644 --- a/manifests/ate-install/generated/ate.dev_sandboxconfigs.yaml +++ b/manifests/ate-install/generated/ate.dev_sandboxconfigs.yaml @@ -40,7 +40,7 @@ spec: - jsonPath: .metadata.creationTimestamp name: Age type: date - name: v1alpha1 + name: v1 schema: openAPIV3Schema: description: |- diff --git a/manifests/ate-install/generated/ate.dev_workerpools.yaml b/manifests/ate-install/generated/ate.dev_workerpools.yaml index 568b7c2fae..bde0e0fc5b 100644 --- a/manifests/ate-install/generated/ate.dev_workerpools.yaml +++ b/manifests/ate-install/generated/ate.dev_workerpools.yaml @@ -49,7 +49,7 @@ spec: - jsonPath: .metadata.creationTimestamp name: Age type: date - name: v1alpha1 + name: v1 schema: openAPIV3Schema: description: WorkerPool is the Schema for the workerpools API diff --git a/manifests/ate-install/generated/role.yaml b/manifests/ate-install/generated/role.yaml index 9e2ab2e7b1..c383843abb 100644 --- a/manifests/ate-install/generated/role.yaml +++ b/manifests/ate-install/generated/role.yaml @@ -27,14 +27,6 @@ rules: - get - list - watch -- apiGroups: - - "" - resources: - - secrets - verbs: - - get - - list - - watch - apiGroups: - "" resources: @@ -141,6 +133,16 @@ metadata: name: ate-controller namespace: ate-system rules: +- apiGroups: + - "" + resourceNames: + - egress-mitm-ca-pool + resources: + - secrets + verbs: + - get + - list + - watch - apiGroups: - discovery.k8s.io resources: diff --git a/manifests/ate-install/role.yaml b/manifests/ate-install/role.yaml index e7efb0504b..18373babce 100644 --- a/manifests/ate-install/role.yaml +++ b/manifests/ate-install/role.yaml @@ -29,14 +29,6 @@ rules: - get - list - watch -- apiGroups: - - "" - resources: - - secrets - verbs: - - get - - list - - watch - apiGroups: - "" resources: @@ -143,6 +135,16 @@ metadata: name: ate-controller namespace: ate-system rules: +- apiGroups: + - "" + resourceNames: + - egress-mitm-ca-pool + resources: + - secrets + verbs: + - get + - list + - watch - apiGroups: - discovery.k8s.io resources: diff --git a/manifests/ate-install/sandboxconfig-gvisor.yaml b/manifests/ate-install/sandboxconfig-gvisor.yaml index 99ef0fcc6a..176c8b8fbd 100644 --- a/manifests/ate-install/sandboxconfig-gvisor.yaml +++ b/manifests/ate-install/sandboxconfig-gvisor.yaml @@ -23,7 +23,7 @@ # A bump adds a version and points defaultVersion at it. Keep the # previous version unless it has a known vulnerability: an actor restores its # memory only on the version its snapshot was taken with. -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: SandboxConfig metadata: name: gvisor-default diff --git a/manifests/ate-install/sandboxconfig-validation.yaml b/manifests/ate-install/sandboxconfig-validation.yaml index f0f3866667..ec28f4457f 100644 --- a/manifests/ate-install/sandboxconfig-validation.yaml +++ b/manifests/ate-install/sandboxconfig-validation.yaml @@ -26,7 +26,7 @@ spec: matchConstraints: resourceRules: - apiGroups: ["ate.dev"] - apiVersions: ["v1alpha1"] + apiVersions: ["v1"] operations: ["CREATE", "UPDATE"] resources: ["sandboxconfigs"] validations: diff --git a/manifests/egress-credential-injection/k8s-credential-provider.yaml b/manifests/egress-credential-injection/k8s-credential-provider.yaml index 8c75721668..328f56ac8d 100644 --- a/manifests/egress-credential-injection/k8s-credential-provider.yaml +++ b/manifests/egress-credential-injection/k8s-credential-provider.yaml @@ -74,7 +74,8 @@ spec: - "--listen-address=:50051" - "--metrics-address=:9090" - "--health-address=:9091" - - "--status-address=:4040" + # The /statusz page binds 127.0.0.1 for port-forward access. + - "--status-address=127.0.0.1:4040" # Serve with the pod's servicedns identity (SAN k8s-credential-provider.ate-system.svc) # and require the injector to present a podidentity client cert whose chain # verifies against the trust bundle. The provider additionally pins the @@ -93,8 +94,6 @@ spec: containerPort: 9090 - name: health containerPort: 9091 - - name: statusz - containerPort: 4040 readinessProbe: httpGet: path: /readyz diff --git a/manifests/microvm/sandboxconfig-microvm.yaml.tmpl b/manifests/microvm/sandboxconfig-microvm.yaml.tmpl index cd07b2ac0a..d84c205ff8 100644 --- a/manifests/microvm/sandboxconfig-microvm.yaml.tmpl +++ b/manifests/microvm/sandboxconfig-microvm.yaml.tmpl @@ -35,7 +35,7 @@ # architecture, and each cluster's bucket holds that arch's binaries at these # paths (staged by hack/install-microvm-deps.sh --install). -apiVersion: ate.dev/v1alpha1 +apiVersion: ate.dev/v1 kind: SandboxConfig metadata: name: microvm diff --git a/pkg/api/v1alpha1/gen.go b/pkg/api/v1alpha1/gen.go deleted file mode 100644 index 2dfe78a064..0000000000 --- a/pkg/api/v1alpha1/gen.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2026 Google LLC -// -// 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 v1alpha1 - -//go:generate bash ../../../hack/run-tool.sh controller-gen crd:headerFile=../../../hack/boilerplate/sh.txt object:headerFile=../../../hack/boilerplate/go.txt paths="./" output:crd:dir="../../../manifests/ate-install/generated/" -//go:generate bash ../../../hack/run-tool.sh client-gen --go-header-file=../../../hack/boilerplate/go.txt --clientset-name versioned --input-base go.ate.dev/substrate --input pkg/api/v1alpha1 --output-pkg go.ate.dev/substrate/pkg/client/clientset --output-dir ../../../pkg/client/clientset -//go:generate bash ../../../hack/run-tool.sh lister-gen --go-header-file=../../../hack/boilerplate/go.txt --output-pkg go.ate.dev/substrate/pkg/client/listers --output-dir ../../../pkg/client/listers go.ate.dev/substrate/pkg/api/v1alpha1 -//go:generate bash ../../../hack/run-tool.sh informer-gen --go-header-file=../../../hack/boilerplate/go.txt --versioned-clientset-package go.ate.dev/substrate/pkg/client/clientset/versioned --listers-package go.ate.dev/substrate/pkg/client/listers --output-pkg go.ate.dev/substrate/pkg/client/informers --output-dir ../../../pkg/client/informers go.ate.dev/substrate/pkg/api/v1alpha1 diff --git a/pkg/assetfetch/assetfetch.go b/pkg/assetfetch/assetfetch.go index 3480705ff7..24582b6642 100644 --- a/pkg/assetfetch/assetfetch.go +++ b/pkg/assetfetch/assetfetch.go @@ -42,7 +42,7 @@ import ( "regexp" "strings" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" + "go.ate.dev/substrate/api/objectstore/v1" "golang.org/x/sync/semaphore" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -218,7 +218,7 @@ type OpenFunc func(ctx context.Context) (rc io.ReadCloser, size int64, err error // // The caller checks the URI (ParseURI, CheckObjectName) first, so a refused // request reads nothing. -func (s *Stager) Fetch(ctx context.Context, req *objectstorev1.FetchAssetRequest, uri string, open OpenFunc, toStatus func(error) error) error { +func (s *Stager) Fetch(ctx context.Context, req *objectstore.FetchAssetRequest, uri string, open OpenFunc, toStatus func(error) error) error { if !sha256Pattern.MatchString(req.GetSha256()) { return status.Errorf(codes.InvalidArgument, "sha256 %q is not 64 lower-case hex characters", req.GetSha256()) } diff --git a/pkg/assetfetch/assetfetch_test.go b/pkg/assetfetch/assetfetch_test.go index c9b3a24a73..bfc8ce7b16 100644 --- a/pkg/assetfetch/assetfetch_test.go +++ b/pkg/assetfetch/assetfetch_test.go @@ -29,8 +29,8 @@ import ( "testing" "time" + "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/internal/resources" - objectstorev1 "go.ate.dev/substrate/pkg/proto/objectstorepb/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -279,7 +279,7 @@ func TestStagerFetch(t *testing.T) { t.Run("verified content replaces the caller's file", func(t *testing.T) { f := newStagerFixture(t) o := &opener{content: kernel} - err := f.stager.Fetch(t.Context(), &objectstorev1.FetchAssetRequest{ + err := f.stager.Fetch(t.Context(), &objectstore.FetchAssetRequest{ Sha256: sum(kernel), WritePath: f.dst, MaxBytes: int64(len(kernel)), }, "gs://bucket/vmlinux", o.open, testStatus) if err != nil { @@ -291,21 +291,21 @@ func TestStagerFetch(t *testing.T) { for _, tc := range []struct { name string - req func(f *stagerFixture) *objectstorev1.FetchAssetRequest + req func(f *stagerFixture) *objectstore.FetchAssetRequest opener *opener want codes.Code wantOpens int }{ { name: "sha256 mismatch", - req: func(f *stagerFixture) *objectstorev1.FetchAssetRequest { return req(sum("other"), f.dst, 1<<20) }, + req: func(f *stagerFixture) *objectstore.FetchAssetRequest { return req(sum("other"), f.dst, 1<<20) }, opener: &opener{content: kernel}, want: codes.FailedPrecondition, wantOpens: 1, }, { name: "one byte over max_bytes", - req: func(f *stagerFixture) *objectstorev1.FetchAssetRequest { + req: func(f *stagerFixture) *objectstore.FetchAssetRequest { return req(sum(kernel), f.dst, int64(len(kernel)-1)) }, opener: &opener{content: kernel}, @@ -314,7 +314,7 @@ func TestStagerFetch(t *testing.T) { }, { name: "reported size over max_bytes fails before reading", - req: func(f *stagerFixture) *objectstorev1.FetchAssetRequest { + req: func(f *stagerFixture) *objectstore.FetchAssetRequest { return req(sum(kernel), f.dst, int64(len(kernel)-1)) }, opener: &opener{content: kernel, sized: true, size: int64(len(kernel))}, @@ -323,28 +323,28 @@ func TestStagerFetch(t *testing.T) { }, { name: "reported size over the staging capacity fails before reading", - req: func(f *stagerFixture) *objectstorev1.FetchAssetRequest { return req(sum(kernel), f.dst, 1<<40) }, + req: func(f *stagerFixture) *objectstore.FetchAssetRequest { return req(sum(kernel), f.dst, 1<<40) }, opener: &opener{content: kernel, sized: true, size: 1 << 31}, want: codes.FailedPrecondition, wantOpens: 1, }, { name: "object longer than its reported size", - req: func(f *stagerFixture) *objectstorev1.FetchAssetRequest { return req(sum(kernel), f.dst, 1<<20) }, + req: func(f *stagerFixture) *objectstore.FetchAssetRequest { return req(sum(kernel), f.dst, 1<<20) }, opener: &opener{content: kernel, sized: true, size: int64(len(kernel) - 1)}, want: codes.Unavailable, wantOpens: 1, }, { name: "open error goes through toStatus", - req: func(f *stagerFixture) *objectstorev1.FetchAssetRequest { return req(sum(kernel), f.dst, 1<<20) }, + req: func(f *stagerFixture) *objectstore.FetchAssetRequest { return req(sum(kernel), f.dst, 1<<20) }, opener: &opener{err: errBackend}, want: codes.Unavailable, wantOpens: 1, }, { name: "upper-case sha256", - req: func(f *stagerFixture) *objectstorev1.FetchAssetRequest { + req: func(f *stagerFixture) *objectstore.FetchAssetRequest { return req(strings.ToUpper(sum(kernel)), f.dst, 1<<20) }, opener: &opener{content: kernel}, @@ -352,13 +352,13 @@ func TestStagerFetch(t *testing.T) { }, { name: "zero max_bytes", - req: func(f *stagerFixture) *objectstorev1.FetchAssetRequest { return req(sum(kernel), f.dst, 0) }, + req: func(f *stagerFixture) *objectstore.FetchAssetRequest { return req(sum(kernel), f.dst, 0) }, opener: &opener{content: kernel}, want: codes.InvalidArgument, }, { name: "relative write path", - req: func(f *stagerFixture) *objectstorev1.FetchAssetRequest { + req: func(f *stagerFixture) *objectstore.FetchAssetRequest { return req(sum(kernel), "static-files/x", 1<<20) }, opener: &opener{content: kernel}, @@ -366,7 +366,7 @@ func TestStagerFetch(t *testing.T) { }, { name: "write path outside root", - req: func(f *stagerFixture) *objectstorev1.FetchAssetRequest { + req: func(f *stagerFixture) *objectstore.FetchAssetRequest { return req(sum(kernel), filepath.Join(f.staging, "x"), 1<<20) }, opener: &opener{content: kernel}, @@ -374,7 +374,7 @@ func TestStagerFetch(t *testing.T) { }, { name: "missing write path", - req: func(f *stagerFixture) *objectstorev1.FetchAssetRequest { + req: func(f *stagerFixture) *objectstore.FetchAssetRequest { return req(sum(kernel), f.dst+"-missing", 1<<20) }, opener: &opener{content: kernel}, @@ -382,7 +382,7 @@ func TestStagerFetch(t *testing.T) { }, { name: "write path is a directory", - req: func(f *stagerFixture) *objectstorev1.FetchAssetRequest { + req: func(f *stagerFixture) *objectstore.FetchAssetRequest { return req(sum(kernel), filepath.Dir(f.dst), 1<<20) }, opener: &opener{content: kernel}, @@ -390,7 +390,7 @@ func TestStagerFetch(t *testing.T) { }, { name: "write path is a symlink", - req: func(f *stagerFixture) *objectstorev1.FetchAssetRequest { + req: func(f *stagerFixture) *objectstore.FetchAssetRequest { link := f.dst + "-link" if err := os.Symlink(f.dst, link); err != nil { panic(err) @@ -402,7 +402,7 @@ func TestStagerFetch(t *testing.T) { }, { name: "write path is a FIFO", - req: func(f *stagerFixture) *objectstorev1.FetchAssetRequest { + req: func(f *stagerFixture) *objectstore.FetchAssetRequest { fifo := f.dst + "-fifo" if err := syscall.Mkfifo(fifo, 0o600); err != nil { panic(err) @@ -454,8 +454,8 @@ func TestStagerFetch(t *testing.T) { }) } -func req(sha string, writePath string, maxBytes int64) *objectstorev1.FetchAssetRequest { - return &objectstorev1.FetchAssetRequest{Sha256: sha, WritePath: writePath, MaxBytes: maxBytes} +func req(sha string, writePath string, maxBytes int64) *objectstore.FetchAssetRequest { + return &objectstore.FetchAssetRequest{Sha256: sha, WritePath: writePath, MaxBytes: maxBytes} } func TestNewStagerRejectsStagingBelowRoot(t *testing.T) { diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index 1b037f499c..f0ff5ef605 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -20,7 +20,7 @@ import ( fmt "fmt" http "net/http" - apiv1alpha1 "go.ate.dev/substrate/pkg/client/clientset/versioned/typed/api/v1alpha1" + atev1 "go.ate.dev/substrate/pkg/client/clientset/versioned/typed/ate/v1" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" @@ -28,18 +28,18 @@ import ( type Interface interface { Discovery() discovery.DiscoveryInterfaces - ApiV1alpha1() apiv1alpha1.ApiV1alpha1Interface + AteV1() atev1.AteV1Interface } // Clientset contains the clients for groups. type Clientset struct { *discovery.DiscoveryClient - apiV1alpha1 *apiv1alpha1.ApiV1alpha1Client + ateV1 *atev1.AteV1Client } -// ApiV1alpha1 retrieves the ApiV1alpha1Client -func (c *Clientset) ApiV1alpha1() apiv1alpha1.ApiV1alpha1Interface { - return c.apiV1alpha1 +// AteV1 retrieves the AteV1Client +func (c *Clientset) AteV1() atev1.AteV1Interface { + return c.ateV1 } // Discovery retrieves the DiscoveryClient @@ -86,7 +86,7 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, var cs Clientset var err error - cs.apiV1alpha1, err = apiv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + cs.ateV1, err = atev1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err } @@ -111,7 +111,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { // New creates a new Clientset for the given RESTClient. func New(c rest.Interface) *Clientset { var cs Clientset - cs.apiV1alpha1 = apiv1alpha1.New(c) + cs.ateV1 = atev1.New(c) cs.DiscoveryClient = discovery.NewDiscoveryClient(c) return &cs diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index 89549e4d95..62d1499bbb 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -18,8 +18,8 @@ package fake import ( clientset "go.ate.dev/substrate/pkg/client/clientset/versioned" - apiv1alpha1 "go.ate.dev/substrate/pkg/client/clientset/versioned/typed/api/v1alpha1" - fakeapiv1alpha1 "go.ate.dev/substrate/pkg/client/clientset/versioned/typed/api/v1alpha1/fake" + atev1 "go.ate.dev/substrate/pkg/client/clientset/versioned/typed/ate/v1" + fakeatev1 "go.ate.dev/substrate/pkg/client/clientset/versioned/typed/ate/v1/fake" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" @@ -93,7 +93,7 @@ var ( _ testing.FakeClient = &Clientset{} ) -// ApiV1alpha1 retrieves the ApiV1alpha1Client -func (c *Clientset) ApiV1alpha1() apiv1alpha1.ApiV1alpha1Interface { - return &fakeapiv1alpha1.FakeApiV1alpha1{Fake: &c.Fake} +// AteV1 retrieves the AteV1Client +func (c *Clientset) AteV1() atev1.AteV1Interface { + return &fakeatev1.FakeAteV1{Fake: &c.Fake} } diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go index 1677e7f9dc..2005676176 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/pkg/client/clientset/versioned/fake/register.go @@ -17,7 +17,7 @@ package fake import ( - apiv1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -29,7 +29,7 @@ var scheme = runtime.NewScheme() var codecs = serializer.NewCodecFactory(scheme) var localSchemeBuilder = runtime.SchemeBuilder{ - apiv1alpha1.AddToScheme, + atev1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go index 38ea0d1a46..22085439b0 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/pkg/client/clientset/versioned/scheme/register.go @@ -17,7 +17,7 @@ package scheme import ( - apiv1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -29,7 +29,7 @@ var Scheme = runtime.NewScheme() var Codecs = serializer.NewCodecFactory(Scheme) var ParameterCodec = runtime.NewParameterCodec(Scheme) var localSchemeBuilder = runtime.SchemeBuilder{ - apiv1alpha1.AddToScheme, + atev1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/pkg/client/clientset/versioned/typed/api/v1alpha1/fake/fake_csidriverconfig.go b/pkg/client/clientset/versioned/typed/api/v1alpha1/fake/fake_csidriverconfig.go deleted file mode 100644 index 8a24f5f679..0000000000 --- a/pkg/client/clientset/versioned/typed/api/v1alpha1/fake/fake_csidriverconfig.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2026 Google LLC -// -// 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. - -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - v1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" - apiv1alpha1 "go.ate.dev/substrate/pkg/client/clientset/versioned/typed/api/v1alpha1" - gentype "k8s.io/client-go/gentype" -) - -// fakeCSIDriverConfigs implements CSIDriverConfigInterface -type fakeCSIDriverConfigs struct { - *gentype.FakeClientWithList[*v1alpha1.CSIDriverConfig, *v1alpha1.CSIDriverConfigList] - Fake *FakeApiV1alpha1 -} - -func newFakeCSIDriverConfigs(fake *FakeApiV1alpha1) apiv1alpha1.CSIDriverConfigInterface { - return &fakeCSIDriverConfigs{ - gentype.NewFakeClientWithList[*v1alpha1.CSIDriverConfig, *v1alpha1.CSIDriverConfigList]( - fake.Fake, - "", - v1alpha1.SchemeGroupVersion.WithResource("csidriverconfigs"), - v1alpha1.SchemeGroupVersion.WithKind("CSIDriverConfig"), - func() *v1alpha1.CSIDriverConfig { return &v1alpha1.CSIDriverConfig{} }, - func() *v1alpha1.CSIDriverConfigList { return &v1alpha1.CSIDriverConfigList{} }, - func(dst, src *v1alpha1.CSIDriverConfigList) { dst.ListMeta = src.ListMeta }, - func(list *v1alpha1.CSIDriverConfigList) []*v1alpha1.CSIDriverConfig { - return gentype.ToPointerSlice(list.Items) - }, - func(list *v1alpha1.CSIDriverConfigList, items []*v1alpha1.CSIDriverConfig) { - list.Items = gentype.FromPointerSlice(items) - }, - ), - fake, - } -} diff --git a/pkg/client/clientset/versioned/typed/api/v1alpha1/fake/fake_sandboxconfig.go b/pkg/client/clientset/versioned/typed/api/v1alpha1/fake/fake_sandboxconfig.go deleted file mode 100644 index dddc8ed559..0000000000 --- a/pkg/client/clientset/versioned/typed/api/v1alpha1/fake/fake_sandboxconfig.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2026 Google LLC -// -// 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. - -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - v1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" - apiv1alpha1 "go.ate.dev/substrate/pkg/client/clientset/versioned/typed/api/v1alpha1" - gentype "k8s.io/client-go/gentype" -) - -// fakeSandboxConfigs implements SandboxConfigInterface -type fakeSandboxConfigs struct { - *gentype.FakeClientWithList[*v1alpha1.SandboxConfig, *v1alpha1.SandboxConfigList] - Fake *FakeApiV1alpha1 -} - -func newFakeSandboxConfigs(fake *FakeApiV1alpha1) apiv1alpha1.SandboxConfigInterface { - return &fakeSandboxConfigs{ - gentype.NewFakeClientWithList[*v1alpha1.SandboxConfig, *v1alpha1.SandboxConfigList]( - fake.Fake, - "", - v1alpha1.SchemeGroupVersion.WithResource("sandboxconfigs"), - v1alpha1.SchemeGroupVersion.WithKind("SandboxConfig"), - func() *v1alpha1.SandboxConfig { return &v1alpha1.SandboxConfig{} }, - func() *v1alpha1.SandboxConfigList { return &v1alpha1.SandboxConfigList{} }, - func(dst, src *v1alpha1.SandboxConfigList) { dst.ListMeta = src.ListMeta }, - func(list *v1alpha1.SandboxConfigList) []*v1alpha1.SandboxConfig { - return gentype.ToPointerSlice(list.Items) - }, - func(list *v1alpha1.SandboxConfigList, items []*v1alpha1.SandboxConfig) { - list.Items = gentype.FromPointerSlice(items) - }, - ), - fake, - } -} diff --git a/pkg/client/clientset/versioned/typed/api/v1alpha1/fake/fake_workerpool.go b/pkg/client/clientset/versioned/typed/api/v1alpha1/fake/fake_workerpool.go deleted file mode 100644 index 9e4da458c1..0000000000 --- a/pkg/client/clientset/versioned/typed/api/v1alpha1/fake/fake_workerpool.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2026 Google LLC -// -// 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. - -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - v1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" - apiv1alpha1 "go.ate.dev/substrate/pkg/client/clientset/versioned/typed/api/v1alpha1" - gentype "k8s.io/client-go/gentype" -) - -// fakeWorkerPools implements WorkerPoolInterface -type fakeWorkerPools struct { - *gentype.FakeClientWithList[*v1alpha1.WorkerPool, *v1alpha1.WorkerPoolList] - Fake *FakeApiV1alpha1 -} - -func newFakeWorkerPools(fake *FakeApiV1alpha1, namespace string) apiv1alpha1.WorkerPoolInterface { - return &fakeWorkerPools{ - gentype.NewFakeClientWithList[*v1alpha1.WorkerPool, *v1alpha1.WorkerPoolList]( - fake.Fake, - namespace, - v1alpha1.SchemeGroupVersion.WithResource("workerpools"), - v1alpha1.SchemeGroupVersion.WithKind("WorkerPool"), - func() *v1alpha1.WorkerPool { return &v1alpha1.WorkerPool{} }, - func() *v1alpha1.WorkerPoolList { return &v1alpha1.WorkerPoolList{} }, - func(dst, src *v1alpha1.WorkerPoolList) { dst.ListMeta = src.ListMeta }, - func(list *v1alpha1.WorkerPoolList) []*v1alpha1.WorkerPool { return gentype.ToPointerSlice(list.Items) }, - func(list *v1alpha1.WorkerPoolList, items []*v1alpha1.WorkerPool) { - list.Items = gentype.FromPointerSlice(items) - }, - ), - fake, - } -} diff --git a/pkg/client/clientset/versioned/typed/api/v1alpha1/api_client.go b/pkg/client/clientset/versioned/typed/ate/v1/ate_client.go similarity index 65% rename from pkg/client/clientset/versioned/typed/api/v1alpha1/api_client.go rename to pkg/client/clientset/versioned/typed/ate/v1/ate_client.go index 16c190a986..91cf40cfaa 100644 --- a/pkg/client/clientset/versioned/typed/api/v1alpha1/api_client.go +++ b/pkg/client/clientset/versioned/typed/ate/v1/ate_client.go @@ -14,44 +14,44 @@ // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1 import ( http "net/http" - apiv1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" scheme "go.ate.dev/substrate/pkg/client/clientset/versioned/scheme" rest "k8s.io/client-go/rest" ) -type ApiV1alpha1Interface interface { +type AteV1Interface interface { RESTClient() rest.Interface CSIDriverConfigsGetter SandboxConfigsGetter WorkerPoolsGetter } -// ApiV1alpha1Client is used to interact with features provided by the api group. -type ApiV1alpha1Client struct { +// AteV1Client is used to interact with features provided by the ate group. +type AteV1Client struct { restClient rest.Interface } -func (c *ApiV1alpha1Client) CSIDriverConfigs() CSIDriverConfigInterface { +func (c *AteV1Client) CSIDriverConfigs() CSIDriverConfigInterface { return newCSIDriverConfigs(c) } -func (c *ApiV1alpha1Client) SandboxConfigs() SandboxConfigInterface { +func (c *AteV1Client) SandboxConfigs() SandboxConfigInterface { return newSandboxConfigs(c) } -func (c *ApiV1alpha1Client) WorkerPools(namespace string) WorkerPoolInterface { +func (c *AteV1Client) WorkerPools(namespace string) WorkerPoolInterface { return newWorkerPools(c, namespace) } -// NewForConfig creates a new ApiV1alpha1Client for the given config. +// NewForConfig creates a new AteV1Client for the given config. // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), // where httpClient was generated with rest.HTTPClientFor(c). -func NewForConfig(c *rest.Config) (*ApiV1alpha1Client, error) { +func NewForConfig(c *rest.Config) (*AteV1Client, error) { config := *c setConfigDefaults(&config) httpClient, err := rest.HTTPClientFor(&config) @@ -61,21 +61,21 @@ func NewForConfig(c *rest.Config) (*ApiV1alpha1Client, error) { return NewForConfigAndClient(&config, httpClient) } -// NewForConfigAndClient creates a new ApiV1alpha1Client for the given config and http client. +// NewForConfigAndClient creates a new AteV1Client for the given config and http client. // Note the http client provided takes precedence over the configured transport values. -func NewForConfigAndClient(c *rest.Config, h *http.Client) (*ApiV1alpha1Client, error) { +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*AteV1Client, error) { config := *c setConfigDefaults(&config) client, err := rest.RESTClientForConfigAndClient(&config, h) if err != nil { return nil, err } - return &ApiV1alpha1Client{client}, nil + return &AteV1Client{client}, nil } -// NewForConfigOrDie creates a new ApiV1alpha1Client for the given config and +// NewForConfigOrDie creates a new AteV1Client for the given config and // panics if there is an error in the config. -func NewForConfigOrDie(c *rest.Config) *ApiV1alpha1Client { +func NewForConfigOrDie(c *rest.Config) *AteV1Client { client, err := NewForConfig(c) if err != nil { panic(err) @@ -83,13 +83,13 @@ func NewForConfigOrDie(c *rest.Config) *ApiV1alpha1Client { return client } -// New creates a new ApiV1alpha1Client for the given RESTClient. -func New(c rest.Interface) *ApiV1alpha1Client { - return &ApiV1alpha1Client{c} +// New creates a new AteV1Client for the given RESTClient. +func New(c rest.Interface) *AteV1Client { + return &AteV1Client{c} } func setConfigDefaults(config *rest.Config) { - gv := apiv1alpha1.SchemeGroupVersion + gv := atev1.SchemeGroupVersion config.GroupVersion = &gv config.APIPath = "/apis" if config.NegotiatedSerializer == nil { @@ -103,7 +103,7 @@ func setConfigDefaults(config *rest.Config) { // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. -func (c *ApiV1alpha1Client) RESTClient() rest.Interface { +func (c *AteV1Client) RESTClient() rest.Interface { if c == nil { return nil } diff --git a/pkg/client/clientset/versioned/typed/api/v1alpha1/csidriverconfig.go b/pkg/client/clientset/versioned/typed/ate/v1/csidriverconfig.go similarity index 53% rename from pkg/client/clientset/versioned/typed/api/v1alpha1/csidriverconfig.go rename to pkg/client/clientset/versioned/typed/ate/v1/csidriverconfig.go index f03c92574f..ac19257f54 100644 --- a/pkg/client/clientset/versioned/typed/api/v1alpha1/csidriverconfig.go +++ b/pkg/client/clientset/versioned/typed/ate/v1/csidriverconfig.go @@ -14,14 +14,14 @@ // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1 import ( context "context" - apiv1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" scheme "go.ate.dev/substrate/pkg/client/clientset/versioned/scheme" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" gentype "k8s.io/client-go/gentype" @@ -35,32 +35,32 @@ type CSIDriverConfigsGetter interface { // CSIDriverConfigInterface has methods to work with CSIDriverConfig resources. type CSIDriverConfigInterface interface { - Create(ctx context.Context, cSIDriverConfig *apiv1alpha1.CSIDriverConfig, opts v1.CreateOptions) (*apiv1alpha1.CSIDriverConfig, error) - Update(ctx context.Context, cSIDriverConfig *apiv1alpha1.CSIDriverConfig, opts v1.UpdateOptions) (*apiv1alpha1.CSIDriverConfig, error) - Delete(ctx context.Context, name string, opts v1.DeleteOptions) error - DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*apiv1alpha1.CSIDriverConfig, error) - List(ctx context.Context, opts v1.ListOptions) (*apiv1alpha1.CSIDriverConfigList, error) - Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *apiv1alpha1.CSIDriverConfig, err error) + Create(ctx context.Context, cSIDriverConfig *atev1.CSIDriverConfig, opts metav1.CreateOptions) (*atev1.CSIDriverConfig, error) + Update(ctx context.Context, cSIDriverConfig *atev1.CSIDriverConfig, opts metav1.UpdateOptions) (*atev1.CSIDriverConfig, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*atev1.CSIDriverConfig, error) + List(ctx context.Context, opts metav1.ListOptions) (*atev1.CSIDriverConfigList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *atev1.CSIDriverConfig, err error) CSIDriverConfigExpansion } // cSIDriverConfigs implements CSIDriverConfigInterface type cSIDriverConfigs struct { - *gentype.ClientWithList[*apiv1alpha1.CSIDriverConfig, *apiv1alpha1.CSIDriverConfigList] + *gentype.ClientWithList[*atev1.CSIDriverConfig, *atev1.CSIDriverConfigList] } // newCSIDriverConfigs returns a CSIDriverConfigs -func newCSIDriverConfigs(c *ApiV1alpha1Client) *cSIDriverConfigs { +func newCSIDriverConfigs(c *AteV1Client) *cSIDriverConfigs { return &cSIDriverConfigs{ - gentype.NewClientWithList[*apiv1alpha1.CSIDriverConfig, *apiv1alpha1.CSIDriverConfigList]( + gentype.NewClientWithList[*atev1.CSIDriverConfig, *atev1.CSIDriverConfigList]( "csidriverconfigs", c.RESTClient(), scheme.ParameterCodec, "", - func() *apiv1alpha1.CSIDriverConfig { return &apiv1alpha1.CSIDriverConfig{} }, - func() *apiv1alpha1.CSIDriverConfigList { return &apiv1alpha1.CSIDriverConfigList{} }, + func() *atev1.CSIDriverConfig { return &atev1.CSIDriverConfig{} }, + func() *atev1.CSIDriverConfigList { return &atev1.CSIDriverConfigList{} }, ), } } diff --git a/pkg/client/clientset/versioned/typed/api/v1alpha1/doc.go b/pkg/client/clientset/versioned/typed/ate/v1/doc.go similarity index 97% rename from pkg/client/clientset/versioned/typed/api/v1alpha1/doc.go rename to pkg/client/clientset/versioned/typed/ate/v1/doc.go index f86d9e830d..760a4d9829 100644 --- a/pkg/client/clientset/versioned/typed/api/v1alpha1/doc.go +++ b/pkg/client/clientset/versioned/typed/ate/v1/doc.go @@ -15,4 +15,4 @@ // Code generated by client-gen. DO NOT EDIT. // This package has the automatically generated typed clients. -package v1alpha1 +package v1 diff --git a/pkg/client/clientset/versioned/typed/api/v1alpha1/fake/doc.go b/pkg/client/clientset/versioned/typed/ate/v1/fake/doc.go similarity index 100% rename from pkg/client/clientset/versioned/typed/api/v1alpha1/fake/doc.go rename to pkg/client/clientset/versioned/typed/ate/v1/fake/doc.go diff --git a/pkg/client/clientset/versioned/typed/api/v1alpha1/fake/fake_api_client.go b/pkg/client/clientset/versioned/typed/ate/v1/fake/fake_ate_client.go similarity index 71% rename from pkg/client/clientset/versioned/typed/api/v1alpha1/fake/fake_api_client.go rename to pkg/client/clientset/versioned/typed/ate/v1/fake/fake_ate_client.go index dd733289f5..d8ada6a46a 100644 --- a/pkg/client/clientset/versioned/typed/api/v1alpha1/fake/fake_api_client.go +++ b/pkg/client/clientset/versioned/typed/ate/v1/fake/fake_ate_client.go @@ -17,30 +17,30 @@ package fake import ( - v1alpha1 "go.ate.dev/substrate/pkg/client/clientset/versioned/typed/api/v1alpha1" + v1 "go.ate.dev/substrate/pkg/client/clientset/versioned/typed/ate/v1" rest "k8s.io/client-go/rest" testing "k8s.io/client-go/testing" ) -type FakeApiV1alpha1 struct { +type FakeAteV1 struct { *testing.Fake } -func (c *FakeApiV1alpha1) CSIDriverConfigs() v1alpha1.CSIDriverConfigInterface { +func (c *FakeAteV1) CSIDriverConfigs() v1.CSIDriverConfigInterface { return newFakeCSIDriverConfigs(c) } -func (c *FakeApiV1alpha1) SandboxConfigs() v1alpha1.SandboxConfigInterface { +func (c *FakeAteV1) SandboxConfigs() v1.SandboxConfigInterface { return newFakeSandboxConfigs(c) } -func (c *FakeApiV1alpha1) WorkerPools(namespace string) v1alpha1.WorkerPoolInterface { +func (c *FakeAteV1) WorkerPools(namespace string) v1.WorkerPoolInterface { return newFakeWorkerPools(c, namespace) } // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. -func (c *FakeApiV1alpha1) RESTClient() rest.Interface { +func (c *FakeAteV1) RESTClient() rest.Interface { var ret *rest.RESTClient return ret } diff --git a/pkg/client/clientset/versioned/typed/ate/v1/fake/fake_csidriverconfig.go b/pkg/client/clientset/versioned/typed/ate/v1/fake/fake_csidriverconfig.go new file mode 100644 index 0000000000..94a4b96043 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/ate/v1/fake/fake_csidriverconfig.go @@ -0,0 +1,48 @@ +// Copyright 2026 Google LLC +// +// 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. + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" + atev1 "go.ate.dev/substrate/pkg/client/clientset/versioned/typed/ate/v1" + gentype "k8s.io/client-go/gentype" +) + +// fakeCSIDriverConfigs implements CSIDriverConfigInterface +type fakeCSIDriverConfigs struct { + *gentype.FakeClientWithList[*v1.CSIDriverConfig, *v1.CSIDriverConfigList] + Fake *FakeAteV1 +} + +func newFakeCSIDriverConfigs(fake *FakeAteV1) atev1.CSIDriverConfigInterface { + return &fakeCSIDriverConfigs{ + gentype.NewFakeClientWithList[*v1.CSIDriverConfig, *v1.CSIDriverConfigList]( + fake.Fake, + "", + v1.SchemeGroupVersion.WithResource("csidriverconfigs"), + v1.SchemeGroupVersion.WithKind("CSIDriverConfig"), + func() *v1.CSIDriverConfig { return &v1.CSIDriverConfig{} }, + func() *v1.CSIDriverConfigList { return &v1.CSIDriverConfigList{} }, + func(dst, src *v1.CSIDriverConfigList) { dst.ListMeta = src.ListMeta }, + func(list *v1.CSIDriverConfigList) []*v1.CSIDriverConfig { return gentype.ToPointerSlice(list.Items) }, + func(list *v1.CSIDriverConfigList, items []*v1.CSIDriverConfig) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/pkg/client/clientset/versioned/typed/ate/v1/fake/fake_sandboxconfig.go b/pkg/client/clientset/versioned/typed/ate/v1/fake/fake_sandboxconfig.go new file mode 100644 index 0000000000..8c741b7eaa --- /dev/null +++ b/pkg/client/clientset/versioned/typed/ate/v1/fake/fake_sandboxconfig.go @@ -0,0 +1,48 @@ +// Copyright 2026 Google LLC +// +// 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. + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" + atev1 "go.ate.dev/substrate/pkg/client/clientset/versioned/typed/ate/v1" + gentype "k8s.io/client-go/gentype" +) + +// fakeSandboxConfigs implements SandboxConfigInterface +type fakeSandboxConfigs struct { + *gentype.FakeClientWithList[*v1.SandboxConfig, *v1.SandboxConfigList] + Fake *FakeAteV1 +} + +func newFakeSandboxConfigs(fake *FakeAteV1) atev1.SandboxConfigInterface { + return &fakeSandboxConfigs{ + gentype.NewFakeClientWithList[*v1.SandboxConfig, *v1.SandboxConfigList]( + fake.Fake, + "", + v1.SchemeGroupVersion.WithResource("sandboxconfigs"), + v1.SchemeGroupVersion.WithKind("SandboxConfig"), + func() *v1.SandboxConfig { return &v1.SandboxConfig{} }, + func() *v1.SandboxConfigList { return &v1.SandboxConfigList{} }, + func(dst, src *v1.SandboxConfigList) { dst.ListMeta = src.ListMeta }, + func(list *v1.SandboxConfigList) []*v1.SandboxConfig { return gentype.ToPointerSlice(list.Items) }, + func(list *v1.SandboxConfigList, items []*v1.SandboxConfig) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/pkg/client/clientset/versioned/typed/ate/v1/fake/fake_workerpool.go b/pkg/client/clientset/versioned/typed/ate/v1/fake/fake_workerpool.go new file mode 100644 index 0000000000..4f6fd3e52e --- /dev/null +++ b/pkg/client/clientset/versioned/typed/ate/v1/fake/fake_workerpool.go @@ -0,0 +1,46 @@ +// Copyright 2026 Google LLC +// +// 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. + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" + atev1 "go.ate.dev/substrate/pkg/client/clientset/versioned/typed/ate/v1" + gentype "k8s.io/client-go/gentype" +) + +// fakeWorkerPools implements WorkerPoolInterface +type fakeWorkerPools struct { + *gentype.FakeClientWithList[*v1.WorkerPool, *v1.WorkerPoolList] + Fake *FakeAteV1 +} + +func newFakeWorkerPools(fake *FakeAteV1, namespace string) atev1.WorkerPoolInterface { + return &fakeWorkerPools{ + gentype.NewFakeClientWithList[*v1.WorkerPool, *v1.WorkerPoolList]( + fake.Fake, + namespace, + v1.SchemeGroupVersion.WithResource("workerpools"), + v1.SchemeGroupVersion.WithKind("WorkerPool"), + func() *v1.WorkerPool { return &v1.WorkerPool{} }, + func() *v1.WorkerPoolList { return &v1.WorkerPoolList{} }, + func(dst, src *v1.WorkerPoolList) { dst.ListMeta = src.ListMeta }, + func(list *v1.WorkerPoolList) []*v1.WorkerPool { return gentype.ToPointerSlice(list.Items) }, + func(list *v1.WorkerPoolList, items []*v1.WorkerPool) { list.Items = gentype.FromPointerSlice(items) }, + ), + fake, + } +} diff --git a/pkg/client/clientset/versioned/typed/api/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/ate/v1/generated_expansion.go similarity index 97% rename from pkg/client/clientset/versioned/typed/api/v1alpha1/generated_expansion.go rename to pkg/client/clientset/versioned/typed/ate/v1/generated_expansion.go index 05b7654ad5..bb67239dba 100644 --- a/pkg/client/clientset/versioned/typed/api/v1alpha1/generated_expansion.go +++ b/pkg/client/clientset/versioned/typed/ate/v1/generated_expansion.go @@ -14,7 +14,7 @@ // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1 type CSIDriverConfigExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/api/v1alpha1/sandboxconfig.go b/pkg/client/clientset/versioned/typed/ate/v1/sandboxconfig.go similarity index 53% rename from pkg/client/clientset/versioned/typed/api/v1alpha1/sandboxconfig.go rename to pkg/client/clientset/versioned/typed/ate/v1/sandboxconfig.go index 6056bea5e8..bbb8666425 100644 --- a/pkg/client/clientset/versioned/typed/api/v1alpha1/sandboxconfig.go +++ b/pkg/client/clientset/versioned/typed/ate/v1/sandboxconfig.go @@ -14,14 +14,14 @@ // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1 import ( context "context" - apiv1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" scheme "go.ate.dev/substrate/pkg/client/clientset/versioned/scheme" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" gentype "k8s.io/client-go/gentype" @@ -35,32 +35,32 @@ type SandboxConfigsGetter interface { // SandboxConfigInterface has methods to work with SandboxConfig resources. type SandboxConfigInterface interface { - Create(ctx context.Context, sandboxConfig *apiv1alpha1.SandboxConfig, opts v1.CreateOptions) (*apiv1alpha1.SandboxConfig, error) - Update(ctx context.Context, sandboxConfig *apiv1alpha1.SandboxConfig, opts v1.UpdateOptions) (*apiv1alpha1.SandboxConfig, error) - Delete(ctx context.Context, name string, opts v1.DeleteOptions) error - DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*apiv1alpha1.SandboxConfig, error) - List(ctx context.Context, opts v1.ListOptions) (*apiv1alpha1.SandboxConfigList, error) - Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *apiv1alpha1.SandboxConfig, err error) + Create(ctx context.Context, sandboxConfig *atev1.SandboxConfig, opts metav1.CreateOptions) (*atev1.SandboxConfig, error) + Update(ctx context.Context, sandboxConfig *atev1.SandboxConfig, opts metav1.UpdateOptions) (*atev1.SandboxConfig, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*atev1.SandboxConfig, error) + List(ctx context.Context, opts metav1.ListOptions) (*atev1.SandboxConfigList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *atev1.SandboxConfig, err error) SandboxConfigExpansion } // sandboxConfigs implements SandboxConfigInterface type sandboxConfigs struct { - *gentype.ClientWithList[*apiv1alpha1.SandboxConfig, *apiv1alpha1.SandboxConfigList] + *gentype.ClientWithList[*atev1.SandboxConfig, *atev1.SandboxConfigList] } // newSandboxConfigs returns a SandboxConfigs -func newSandboxConfigs(c *ApiV1alpha1Client) *sandboxConfigs { +func newSandboxConfigs(c *AteV1Client) *sandboxConfigs { return &sandboxConfigs{ - gentype.NewClientWithList[*apiv1alpha1.SandboxConfig, *apiv1alpha1.SandboxConfigList]( + gentype.NewClientWithList[*atev1.SandboxConfig, *atev1.SandboxConfigList]( "sandboxconfigs", c.RESTClient(), scheme.ParameterCodec, "", - func() *apiv1alpha1.SandboxConfig { return &apiv1alpha1.SandboxConfig{} }, - func() *apiv1alpha1.SandboxConfigList { return &apiv1alpha1.SandboxConfigList{} }, + func() *atev1.SandboxConfig { return &atev1.SandboxConfig{} }, + func() *atev1.SandboxConfigList { return &atev1.SandboxConfigList{} }, ), } } diff --git a/pkg/client/clientset/versioned/typed/api/v1alpha1/workerpool.go b/pkg/client/clientset/versioned/typed/ate/v1/workerpool.go similarity index 53% rename from pkg/client/clientset/versioned/typed/api/v1alpha1/workerpool.go rename to pkg/client/clientset/versioned/typed/ate/v1/workerpool.go index 539f2be3a1..41df1eaac2 100644 --- a/pkg/client/clientset/versioned/typed/api/v1alpha1/workerpool.go +++ b/pkg/client/clientset/versioned/typed/ate/v1/workerpool.go @@ -14,14 +14,14 @@ // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1 import ( context "context" - apiv1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" scheme "go.ate.dev/substrate/pkg/client/clientset/versioned/scheme" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" gentype "k8s.io/client-go/gentype" @@ -35,34 +35,34 @@ type WorkerPoolsGetter interface { // WorkerPoolInterface has methods to work with WorkerPool resources. type WorkerPoolInterface interface { - Create(ctx context.Context, workerPool *apiv1alpha1.WorkerPool, opts v1.CreateOptions) (*apiv1alpha1.WorkerPool, error) - Update(ctx context.Context, workerPool *apiv1alpha1.WorkerPool, opts v1.UpdateOptions) (*apiv1alpha1.WorkerPool, error) + Create(ctx context.Context, workerPool *atev1.WorkerPool, opts metav1.CreateOptions) (*atev1.WorkerPool, error) + Update(ctx context.Context, workerPool *atev1.WorkerPool, opts metav1.UpdateOptions) (*atev1.WorkerPool, error) // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). - UpdateStatus(ctx context.Context, workerPool *apiv1alpha1.WorkerPool, opts v1.UpdateOptions) (*apiv1alpha1.WorkerPool, error) - Delete(ctx context.Context, name string, opts v1.DeleteOptions) error - DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*apiv1alpha1.WorkerPool, error) - List(ctx context.Context, opts v1.ListOptions) (*apiv1alpha1.WorkerPoolList, error) - Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *apiv1alpha1.WorkerPool, err error) + UpdateStatus(ctx context.Context, workerPool *atev1.WorkerPool, opts metav1.UpdateOptions) (*atev1.WorkerPool, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*atev1.WorkerPool, error) + List(ctx context.Context, opts metav1.ListOptions) (*atev1.WorkerPoolList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *atev1.WorkerPool, err error) WorkerPoolExpansion } // workerPools implements WorkerPoolInterface type workerPools struct { - *gentype.ClientWithList[*apiv1alpha1.WorkerPool, *apiv1alpha1.WorkerPoolList] + *gentype.ClientWithList[*atev1.WorkerPool, *atev1.WorkerPoolList] } // newWorkerPools returns a WorkerPools -func newWorkerPools(c *ApiV1alpha1Client, namespace string) *workerPools { +func newWorkerPools(c *AteV1Client, namespace string) *workerPools { return &workerPools{ - gentype.NewClientWithList[*apiv1alpha1.WorkerPool, *apiv1alpha1.WorkerPoolList]( + gentype.NewClientWithList[*atev1.WorkerPool, *atev1.WorkerPoolList]( "workerpools", c.RESTClient(), scheme.ParameterCodec, namespace, - func() *apiv1alpha1.WorkerPool { return &apiv1alpha1.WorkerPool{} }, - func() *apiv1alpha1.WorkerPoolList { return &apiv1alpha1.WorkerPoolList{} }, + func() *atev1.WorkerPool { return &atev1.WorkerPool{} }, + func() *atev1.WorkerPoolList { return &atev1.WorkerPoolList{} }, ), } } diff --git a/pkg/client/informers/externalversions/api/interface.go b/pkg/client/informers/externalversions/ate/interface.go similarity index 77% rename from pkg/client/informers/externalversions/api/interface.go rename to pkg/client/informers/externalversions/ate/interface.go index c994543342..d4cc0c4fcd 100644 --- a/pkg/client/informers/externalversions/api/interface.go +++ b/pkg/client/informers/externalversions/ate/interface.go @@ -14,17 +14,17 @@ // Code generated by informer-gen. DO NOT EDIT. -package api +package ate import ( - v1alpha1 "go.ate.dev/substrate/pkg/client/informers/externalversions/api/v1alpha1" + v1 "go.ate.dev/substrate/pkg/client/informers/externalversions/ate/v1" internalinterfaces "go.ate.dev/substrate/pkg/client/informers/externalversions/internalinterfaces" ) // Interface provides access to each of this group's versions. type Interface interface { - // V1alpha1 provides access to shared informers for resources in V1alpha1. - V1alpha1() v1alpha1.Interface + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface } type group struct { @@ -38,7 +38,7 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } -// V1alpha1 returns a new v1alpha1.Interface. -func (g *group) V1alpha1() v1alpha1.Interface { - return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) } diff --git a/pkg/client/informers/externalversions/api/v1alpha1/csidriverconfig.go b/pkg/client/informers/externalversions/ate/v1/csidriverconfig.go similarity index 82% rename from pkg/client/informers/externalversions/api/v1alpha1/csidriverconfig.go rename to pkg/client/informers/externalversions/ate/v1/csidriverconfig.go index ec26c674bc..659f5ee94c 100644 --- a/pkg/client/informers/externalversions/api/v1alpha1/csidriverconfig.go +++ b/pkg/client/informers/externalversions/ate/v1/csidriverconfig.go @@ -14,17 +14,17 @@ // Code generated by informer-gen. DO NOT EDIT. -package v1alpha1 +package v1 import ( context "context" time "time" - pkgapiv1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + k8satev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" versioned "go.ate.dev/substrate/pkg/client/clientset/versioned" internalinterfaces "go.ate.dev/substrate/pkg/client/informers/externalversions/internalinterfaces" - apiv1alpha1 "go.ate.dev/substrate/pkg/client/listers/api/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + atev1 "go.ate.dev/substrate/pkg/client/listers/ate/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" @@ -35,7 +35,7 @@ import ( // CSIDriverConfigs. Prefer using the type-safe variant (see [TypedCSIDriverConfigInformer]). type CSIDriverConfigInformer interface { Informer() cache.SharedIndexInformer - Lister() apiv1alpha1.CSIDriverConfigLister + Lister() atev1.CSIDriverConfigLister } // TypedCSIDriverConfigInformer provides access to a shared informer and lister for @@ -44,27 +44,27 @@ type CSIDriverConfigInformer interface { type TypedCSIDriverConfigInformer interface { Informer() cache.SharedIndexInformer TypedInformer() CSIDriverConfigIndexInformer - Lister() apiv1alpha1.CSIDriverConfigLister + Lister() atev1.CSIDriverConfigLister } // CSIDriverConfigIndexInformer is a wrapper around the underlying [cache.SharedIndexInformer] // with type-safe variants of several methods. -type CSIDriverConfigIndexInformer cache.TypedSharedIndexInformer[*pkgapiv1alpha1.CSIDriverConfig] +type CSIDriverConfigIndexInformer cache.TypedSharedIndexInformer[*k8satev1.CSIDriverConfig] // CSIDriverConfigHandlerFuncs is a specialization of [cache.TypedResourceEventHandlerFuncs] for CSIDriverConfig. -type CSIDriverConfigHandlerFuncs = cache.TypedResourceEventHandlerFuncs[*pkgapiv1alpha1.CSIDriverConfig] +type CSIDriverConfigHandlerFuncs = cache.TypedResourceEventHandlerFuncs[*k8satev1.CSIDriverConfig] // CSIDriverConfigDetailedHandlerFuncs is a specialization of [cache.TypedResourceEventHandlerDetailedFuncs] for CSIDriverConfig. -type CSIDriverConfigDetailedHandlerFuncs = cache.TypedResourceEventHandlerDetailedFuncs[*pkgapiv1alpha1.CSIDriverConfig] +type CSIDriverConfigDetailedHandlerFuncs = cache.TypedResourceEventHandlerDetailedFuncs[*k8satev1.CSIDriverConfig] // CSIDriverConfigFilteringHandler is a specialization of [cache.TypedFilteringResourceEventHandler] for CSIDriverConfig. -type CSIDriverConfigFilteringHandler = cache.TypedFilteringResourceEventHandler[*pkgapiv1alpha1.CSIDriverConfig] +type CSIDriverConfigFilteringHandler = cache.TypedFilteringResourceEventHandler[*k8satev1.CSIDriverConfig] // CSIDriverConfigIndexers is a specialization of [cache.TypedIndexers] for CSIDriverConfig. -type CSIDriverConfigIndexers = cache.TypedIndexers[*pkgapiv1alpha1.CSIDriverConfig] +type CSIDriverConfigIndexers = cache.TypedIndexers[*k8satev1.CSIDriverConfig] // DeletedCSIDriverConfig is a specialization of [cache.DeletedObject] for CSIDriverConfig. -type DeletedCSIDriverConfig = cache.DeletedObject[*pkgapiv1alpha1.CSIDriverConfig] +type DeletedCSIDriverConfig = cache.DeletedObject[*k8satev1.CSIDriverConfig] type cSIDriverConfigInformer struct { factory internalinterfaces.SharedInformerFactory @@ -113,37 +113,37 @@ func NewCSIDriverConfigInformerWithOptions(client versioned.Interface, options i // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewTypedCSIDriverConfigInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) CSIDriverConfigIndexInformer { - gvr := schema.GroupVersionResource{Group: "api", Version: "v1alpha1", Resource: "csidriverconfigs"} + gvr := schema.GroupVersionResource{Group: "ate", Version: "v1", Resource: "csidriverconfigs"} identifier := options.InformerName.WithResource(gvr) tweakListOptions := options.TweakListOptions - return cache.NewTypedSharedIndexInformer[*pkgapiv1alpha1.CSIDriverConfig](cache.NewSharedIndexInformerWithOptions( + return cache.NewTypedSharedIndexInformer[*k8satev1.CSIDriverConfig](cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { tweakListOptions(&opts) } - return client.ApiV1alpha1().CSIDriverConfigs().List(context.Background(), opts) + return client.AteV1().CSIDriverConfigs().List(context.Background(), opts) }, - WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&opts) } - return client.ApiV1alpha1().CSIDriverConfigs().Watch(context.Background(), opts) + return client.AteV1().CSIDriverConfigs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { tweakListOptions(&opts) } - return client.ApiV1alpha1().CSIDriverConfigs().List(ctx, opts) + return client.AteV1().CSIDriverConfigs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&opts) } - return client.ApiV1alpha1().CSIDriverConfigs().Watch(ctx, opts) + return client.AteV1().CSIDriverConfigs().Watch(ctx, opts) }, }, client), - &pkgapiv1alpha1.CSIDriverConfig{}, + &k8satev1.CSIDriverConfig{}, cache.SharedIndexInformerOptions{ ResyncPeriod: options.ResyncPeriod, Indexers: options.Indexers, @@ -161,11 +161,11 @@ func (f *cSIDriverConfigInformer) Informer() cache.SharedIndexInformer { } func (f *cSIDriverConfigInformer) TypedInformer() CSIDriverConfigIndexInformer { - return cache.NewTypedSharedIndexInformer[*pkgapiv1alpha1.CSIDriverConfig](f.factory.InformerFor(&pkgapiv1alpha1.CSIDriverConfig{}, f.defaultInformer)) + return cache.NewTypedSharedIndexInformer[*k8satev1.CSIDriverConfig](f.factory.InformerFor(&k8satev1.CSIDriverConfig{}, f.defaultInformer)) } -func (f *cSIDriverConfigInformer) Lister() apiv1alpha1.CSIDriverConfigLister { - return apiv1alpha1.NewCSIDriverConfigLister(f.Informer().GetIndexer()) +func (f *cSIDriverConfigInformer) Lister() atev1.CSIDriverConfigLister { + return atev1.NewCSIDriverConfigLister(f.Informer().GetIndexer()) } // ToTypedCSIDriverConfigInformer converts an untyped informer into a TypedCSIDriverConfigInformer. @@ -187,7 +187,7 @@ type cSIDriverConfigTypedInformerAdapter struct { } func (a *cSIDriverConfigTypedInformerAdapter) TypedInformer() CSIDriverConfigIndexInformer { - return cache.NewTypedSharedIndexInformer[*pkgapiv1alpha1.CSIDriverConfig](a.Informer()) + return cache.NewTypedSharedIndexInformer[*k8satev1.CSIDriverConfig](a.Informer()) } // ToCSIDriverConfigIndexInformer converts an untyped informer into a CSIDriverConfigIndexInformer. @@ -201,5 +201,5 @@ func ToCSIDriverConfigIndexInformer(informer cache.SharedIndexInformer) CSIDrive if informer, ok := informer.(CSIDriverConfigIndexInformer); ok { return informer } - return cache.NewTypedSharedIndexInformer[*pkgapiv1alpha1.CSIDriverConfig](informer) + return cache.NewTypedSharedIndexInformer[*k8satev1.CSIDriverConfig](informer) } diff --git a/pkg/client/informers/externalversions/api/v1alpha1/interface.go b/pkg/client/informers/externalversions/ate/v1/interface.go similarity index 99% rename from pkg/client/informers/externalversions/api/v1alpha1/interface.go rename to pkg/client/informers/externalversions/ate/v1/interface.go index 305eff420d..01b8f98641 100644 --- a/pkg/client/informers/externalversions/api/v1alpha1/interface.go +++ b/pkg/client/informers/externalversions/ate/v1/interface.go @@ -14,7 +14,7 @@ // Code generated by informer-gen. DO NOT EDIT. -package v1alpha1 +package v1 import ( internalinterfaces "go.ate.dev/substrate/pkg/client/informers/externalversions/internalinterfaces" diff --git a/pkg/client/informers/externalversions/api/v1alpha1/sandboxconfig.go b/pkg/client/informers/externalversions/ate/v1/sandboxconfig.go similarity index 82% rename from pkg/client/informers/externalversions/api/v1alpha1/sandboxconfig.go rename to pkg/client/informers/externalversions/ate/v1/sandboxconfig.go index 747ae5d1a1..fba80dcfdf 100644 --- a/pkg/client/informers/externalversions/api/v1alpha1/sandboxconfig.go +++ b/pkg/client/informers/externalversions/ate/v1/sandboxconfig.go @@ -14,17 +14,17 @@ // Code generated by informer-gen. DO NOT EDIT. -package v1alpha1 +package v1 import ( context "context" time "time" - pkgapiv1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + k8satev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" versioned "go.ate.dev/substrate/pkg/client/clientset/versioned" internalinterfaces "go.ate.dev/substrate/pkg/client/informers/externalversions/internalinterfaces" - apiv1alpha1 "go.ate.dev/substrate/pkg/client/listers/api/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + atev1 "go.ate.dev/substrate/pkg/client/listers/ate/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" @@ -35,7 +35,7 @@ import ( // SandboxConfigs. Prefer using the type-safe variant (see [TypedSandboxConfigInformer]). type SandboxConfigInformer interface { Informer() cache.SharedIndexInformer - Lister() apiv1alpha1.SandboxConfigLister + Lister() atev1.SandboxConfigLister } // TypedSandboxConfigInformer provides access to a shared informer and lister for @@ -44,27 +44,27 @@ type SandboxConfigInformer interface { type TypedSandboxConfigInformer interface { Informer() cache.SharedIndexInformer TypedInformer() SandboxConfigIndexInformer - Lister() apiv1alpha1.SandboxConfigLister + Lister() atev1.SandboxConfigLister } // SandboxConfigIndexInformer is a wrapper around the underlying [cache.SharedIndexInformer] // with type-safe variants of several methods. -type SandboxConfigIndexInformer cache.TypedSharedIndexInformer[*pkgapiv1alpha1.SandboxConfig] +type SandboxConfigIndexInformer cache.TypedSharedIndexInformer[*k8satev1.SandboxConfig] // SandboxConfigHandlerFuncs is a specialization of [cache.TypedResourceEventHandlerFuncs] for SandboxConfig. -type SandboxConfigHandlerFuncs = cache.TypedResourceEventHandlerFuncs[*pkgapiv1alpha1.SandboxConfig] +type SandboxConfigHandlerFuncs = cache.TypedResourceEventHandlerFuncs[*k8satev1.SandboxConfig] // SandboxConfigDetailedHandlerFuncs is a specialization of [cache.TypedResourceEventHandlerDetailedFuncs] for SandboxConfig. -type SandboxConfigDetailedHandlerFuncs = cache.TypedResourceEventHandlerDetailedFuncs[*pkgapiv1alpha1.SandboxConfig] +type SandboxConfigDetailedHandlerFuncs = cache.TypedResourceEventHandlerDetailedFuncs[*k8satev1.SandboxConfig] // SandboxConfigFilteringHandler is a specialization of [cache.TypedFilteringResourceEventHandler] for SandboxConfig. -type SandboxConfigFilteringHandler = cache.TypedFilteringResourceEventHandler[*pkgapiv1alpha1.SandboxConfig] +type SandboxConfigFilteringHandler = cache.TypedFilteringResourceEventHandler[*k8satev1.SandboxConfig] // SandboxConfigIndexers is a specialization of [cache.TypedIndexers] for SandboxConfig. -type SandboxConfigIndexers = cache.TypedIndexers[*pkgapiv1alpha1.SandboxConfig] +type SandboxConfigIndexers = cache.TypedIndexers[*k8satev1.SandboxConfig] // DeletedSandboxConfig is a specialization of [cache.DeletedObject] for SandboxConfig. -type DeletedSandboxConfig = cache.DeletedObject[*pkgapiv1alpha1.SandboxConfig] +type DeletedSandboxConfig = cache.DeletedObject[*k8satev1.SandboxConfig] type sandboxConfigInformer struct { factory internalinterfaces.SharedInformerFactory @@ -113,37 +113,37 @@ func NewSandboxConfigInformerWithOptions(client versioned.Interface, options int // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewTypedSandboxConfigInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) SandboxConfigIndexInformer { - gvr := schema.GroupVersionResource{Group: "api", Version: "v1alpha1", Resource: "sandboxconfigs"} + gvr := schema.GroupVersionResource{Group: "ate", Version: "v1", Resource: "sandboxconfigs"} identifier := options.InformerName.WithResource(gvr) tweakListOptions := options.TweakListOptions - return cache.NewTypedSharedIndexInformer[*pkgapiv1alpha1.SandboxConfig](cache.NewSharedIndexInformerWithOptions( + return cache.NewTypedSharedIndexInformer[*k8satev1.SandboxConfig](cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { tweakListOptions(&opts) } - return client.ApiV1alpha1().SandboxConfigs().List(context.Background(), opts) + return client.AteV1().SandboxConfigs().List(context.Background(), opts) }, - WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&opts) } - return client.ApiV1alpha1().SandboxConfigs().Watch(context.Background(), opts) + return client.AteV1().SandboxConfigs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { tweakListOptions(&opts) } - return client.ApiV1alpha1().SandboxConfigs().List(ctx, opts) + return client.AteV1().SandboxConfigs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&opts) } - return client.ApiV1alpha1().SandboxConfigs().Watch(ctx, opts) + return client.AteV1().SandboxConfigs().Watch(ctx, opts) }, }, client), - &pkgapiv1alpha1.SandboxConfig{}, + &k8satev1.SandboxConfig{}, cache.SharedIndexInformerOptions{ ResyncPeriod: options.ResyncPeriod, Indexers: options.Indexers, @@ -161,11 +161,11 @@ func (f *sandboxConfigInformer) Informer() cache.SharedIndexInformer { } func (f *sandboxConfigInformer) TypedInformer() SandboxConfigIndexInformer { - return cache.NewTypedSharedIndexInformer[*pkgapiv1alpha1.SandboxConfig](f.factory.InformerFor(&pkgapiv1alpha1.SandboxConfig{}, f.defaultInformer)) + return cache.NewTypedSharedIndexInformer[*k8satev1.SandboxConfig](f.factory.InformerFor(&k8satev1.SandboxConfig{}, f.defaultInformer)) } -func (f *sandboxConfigInformer) Lister() apiv1alpha1.SandboxConfigLister { - return apiv1alpha1.NewSandboxConfigLister(f.Informer().GetIndexer()) +func (f *sandboxConfigInformer) Lister() atev1.SandboxConfigLister { + return atev1.NewSandboxConfigLister(f.Informer().GetIndexer()) } // ToTypedSandboxConfigInformer converts an untyped informer into a TypedSandboxConfigInformer. @@ -187,7 +187,7 @@ type sandboxConfigTypedInformerAdapter struct { } func (a *sandboxConfigTypedInformerAdapter) TypedInformer() SandboxConfigIndexInformer { - return cache.NewTypedSharedIndexInformer[*pkgapiv1alpha1.SandboxConfig](a.Informer()) + return cache.NewTypedSharedIndexInformer[*k8satev1.SandboxConfig](a.Informer()) } // ToSandboxConfigIndexInformer converts an untyped informer into a SandboxConfigIndexInformer. @@ -201,5 +201,5 @@ func ToSandboxConfigIndexInformer(informer cache.SharedIndexInformer) SandboxCon if informer, ok := informer.(SandboxConfigIndexInformer); ok { return informer } - return cache.NewTypedSharedIndexInformer[*pkgapiv1alpha1.SandboxConfig](informer) + return cache.NewTypedSharedIndexInformer[*k8satev1.SandboxConfig](informer) } diff --git a/pkg/client/informers/externalversions/api/v1alpha1/workerpool.go b/pkg/client/informers/externalversions/ate/v1/workerpool.go similarity index 82% rename from pkg/client/informers/externalversions/api/v1alpha1/workerpool.go rename to pkg/client/informers/externalversions/ate/v1/workerpool.go index 27a9214c52..dc75d595b1 100644 --- a/pkg/client/informers/externalversions/api/v1alpha1/workerpool.go +++ b/pkg/client/informers/externalversions/ate/v1/workerpool.go @@ -14,17 +14,17 @@ // Code generated by informer-gen. DO NOT EDIT. -package v1alpha1 +package v1 import ( context "context" time "time" - pkgapiv1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + k8satev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" versioned "go.ate.dev/substrate/pkg/client/clientset/versioned" internalinterfaces "go.ate.dev/substrate/pkg/client/informers/externalversions/internalinterfaces" - apiv1alpha1 "go.ate.dev/substrate/pkg/client/listers/api/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + atev1 "go.ate.dev/substrate/pkg/client/listers/ate/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" @@ -35,7 +35,7 @@ import ( // WorkerPools. Prefer using the type-safe variant (see [TypedWorkerPoolInformer]). type WorkerPoolInformer interface { Informer() cache.SharedIndexInformer - Lister() apiv1alpha1.WorkerPoolLister + Lister() atev1.WorkerPoolLister } // TypedWorkerPoolInformer provides access to a shared informer and lister for @@ -44,27 +44,27 @@ type WorkerPoolInformer interface { type TypedWorkerPoolInformer interface { Informer() cache.SharedIndexInformer TypedInformer() WorkerPoolIndexInformer - Lister() apiv1alpha1.WorkerPoolLister + Lister() atev1.WorkerPoolLister } // WorkerPoolIndexInformer is a wrapper around the underlying [cache.SharedIndexInformer] // with type-safe variants of several methods. -type WorkerPoolIndexInformer cache.TypedSharedIndexInformer[*pkgapiv1alpha1.WorkerPool] +type WorkerPoolIndexInformer cache.TypedSharedIndexInformer[*k8satev1.WorkerPool] // WorkerPoolHandlerFuncs is a specialization of [cache.TypedResourceEventHandlerFuncs] for WorkerPool. -type WorkerPoolHandlerFuncs = cache.TypedResourceEventHandlerFuncs[*pkgapiv1alpha1.WorkerPool] +type WorkerPoolHandlerFuncs = cache.TypedResourceEventHandlerFuncs[*k8satev1.WorkerPool] // WorkerPoolDetailedHandlerFuncs is a specialization of [cache.TypedResourceEventHandlerDetailedFuncs] for WorkerPool. -type WorkerPoolDetailedHandlerFuncs = cache.TypedResourceEventHandlerDetailedFuncs[*pkgapiv1alpha1.WorkerPool] +type WorkerPoolDetailedHandlerFuncs = cache.TypedResourceEventHandlerDetailedFuncs[*k8satev1.WorkerPool] // WorkerPoolFilteringHandler is a specialization of [cache.TypedFilteringResourceEventHandler] for WorkerPool. -type WorkerPoolFilteringHandler = cache.TypedFilteringResourceEventHandler[*pkgapiv1alpha1.WorkerPool] +type WorkerPoolFilteringHandler = cache.TypedFilteringResourceEventHandler[*k8satev1.WorkerPool] // WorkerPoolIndexers is a specialization of [cache.TypedIndexers] for WorkerPool. -type WorkerPoolIndexers = cache.TypedIndexers[*pkgapiv1alpha1.WorkerPool] +type WorkerPoolIndexers = cache.TypedIndexers[*k8satev1.WorkerPool] // DeletedWorkerPool is a specialization of [cache.DeletedObject] for WorkerPool. -type DeletedWorkerPool = cache.DeletedObject[*pkgapiv1alpha1.WorkerPool] +type DeletedWorkerPool = cache.DeletedObject[*k8satev1.WorkerPool] type workerPoolInformer struct { factory internalinterfaces.SharedInformerFactory @@ -114,37 +114,37 @@ func NewWorkerPoolInformerWithOptions(client versioned.Interface, namespace stri // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewTypedWorkerPoolInformerWithOptions(client versioned.Interface, namespace string, options internalinterfaces.InformerOptions) WorkerPoolIndexInformer { - gvr := schema.GroupVersionResource{Group: "api", Version: "v1alpha1", Resource: "workerpools"} + gvr := schema.GroupVersionResource{Group: "ate", Version: "v1", Resource: "workerpools"} identifier := options.InformerName.WithResource(gvr) tweakListOptions := options.TweakListOptions - return cache.NewTypedSharedIndexInformer[*pkgapiv1alpha1.WorkerPool](cache.NewSharedIndexInformerWithOptions( + return cache.NewTypedSharedIndexInformer[*k8satev1.WorkerPool](cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { tweakListOptions(&opts) } - return client.ApiV1alpha1().WorkerPools(namespace).List(context.Background(), opts) + return client.AteV1().WorkerPools(namespace).List(context.Background(), opts) }, - WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&opts) } - return client.ApiV1alpha1().WorkerPools(namespace).Watch(context.Background(), opts) + return client.AteV1().WorkerPools(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { tweakListOptions(&opts) } - return client.ApiV1alpha1().WorkerPools(namespace).List(ctx, opts) + return client.AteV1().WorkerPools(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&opts) } - return client.ApiV1alpha1().WorkerPools(namespace).Watch(ctx, opts) + return client.AteV1().WorkerPools(namespace).Watch(ctx, opts) }, }, client), - &pkgapiv1alpha1.WorkerPool{}, + &k8satev1.WorkerPool{}, cache.SharedIndexInformerOptions{ ResyncPeriod: options.ResyncPeriod, Indexers: options.Indexers, @@ -162,11 +162,11 @@ func (f *workerPoolInformer) Informer() cache.SharedIndexInformer { } func (f *workerPoolInformer) TypedInformer() WorkerPoolIndexInformer { - return cache.NewTypedSharedIndexInformer[*pkgapiv1alpha1.WorkerPool](f.factory.InformerFor(&pkgapiv1alpha1.WorkerPool{}, f.defaultInformer)) + return cache.NewTypedSharedIndexInformer[*k8satev1.WorkerPool](f.factory.InformerFor(&k8satev1.WorkerPool{}, f.defaultInformer)) } -func (f *workerPoolInformer) Lister() apiv1alpha1.WorkerPoolLister { - return apiv1alpha1.NewWorkerPoolLister(f.Informer().GetIndexer()) +func (f *workerPoolInformer) Lister() atev1.WorkerPoolLister { + return atev1.NewWorkerPoolLister(f.Informer().GetIndexer()) } // ToTypedWorkerPoolInformer converts an untyped informer into a TypedWorkerPoolInformer. @@ -188,7 +188,7 @@ type workerPoolTypedInformerAdapter struct { } func (a *workerPoolTypedInformerAdapter) TypedInformer() WorkerPoolIndexInformer { - return cache.NewTypedSharedIndexInformer[*pkgapiv1alpha1.WorkerPool](a.Informer()) + return cache.NewTypedSharedIndexInformer[*k8satev1.WorkerPool](a.Informer()) } // ToWorkerPoolIndexInformer converts an untyped informer into a WorkerPoolIndexInformer. @@ -202,5 +202,5 @@ func ToWorkerPoolIndexInformer(informer cache.SharedIndexInformer) WorkerPoolInd if informer, ok := informer.(WorkerPoolIndexInformer); ok { return informer } - return cache.NewTypedSharedIndexInformer[*pkgapiv1alpha1.WorkerPool](informer) + return cache.NewTypedSharedIndexInformer[*k8satev1.WorkerPool](informer) } diff --git a/pkg/client/informers/externalversions/factory.go b/pkg/client/informers/externalversions/factory.go index 36d54285a2..0e16806f06 100644 --- a/pkg/client/informers/externalversions/factory.go +++ b/pkg/client/informers/externalversions/factory.go @@ -23,7 +23,7 @@ import ( time "time" versioned "go.ate.dev/substrate/pkg/client/clientset/versioned" - api "go.ate.dev/substrate/pkg/client/informers/externalversions/api" + ate "go.ate.dev/substrate/pkg/client/informers/externalversions/ate" internalinterfaces "go.ate.dev/substrate/pkg/client/informers/externalversions/internalinterfaces" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" @@ -323,9 +323,9 @@ type SharedInformerFactory interface { // client. InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer - Api() api.Interface + Ate() ate.Interface } -func (f *sharedInformerFactory) Api() api.Interface { - return api.New(f, f.namespace, f.tweakListOptions) +func (f *sharedInformerFactory) Ate() ate.Interface { + return ate.New(f, f.namespace, f.tweakListOptions) } diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index 0c14c958a4..e62a584878 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -19,7 +19,7 @@ package externalversions import ( fmt "fmt" - v1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + v1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" ) @@ -50,13 +50,13 @@ func (f *genericInformer) Lister() cache.GenericLister { // TODO extend this to unknown resources with a client pool func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { switch resource { - // Group=api, Version=v1alpha1 - case v1alpha1.SchemeGroupVersion.WithResource("csidriverconfigs"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Api().V1alpha1().CSIDriverConfigs().Informer()}, nil - case v1alpha1.SchemeGroupVersion.WithResource("sandboxconfigs"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Api().V1alpha1().SandboxConfigs().Informer()}, nil - case v1alpha1.SchemeGroupVersion.WithResource("workerpools"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Api().V1alpha1().WorkerPools().Informer()}, nil + // Group=ate, Version=v1 + case v1.SchemeGroupVersion.WithResource("csidriverconfigs"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Ate().V1().CSIDriverConfigs().Informer()}, nil + case v1.SchemeGroupVersion.WithResource("sandboxconfigs"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Ate().V1().SandboxConfigs().Informer()}, nil + case v1.SchemeGroupVersion.WithResource("workerpools"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Ate().V1().WorkerPools().Informer()}, nil } diff --git a/pkg/client/listers/api/v1alpha1/csidriverconfig.go b/pkg/client/listers/ate/v1/csidriverconfig.go similarity index 78% rename from pkg/client/listers/api/v1alpha1/csidriverconfig.go rename to pkg/client/listers/ate/v1/csidriverconfig.go index 2ce7f1f788..47085dc950 100644 --- a/pkg/client/listers/api/v1alpha1/csidriverconfig.go +++ b/pkg/client/listers/ate/v1/csidriverconfig.go @@ -14,10 +14,10 @@ // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1 import ( - apiv1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" labels "k8s.io/apimachinery/pkg/labels" listers "k8s.io/client-go/listers" cache "k8s.io/client-go/tools/cache" @@ -28,19 +28,19 @@ import ( type CSIDriverConfigLister interface { // List lists all CSIDriverConfigs in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*apiv1alpha1.CSIDriverConfig, err error) + List(selector labels.Selector) (ret []*atev1.CSIDriverConfig, err error) // Get retrieves the CSIDriverConfig from the index for a given name. // Objects returned here must be treated as read-only. - Get(name string) (*apiv1alpha1.CSIDriverConfig, error) + Get(name string) (*atev1.CSIDriverConfig, error) CSIDriverConfigListerExpansion } // cSIDriverConfigLister implements the CSIDriverConfigLister interface. type cSIDriverConfigLister struct { - listers.ResourceIndexer[*apiv1alpha1.CSIDriverConfig] + listers.ResourceIndexer[*atev1.CSIDriverConfig] } // NewCSIDriverConfigLister returns a new CSIDriverConfigLister. func NewCSIDriverConfigLister(indexer cache.Indexer) CSIDriverConfigLister { - return &cSIDriverConfigLister{listers.New[*apiv1alpha1.CSIDriverConfig](indexer, apiv1alpha1.Resource("csidriverconfig"))} + return &cSIDriverConfigLister{listers.New[*atev1.CSIDriverConfig](indexer, atev1.Resource("csidriverconfig"))} } diff --git a/pkg/client/listers/api/v1alpha1/expansion_generated.go b/pkg/client/listers/ate/v1/expansion_generated.go similarity index 98% rename from pkg/client/listers/api/v1alpha1/expansion_generated.go rename to pkg/client/listers/ate/v1/expansion_generated.go index 89a3abb136..f04db2448b 100644 --- a/pkg/client/listers/api/v1alpha1/expansion_generated.go +++ b/pkg/client/listers/ate/v1/expansion_generated.go @@ -14,7 +14,7 @@ // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1 // CSIDriverConfigListerExpansion allows custom methods to be added to // CSIDriverConfigLister. diff --git a/pkg/client/listers/api/v1alpha1/sandboxconfig.go b/pkg/client/listers/ate/v1/sandboxconfig.go similarity index 79% rename from pkg/client/listers/api/v1alpha1/sandboxconfig.go rename to pkg/client/listers/ate/v1/sandboxconfig.go index 4b27c7230f..49c0da41d4 100644 --- a/pkg/client/listers/api/v1alpha1/sandboxconfig.go +++ b/pkg/client/listers/ate/v1/sandboxconfig.go @@ -14,10 +14,10 @@ // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1 import ( - apiv1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" labels "k8s.io/apimachinery/pkg/labels" listers "k8s.io/client-go/listers" cache "k8s.io/client-go/tools/cache" @@ -28,19 +28,19 @@ import ( type SandboxConfigLister interface { // List lists all SandboxConfigs in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*apiv1alpha1.SandboxConfig, err error) + List(selector labels.Selector) (ret []*atev1.SandboxConfig, err error) // Get retrieves the SandboxConfig from the index for a given name. // Objects returned here must be treated as read-only. - Get(name string) (*apiv1alpha1.SandboxConfig, error) + Get(name string) (*atev1.SandboxConfig, error) SandboxConfigListerExpansion } // sandboxConfigLister implements the SandboxConfigLister interface. type sandboxConfigLister struct { - listers.ResourceIndexer[*apiv1alpha1.SandboxConfig] + listers.ResourceIndexer[*atev1.SandboxConfig] } // NewSandboxConfigLister returns a new SandboxConfigLister. func NewSandboxConfigLister(indexer cache.Indexer) SandboxConfigLister { - return &sandboxConfigLister{listers.New[*apiv1alpha1.SandboxConfig](indexer, apiv1alpha1.Resource("sandboxconfig"))} + return &sandboxConfigLister{listers.New[*atev1.SandboxConfig](indexer, atev1.Resource("sandboxconfig"))} } diff --git a/pkg/client/listers/api/v1alpha1/workerpool.go b/pkg/client/listers/ate/v1/workerpool.go similarity index 78% rename from pkg/client/listers/api/v1alpha1/workerpool.go rename to pkg/client/listers/ate/v1/workerpool.go index 32569334b1..7a99a32115 100644 --- a/pkg/client/listers/api/v1alpha1/workerpool.go +++ b/pkg/client/listers/ate/v1/workerpool.go @@ -14,10 +14,10 @@ // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1 import ( - apiv1alpha1 "go.ate.dev/substrate/pkg/api/v1alpha1" + atev1 "go.ate.dev/substrate/api/infra/k8s/ate/v1" labels "k8s.io/apimachinery/pkg/labels" listers "k8s.io/client-go/listers" cache "k8s.io/client-go/tools/cache" @@ -28,7 +28,7 @@ import ( type WorkerPoolLister interface { // List lists all WorkerPools in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*apiv1alpha1.WorkerPool, err error) + List(selector labels.Selector) (ret []*atev1.WorkerPool, err error) // WorkerPools returns an object that can list and get WorkerPools. WorkerPools(namespace string) WorkerPoolNamespaceLister WorkerPoolListerExpansion @@ -36,17 +36,17 @@ type WorkerPoolLister interface { // workerPoolLister implements the WorkerPoolLister interface. type workerPoolLister struct { - listers.ResourceIndexer[*apiv1alpha1.WorkerPool] + listers.ResourceIndexer[*atev1.WorkerPool] } // NewWorkerPoolLister returns a new WorkerPoolLister. func NewWorkerPoolLister(indexer cache.Indexer) WorkerPoolLister { - return &workerPoolLister{listers.New[*apiv1alpha1.WorkerPool](indexer, apiv1alpha1.Resource("workerpool"))} + return &workerPoolLister{listers.New[*atev1.WorkerPool](indexer, atev1.Resource("workerpool"))} } // WorkerPools returns an object that can list and get WorkerPools. func (s *workerPoolLister) WorkerPools(namespace string) WorkerPoolNamespaceLister { - return workerPoolNamespaceLister{listers.NewNamespaced[*apiv1alpha1.WorkerPool](s.ResourceIndexer, namespace)} + return workerPoolNamespaceLister{listers.NewNamespaced[*atev1.WorkerPool](s.ResourceIndexer, namespace)} } // WorkerPoolNamespaceLister helps list and get WorkerPools. @@ -54,15 +54,15 @@ func (s *workerPoolLister) WorkerPools(namespace string) WorkerPoolNamespaceList type WorkerPoolNamespaceLister interface { // List lists all WorkerPools in the indexer for a given namespace. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*apiv1alpha1.WorkerPool, err error) + List(selector labels.Selector) (ret []*atev1.WorkerPool, err error) // Get retrieves the WorkerPool from the indexer for a given namespace and name. // Objects returned here must be treated as read-only. - Get(name string) (*apiv1alpha1.WorkerPool, error) + Get(name string) (*atev1.WorkerPool, error) WorkerPoolNamespaceListerExpansion } // workerPoolNamespaceLister implements the WorkerPoolNamespaceLister // interface. type workerPoolNamespaceLister struct { - listers.ResourceIndexer[*apiv1alpha1.WorkerPool] + listers.ResourceIndexer[*atev1.WorkerPool] } diff --git a/pkg/proto/ateconfigpb/apiconfig.pb.go b/pkg/proto/ateconfigpb/apiconfig.pb.go index 0eb9400877..0fea1d0dc1 100644 --- a/pkg/proto/ateconfigpb/apiconfig.pb.go +++ b/pkg/proto/ateconfigpb/apiconfig.pb.go @@ -16,7 +16,7 @@ // versions: // protoc-gen-go v1.36.11-devel // protoc v4.25.3 -// source: apiconfig.proto +// source: pkg/proto/ateconfigpb/apiconfig.proto package ateconfigpb @@ -45,7 +45,7 @@ type APIConfig struct { func (x *APIConfig) Reset() { *x = APIConfig{} - mi := &file_apiconfig_proto_msgTypes[0] + mi := &file_pkg_proto_ateconfigpb_apiconfig_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -57,7 +57,7 @@ func (x *APIConfig) String() string { func (*APIConfig) ProtoMessage() {} func (x *APIConfig) ProtoReflect() protoreflect.Message { - mi := &file_apiconfig_proto_msgTypes[0] + mi := &file_pkg_proto_ateconfigpb_apiconfig_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -70,7 +70,7 @@ func (x *APIConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use APIConfig.ProtoReflect.Descriptor instead. func (*APIConfig) Descriptor() ([]byte, []int) { - return file_apiconfig_proto_rawDescGZIP(), []int{0} + return file_pkg_proto_ateconfigpb_apiconfig_proto_rawDescGZIP(), []int{0} } func (x *APIConfig) GetLogging() *APILogging { @@ -90,7 +90,7 @@ type APILogging struct { func (x *APILogging) Reset() { *x = APILogging{} - mi := &file_apiconfig_proto_msgTypes[1] + mi := &file_pkg_proto_ateconfigpb_apiconfig_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -102,7 +102,7 @@ func (x *APILogging) String() string { func (*APILogging) ProtoMessage() {} func (x *APILogging) ProtoReflect() protoreflect.Message { - mi := &file_apiconfig_proto_msgTypes[1] + mi := &file_pkg_proto_ateconfigpb_apiconfig_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -115,7 +115,7 @@ func (x *APILogging) ProtoReflect() protoreflect.Message { // Deprecated: Use APILogging.ProtoReflect.Descriptor instead. func (*APILogging) Descriptor() ([]byte, []int) { - return file_apiconfig_proto_rawDescGZIP(), []int{1} + return file_pkg_proto_ateconfigpb_apiconfig_proto_rawDescGZIP(), []int{1} } func (x *APILogging) GetLevel() string { @@ -125,11 +125,11 @@ func (x *APILogging) GetLevel() string { return "" } -var File_apiconfig_proto protoreflect.FileDescriptor +var File_pkg_proto_ateconfigpb_apiconfig_proto protoreflect.FileDescriptor -const file_apiconfig_proto_rawDesc = "" + +const file_pkg_proto_ateconfigpb_apiconfig_proto_rawDesc = "" + "\n" + - "\x0fapiconfig.proto\x12\vateconfigpb\">\n" + + "%pkg/proto/ateconfigpb/apiconfig.proto\x12\vateconfigpb\">\n" + "\tAPIConfig\x121\n" + "\alogging\x18\x01 \x01(\v2\x17.ateconfigpb.APILoggingR\alogging\"\"\n" + "\n" + @@ -137,23 +137,23 @@ const file_apiconfig_proto_rawDesc = "" + "\x05level\x18\x01 \x01(\tR\x05levelB,Z*go.ate.dev/substrate/pkg/proto/ateconfigpbb\x06proto3" var ( - file_apiconfig_proto_rawDescOnce sync.Once - file_apiconfig_proto_rawDescData []byte + file_pkg_proto_ateconfigpb_apiconfig_proto_rawDescOnce sync.Once + file_pkg_proto_ateconfigpb_apiconfig_proto_rawDescData []byte ) -func file_apiconfig_proto_rawDescGZIP() []byte { - file_apiconfig_proto_rawDescOnce.Do(func() { - file_apiconfig_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_apiconfig_proto_rawDesc), len(file_apiconfig_proto_rawDesc))) +func file_pkg_proto_ateconfigpb_apiconfig_proto_rawDescGZIP() []byte { + file_pkg_proto_ateconfigpb_apiconfig_proto_rawDescOnce.Do(func() { + file_pkg_proto_ateconfigpb_apiconfig_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_pkg_proto_ateconfigpb_apiconfig_proto_rawDesc), len(file_pkg_proto_ateconfigpb_apiconfig_proto_rawDesc))) }) - return file_apiconfig_proto_rawDescData + return file_pkg_proto_ateconfigpb_apiconfig_proto_rawDescData } -var file_apiconfig_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_apiconfig_proto_goTypes = []any{ +var file_pkg_proto_ateconfigpb_apiconfig_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_pkg_proto_ateconfigpb_apiconfig_proto_goTypes = []any{ (*APIConfig)(nil), // 0: ateconfigpb.APIConfig (*APILogging)(nil), // 1: ateconfigpb.APILogging } -var file_apiconfig_proto_depIdxs = []int32{ +var file_pkg_proto_ateconfigpb_apiconfig_proto_depIdxs = []int32{ 1, // 0: ateconfigpb.APIConfig.logging:type_name -> ateconfigpb.APILogging 1, // [1:1] is the sub-list for method output_type 1, // [1:1] is the sub-list for method input_type @@ -162,26 +162,26 @@ var file_apiconfig_proto_depIdxs = []int32{ 0, // [0:1] is the sub-list for field type_name } -func init() { file_apiconfig_proto_init() } -func file_apiconfig_proto_init() { - if File_apiconfig_proto != nil { +func init() { file_pkg_proto_ateconfigpb_apiconfig_proto_init() } +func file_pkg_proto_ateconfigpb_apiconfig_proto_init() { + if File_pkg_proto_ateconfigpb_apiconfig_proto != nil { return } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_apiconfig_proto_rawDesc), len(file_apiconfig_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_pkg_proto_ateconfigpb_apiconfig_proto_rawDesc), len(file_pkg_proto_ateconfigpb_apiconfig_proto_rawDesc)), NumEnums: 0, NumMessages: 2, NumExtensions: 0, NumServices: 0, }, - GoTypes: file_apiconfig_proto_goTypes, - DependencyIndexes: file_apiconfig_proto_depIdxs, - MessageInfos: file_apiconfig_proto_msgTypes, + GoTypes: file_pkg_proto_ateconfigpb_apiconfig_proto_goTypes, + DependencyIndexes: file_pkg_proto_ateconfigpb_apiconfig_proto_depIdxs, + MessageInfos: file_pkg_proto_ateconfigpb_apiconfig_proto_msgTypes, }.Build() - File_apiconfig_proto = out.File - file_apiconfig_proto_goTypes = nil - file_apiconfig_proto_depIdxs = nil + File_pkg_proto_ateconfigpb_apiconfig_proto = out.File + file_pkg_proto_ateconfigpb_apiconfig_proto_goTypes = nil + file_pkg_proto_ateconfigpb_apiconfig_proto_depIdxs = nil } diff --git a/pkg/proto/credproviderpb/gen.go b/pkg/proto/credproviderpb/gen.go deleted file mode 100644 index 7ac0cc97b0..0000000000 --- a/pkg/proto/credproviderpb/gen.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2026 Google LLC -// -// 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 credproviderpb - -//go:generate bash -c "../../../hack/protoc.sh --plugin=protoc-gen-go=$(bash ../../../hack/run-tool.sh --print-bin-path protoc-gen-go) --plugin=protoc-gen-go-grpc=$(bash ../../../hack/run-tool.sh --print-bin-path protoc-gen-go-grpc) --go_out=paths=source_relative:. --go-grpc_out=paths=source_relative:. credprovider.proto" diff --git a/pkg/proto/objectstorepb/v1/gen.go b/pkg/proto/objectstorepb/v1/gen.go deleted file mode 100644 index 25a454562d..0000000000 --- a/pkg/proto/objectstorepb/v1/gen.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2026 Google LLC -// -// 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 objectstorev1 - -//go:generate bash -c "../../../../hack/protoc.sh --plugin=protoc-gen-go=$(bash ../../../../hack/run-tool.sh --print-bin-path protoc-gen-go) --plugin=protoc-gen-go-grpc=$(bash ../../../../hack/run-tool.sh --print-bin-path protoc-gen-go-grpc) --go_out=paths=source_relative:. --go-grpc_out=paths=source_relative:. objectstore.proto" diff --git a/pkg/sandboxclass/sandboxclass.go b/pkg/sandboxclass/sandboxclass.go index 22a57992de..70455e9e1b 100644 --- a/pkg/sandboxclass/sandboxclass.go +++ b/pkg/sandboxclass/sandboxclass.go @@ -15,7 +15,7 @@ // Package sandboxclass names the sandbox runtime families: the values a // WorkerPool and a SandboxConfig can select. It imports // nothing from Kubernetes, so any package can name a class without pulling in -// the ate.dev/v1alpha1 API types. +// the ate.dev/v1 API types. package sandboxclass import "slices" @@ -29,7 +29,7 @@ const ( ) // All returns every sandbox class. Keep it in sync with the -// +kubebuilder:validation:Enum markers in pkg/api/v1alpha1. +// +kubebuilder:validation:Enum markers in api/infra/k8s/ate/v1. func All() []string { return []string{GVisor, MicroVM} } diff --git a/tools/apitool/exemptions.json b/tools/apitool/exemptions.json index 58bfc2b44d..4e7e6007bd 100644 --- a/tools/apitool/exemptions.json +++ b/tools/apitool/exemptions.json @@ -1,352 +1,352 @@ [ { "rule": "documented", - "subject": "ateapi.Actor", + "subject": "substrate.ateapi.v1.Actor", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ActorAssignment.actor_uid", + "subject": "substrate.ateapi.v1.ActorAssignment.actor_uid", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ActorMetadataItem.field", + "subject": "substrate.ateapi.v1.ActorMetadataItem.field", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ActorState", + "subject": "substrate.ateapi.v1.ActorState", "message": "enum has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ActorStatus", + "subject": "substrate.ateapi.v1.ActorStatus", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ActorTemplate", + "subject": "substrate.ateapi.v1.ActorTemplate", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ActorTemplate.containers", + "subject": "substrate.ateapi.v1.ActorTemplate.containers", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ActorTemplate.status", + "subject": "substrate.ateapi.v1.ActorTemplate.status", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ActorTemplate.volumes", + "subject": "substrate.ateapi.v1.ActorTemplate.volumes", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ActorTemplateStatus", + "subject": "substrate.ateapi.v1.ActorTemplateStatus", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ActorTemplateStatus.golden_snapshot_status", + "subject": "substrate.ateapi.v1.ActorTemplateStatus.golden_snapshot_status", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.Container.name", + "subject": "substrate.ateapi.v1.Container.name", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.Control.CreateActorTemplate", + "subject": "substrate.ateapi.v1.Control.CreateActorTemplate", "message": "method has no doc comment" }, { "rule": "documented", - "subject": "ateapi.Control.GetActorTemplate", + "subject": "substrate.ateapi.v1.Control.GetActorTemplate", "message": "method has no doc comment" }, { "rule": "documented", - "subject": "ateapi.Control.ListActorTemplates", + "subject": "substrate.ateapi.v1.Control.ListActorTemplates", "message": "method has no doc comment" }, { "rule": "documented", - "subject": "ateapi.CreateActorTemplateRequest", + "subject": "substrate.ateapi.v1.CreateActorTemplateRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.CreateAtespaceRequest", + "subject": "substrate.ateapi.v1.CreateAtespaceRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.CreateWorkerRequest", + "subject": "substrate.ateapi.v1.CreateWorkerRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.DeleteActorRequest", + "subject": "substrate.ateapi.v1.DeleteActorRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.DeleteActorRequest.actor", + "subject": "substrate.ateapi.v1.DeleteActorRequest.actor", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.DeleteActorTemplateRequest", + "subject": "substrate.ateapi.v1.DeleteActorTemplateRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.DeleteActorTemplateRequest.actor_template", + "subject": "substrate.ateapi.v1.DeleteActorTemplateRequest.actor_template", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.DeleteAtespaceRequest", + "subject": "substrate.ateapi.v1.DeleteAtespaceRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.DeleteAtespaceRequest.atespace", + "subject": "substrate.ateapi.v1.DeleteAtespaceRequest.atespace", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.DeleteTagRequest", + "subject": "substrate.ateapi.v1.DeleteTagRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.DeleteTagRequest.tag", + "subject": "substrate.ateapi.v1.DeleteTagRequest.tag", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.DeleteWorkerRequest", + "subject": "substrate.ateapi.v1.DeleteWorkerRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.DrainWorkerRequest", + "subject": "substrate.ateapi.v1.DrainWorkerRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.GetActorRequest", + "subject": "substrate.ateapi.v1.GetActorRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.GetActorRequest.actor", + "subject": "substrate.ateapi.v1.GetActorRequest.actor", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.GetActorTemplateRequest", + "subject": "substrate.ateapi.v1.GetActorTemplateRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.GetActorTemplateRequest.actor_template", + "subject": "substrate.ateapi.v1.GetActorTemplateRequest.actor_template", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.GetAtespaceRequest", + "subject": "substrate.ateapi.v1.GetAtespaceRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.GetAtespaceRequest.atespace", + "subject": "substrate.ateapi.v1.GetAtespaceRequest.atespace", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.GetTagRequest", + "subject": "substrate.ateapi.v1.GetTagRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.GetTagRequest.tag", + "subject": "substrate.ateapi.v1.GetTagRequest.tag", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.GetWorkerRequest", + "subject": "substrate.ateapi.v1.GetWorkerRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.GoldenSnapshotStatus", + "subject": "substrate.ateapi.v1.GoldenSnapshotStatus", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ListActorTemplatesRequest", + "subject": "substrate.ateapi.v1.ListActorTemplatesRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ListActorTemplatesResponse", + "subject": "substrate.ateapi.v1.ListActorTemplatesResponse", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ListActorsResponse", + "subject": "substrate.ateapi.v1.ListActorsResponse", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ListAtespacesRequest", + "subject": "substrate.ateapi.v1.ListAtespacesRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ListAtespacesResponse", + "subject": "substrate.ateapi.v1.ListAtespacesResponse", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ListTagsRequest", + "subject": "substrate.ateapi.v1.ListTagsRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ListTagsResponse", + "subject": "substrate.ateapi.v1.ListTagsResponse", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ListTagsResponse.next_page_token", + "subject": "substrate.ateapi.v1.ListTagsResponse.next_page_token", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ListTagsResponse.tags", + "subject": "substrate.ateapi.v1.ListTagsResponse.tags", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ListWorkersRequest", + "subject": "substrate.ateapi.v1.ListWorkersRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ListWorkersResponse", + "subject": "substrate.ateapi.v1.ListWorkersResponse", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ResumeActorRequest", + "subject": "substrate.ateapi.v1.ResumeActorRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ResumeActorRequest.actor", + "subject": "substrate.ateapi.v1.ResumeActorRequest.actor", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ResumeActorResponse", + "subject": "substrate.ateapi.v1.ResumeActorResponse", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.ResumeActorResponse.actor", + "subject": "substrate.ateapi.v1.ResumeActorResponse.actor", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.SuspendActorRequest", + "subject": "substrate.ateapi.v1.SuspendActorRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.SuspendActorRequest.actor", + "subject": "substrate.ateapi.v1.SuspendActorRequest.actor", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.SuspendActorResponse", + "subject": "substrate.ateapi.v1.SuspendActorResponse", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.SuspendActorResponse.actor", + "subject": "substrate.ateapi.v1.SuspendActorResponse.actor", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.SystemInfoDataSource", + "subject": "substrate.ateapi.v1.SystemInfoDataSource", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.SystemInfoDataSource.trust_bundle", + "subject": "substrate.ateapi.v1.SystemInfoDataSource.trust_bundle", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.TagScope", + "subject": "substrate.ateapi.v1.TagScope", "message": "enum has no doc comment" }, { "rule": "documented", - "subject": "ateapi.UpdateWorkerRequest", + "subject": "substrate.ateapi.v1.UpdateWorkerRequest", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.Volume", + "subject": "substrate.ateapi.v1.Volume", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.Volume.system_info", + "subject": "substrate.ateapi.v1.Volume.system_info", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.Worker.node_name", + "subject": "substrate.ateapi.v1.Worker.node_name", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.Worker.worker_pod", + "subject": "substrate.ateapi.v1.Worker.worker_pod", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.Worker.worker_pod_uid", + "subject": "substrate.ateapi.v1.Worker.worker_pod_uid", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.Worker.worker_pool", + "subject": "substrate.ateapi.v1.Worker.worker_pool", "message": "field has no doc comment" }, { "rule": "documented", - "subject": "ateapi.WorkerState", + "subject": "substrate.ateapi.v1.WorkerState", "message": "enum has no doc comment" }, { "rule": "documented", - "subject": "ateapi.WorkerStatus", + "subject": "substrate.ateapi.v1.WorkerStatus", "message": "message has no doc comment" }, { "rule": "documented", - "subject": "ateapi.WorkerStatus.state", + "subject": "substrate.ateapi.v1.WorkerStatus.state", "message": "field has no doc comment" } ] diff --git a/tools/apitool/internal/exemption/exemption_test.go b/tools/apitool/internal/exemption/exemption_test.go index bb59032ed3..ba4a6ef487 100644 --- a/tools/apitool/internal/exemption/exemption_test.go +++ b/tools/apitool/internal/exemption/exemption_test.go @@ -35,8 +35,8 @@ func TestLoadMissingFileIsEmpty(t *testing.T) { func TestSaveThenLoadRoundTrips(t *testing.T) { path := filepath.Join(t.TempDir(), "exemptions.json") in := []exemption.Exemption{ - {Rule: "documented", Subject: "ateapi.Foo", Message: "message has no doc comment"}, - {Rule: "delete-request-shape", Subject: "ateapi.Control.DeleteActor", Message: `field "any_state" is not a message`}, + {Rule: "documented", Subject: "substrate.ateapi.v1.Foo", Message: "message has no doc comment"}, + {Rule: "delete-request-shape", Subject: "substrate.ateapi.v1.Control.DeleteActor", Message: `field "any_state" is not a message`}, } if err := exemption.Save(path, in); err != nil { @@ -56,8 +56,8 @@ func TestSaveThenLoadRoundTrips(t *testing.T) { func TestSaveSortsDeterministically(t *testing.T) { path := filepath.Join(t.TempDir(), "exemptions.json") if err := exemption.Save(path, []exemption.Exemption{ - {Rule: "documented", Subject: "ateapi.B", Message: "m"}, - {Rule: "documented", Subject: "ateapi.A", Message: "m"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.B", Message: "m"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.A", Message: "m"}, }); err != nil { t.Fatalf("Save: %v", err) } @@ -67,8 +67,8 @@ func TestSaveSortsDeterministically(t *testing.T) { t.Fatalf("Load: %v", err) } want := []exemption.Exemption{ - {Rule: "documented", Subject: "ateapi.A", Message: "m"}, - {Rule: "documented", Subject: "ateapi.B", Message: "m"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.A", Message: "m"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.B", Message: "m"}, } if !reflect.DeepEqual(got, want) { t.Errorf("Save() order = %+v, want %+v", got, want) @@ -89,32 +89,32 @@ func TestCheckSorted(t *testing.T) { { name: "singleton", exemptions: []exemption.Exemption{ - {Rule: "documented", Subject: "ateapi.A", Message: "m"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.A", Message: "m"}, }, wantErr: false, }, { name: "sorted", exemptions: []exemption.Exemption{ - {Rule: "documented", Subject: "ateapi.A", Message: "m"}, - {Rule: "documented", Subject: "ateapi.B", Message: "m"}, - {Rule: "no-oneofs", Subject: "ateapi.A", Message: "m"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.A", Message: "m"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.B", Message: "m"}, + {Rule: "no-oneofs", Subject: "substrate.ateapi.v1.A", Message: "m"}, }, wantErr: false, }, { name: "out of order subject", exemptions: []exemption.Exemption{ - {Rule: "documented", Subject: "ateapi.TagScope", Message: "m"}, - {Rule: "documented", Subject: "ateapi.ActorState", Message: "m"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.TagScope", Message: "m"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.ActorState", Message: "m"}, }, wantErr: true, }, { name: "out of order rule", exemptions: []exemption.Exemption{ - {Rule: "no-oneofs", Subject: "ateapi.A", Message: "m"}, - {Rule: "documented", Subject: "ateapi.A", Message: "m"}, + {Rule: "no-oneofs", Subject: "substrate.ateapi.v1.A", Message: "m"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.A", Message: "m"}, }, wantErr: true, }, @@ -130,40 +130,40 @@ func TestCheckSorted(t *testing.T) { func TestSetConsume(t *testing.T) { set := exemption.NewSet([]exemption.Exemption{ - {Rule: "documented", Subject: "ateapi.Foo", Message: "message has no doc comment"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.Foo", Message: "message has no doc comment"}, }) - if !set.Consume("documented", "ateapi.Foo", "message has no doc comment") { + if !set.Consume("documented", "substrate.ateapi.v1.Foo", "message has no doc comment") { t.Error("Consume() = false for an exempted finding, want true") } - if set.Consume("documented", "ateapi.Foo", "message has no doc comment") { + if set.Consume("documented", "substrate.ateapi.v1.Foo", "message has no doc comment") { t.Error("Consume() = true for an already-claimed exemption, want false") } - if set.Consume("documented", "ateapi.Bar", "message has no doc comment") { + if set.Consume("documented", "substrate.ateapi.v1.Bar", "message has no doc comment") { t.Error("Consume() = true for a finding with no matching exemption, want false") } } func TestDiff(t *testing.T) { current := []exemption.Exemption{ - {Rule: "documented", Subject: "ateapi.Foo", Message: "message has no doc comment"}, - {Rule: "documented", Subject: "ateapi.Bar", Message: "message has no doc comment"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.Foo", Message: "message has no doc comment"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.Bar", Message: "message has no doc comment"}, } exemptions := []exemption.Exemption{ - {Rule: "documented", Subject: "ateapi.Foo", Message: "message has no doc comment"}, - {Rule: "documented", Subject: "ateapi.Baz", Message: "message has no doc comment"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.Foo", Message: "message has no doc comment"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.Baz", Message: "message has no doc comment"}, } missing, stale := exemption.Diff(current, exemptions) wantMissing := []exemption.Exemption{ - {Rule: "documented", Subject: "ateapi.Bar", Message: "message has no doc comment"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.Bar", Message: "message has no doc comment"}, } if !reflect.DeepEqual(missing, wantMissing) { t.Errorf("Diff() missing = %+v, want %+v", missing, wantMissing) } wantStale := []exemption.Exemption{ - {Rule: "documented", Subject: "ateapi.Baz", Message: "message has no doc comment"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.Baz", Message: "message has no doc comment"}, } if !reflect.DeepEqual(stale, wantStale) { t.Errorf("Diff() stale = %+v, want %+v", stale, wantStale) @@ -172,14 +172,14 @@ func TestDiff(t *testing.T) { func TestSetUnusedReportsUnclaimedExemptions(t *testing.T) { set := exemption.NewSet([]exemption.Exemption{ - {Rule: "documented", Subject: "ateapi.Foo", Message: "message has no doc comment"}, - {Rule: "documented", Subject: "ateapi.Bar", Message: "message has no doc comment"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.Foo", Message: "message has no doc comment"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.Bar", Message: "message has no doc comment"}, }) - set.Consume("documented", "ateapi.Foo", "message has no doc comment") + set.Consume("documented", "substrate.ateapi.v1.Foo", "message has no doc comment") got := set.Unused() want := []exemption.Exemption{ - {Rule: "documented", Subject: "ateapi.Bar", Message: "message has no doc comment"}, + {Rule: "documented", Subject: "substrate.ateapi.v1.Bar", Message: "message has no doc comment"}, } if !reflect.DeepEqual(got, want) { t.Errorf("Unused() = %+v, want %+v", got, want) diff --git a/tools/apitool/internal/lint/fields.go b/tools/apitool/internal/lint/fields.go index 0d6c5f75b6..7a47e8f6b6 100644 --- a/tools/apitool/internal/lint/fields.go +++ b/tools/apitool/internal/lint/fields.go @@ -28,7 +28,7 @@ import ( // whether it's repeated, and names that type in findings. type typeMatcher struct { // label names the type in findings. For example, "string" or - // "ateapi.ObjectRef". + // "substrate.ateapi.v1.ObjectRef". label string matches func(model.Field) bool } @@ -147,7 +147,7 @@ func wantStrings(want wantFields) []string { } // typeOf describes f's type in findings. For example, "string", -// "ateapi.ObjectRef", or "repeated ateapi.Actor". +// "substrate.ateapi.v1.ObjectRef", or "repeated substrate.ateapi.v1.Actor". func typeOf(f model.Field) string { if f.TypeFullName == "" { return f.TypeDisplay diff --git a/tools/apitool/internal/lint/fields_test.go b/tools/apitool/internal/lint/fields_test.go index fbc467750b..2be4ea8481 100644 --- a/tools/apitool/internal/lint/fields_test.go +++ b/tools/apitool/internal/lint/fields_test.go @@ -24,13 +24,13 @@ import ( ) func TestCheckFields(t *testing.T) { - ref := model.Field{Name: "gadget", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"} + ref := model.Field{Name: "gadget", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"} name := model.Field{Name: "name", Kind: protoreflect.StringKind, TypeDisplay: "string"} - opts := model.Field{Name: "options", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.DeleteOptions"} + opts := model.Field{Name: "options", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.DeleteOptions"} want := []wantFields{ - required("gadget", message("ateapi.ObjectRef")), + required("gadget", message("substrate.ateapi.v1.ObjectRef")), required("name", scalar(protoreflect.StringKind)), - optional("options", message("ateapi.DeleteOptions")), + optional("options", message("substrate.ateapi.v1.DeleteOptions")), } tests := []struct { @@ -62,44 +62,44 @@ func TestCheckFields(t *testing.T) { }, { name: "field of a required type, misnamed", - fields: []model.Field{{Name: "parent", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"}, name}, + fields: []model.Field{{Name: "parent", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"}, name}, want: []Finding{ - {Subject: "s", Message: `request field "parent" is ateapi.ObjectRef, want it named "gadget"`}, + {Subject: "s", Message: `request field "parent" is substrate.ateapi.v1.ObjectRef, want it named "gadget"`}, }, }, { name: "field of an already filled wanted field's type is stray", - fields: []model.Field{ref, name, {Name: "other", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"}}, + fields: []model.Field{ref, name, {Name: "other", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"}}, want: []Finding{ - {Subject: "s", Message: `request field "other" is not allowed - want only "gadget" ateapi.ObjectRef, "name" string, and optional "options" ateapi.DeleteOptions`}, + {Subject: "s", Message: `request field "other" is not allowed - want only "gadget" substrate.ateapi.v1.ObjectRef, "name" string, and optional "options" substrate.ateapi.v1.DeleteOptions`}, }, }, { name: "stray field", fields: []model.Field{ref, name, {Name: "dry_run", Kind: protoreflect.BoolKind, TypeDisplay: "bool"}}, want: []Finding{ - {Subject: "s", Message: `request field "dry_run" is not allowed - want only "gadget" ateapi.ObjectRef, "name" string, and optional "options" ateapi.DeleteOptions`}, + {Subject: "s", Message: `request field "dry_run" is not allowed - want only "gadget" substrate.ateapi.v1.ObjectRef, "name" string, and optional "options" substrate.ateapi.v1.DeleteOptions`}, }, }, { name: "optional field twice", fields: []model.Field{ref, name, opts, opts}, want: []Finding{ - {Subject: "s", Message: `request has 2 "options" ateapi.DeleteOptions fields, want at most 1`}, + {Subject: "s", Message: `request has 2 "options" substrate.ateapi.v1.DeleteOptions fields, want at most 1`}, }, }, { name: "named field twice", fields: []model.Field{ref, ref, name}, want: []Finding{ - {Subject: "s", Message: `request has 2 "gadget" ateapi.ObjectRef fields, want at most 1`}, + {Subject: "s", Message: `request has 2 "gadget" substrate.ateapi.v1.ObjectRef fields, want at most 1`}, }, }, { name: "repeated field where a singular message is wanted", - fields: []model.Field{{Name: "gadget", Repeated: true, Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"}, name}, + fields: []model.Field{{Name: "gadget", Repeated: true, Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"}, name}, want: []Finding{ - {Subject: "s", Message: `request field "gadget" is repeated ateapi.ObjectRef, want ateapi.ObjectRef`}, + {Subject: "s", Message: `request field "gadget" is repeated substrate.ateapi.v1.ObjectRef, want substrate.ateapi.v1.ObjectRef`}, }, }, { diff --git a/tools/apitool/internal/lint/fixtures_test.go b/tools/apitool/internal/lint/fixtures_test.go index 08bd26a69c..75b9781f1c 100644 --- a/tools/apitool/internal/lint/fixtures_test.go +++ b/tools/apitool/internal/lint/fixtures_test.go @@ -19,7 +19,7 @@ package lint_test import ( "google.golang.org/protobuf/reflect/protoreflect" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/tools/apitool/internal/model" ) @@ -51,7 +51,7 @@ func rpc(name, resource, output string) model.Method { func resource(name string, parents []string, fields ...model.Field) model.Message { a := &model.ResourceAnnotation{Parents: parents, Plural: name + "s"} if len(parents) == 0 { - a.Scope = ateapipb.Scope_SCOPE_ATESPACE + a.Scope = ateapi.Scope_SCOPE_ATESPACE } return model.Message{FullName: protoreflect.FullName("test." + name), Name: name, Fields: fields, ResourceAnnotation: a} } @@ -60,7 +60,7 @@ func resource(name string, parents []string, fields ...model.Field) model.Messag // test.{name}, with the given fields. func globalResource(name string, fields ...model.Field) model.Message { m := resource(name, nil, fields...) - m.ResourceAnnotation.Scope = ateapipb.Scope_SCOPE_GLOBAL + m.ResourceAnnotation.Scope = ateapi.Scope_SCOPE_GLOBAL return m } diff --git a/tools/apitool/internal/lint/method.go b/tools/apitool/internal/lint/method.go index 5e9e96ecce..d5c64c227b 100644 --- a/tools/apitool/internal/lint/method.go +++ b/tools/apitool/internal/lint/method.go @@ -54,7 +54,7 @@ func findingf(subject protoreflect.FullName, format string, args ...any) Finding return Finding{Subject: string(subject), Message: fmt.Sprintf(format, args...)} } -// subjectOf names m in findings. For example, "ateapi.Control.GetActor". +// subjectOf names m in findings. For example, "substrate.ateapi.v1.Control.GetActor". func subjectOf(m model.Method) protoreflect.FullName { return m.ServiceFullName.Append(m.Name) } diff --git a/tools/apitool/internal/lint/resources.go b/tools/apitool/internal/lint/resources.go index 6d16e4de4b..7d3c07e127 100644 --- a/tools/apitool/internal/lint/resources.go +++ b/tools/apitool/internal/lint/resources.go @@ -20,7 +20,7 @@ import ( "go.ate.dev/substrate/tools/apitool/internal/model" ) -const resourceMetadataTypeFullName protoreflect.FullName = "ateapi.ResourceMetadata" +const resourceMetadataTypeFullName protoreflect.FullName = "substrate.ateapi.v1.ResourceMetadata" var ResourceMetadata = Rule{ Name: "resource-metadata", diff --git a/tools/apitool/internal/lint/resources_test.go b/tools/apitool/internal/lint/resources_test.go index 89a4f43ad6..26b51141e9 100644 --- a/tools/apitool/internal/lint/resources_test.go +++ b/tools/apitool/internal/lint/resources_test.go @@ -33,7 +33,7 @@ func TestResourceMetadata(t *testing.T) { }{ { name: "compliant", - api: messagesAPI(resource("Widget", nil, model.Field{Name: "metadata", Number: 1, Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ResourceMetadata"})), + api: messagesAPI(resource("Widget", nil, model.Field{Name: "metadata", Number: 1, Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ResourceMetadata"})), }, { name: "missing entirely", @@ -44,28 +44,28 @@ func TestResourceMetadata(t *testing.T) { }, { name: "wrong type", - api: messagesAPI(resource("Widget", nil, model.Field{Name: "metadata", Number: 1, Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"})), + api: messagesAPI(resource("Widget", nil, model.Field{Name: "metadata", Number: 1, Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"})), want: []lint.Finding{ - {Subject: "test.Widget", Message: `"metadata" field is ateapi.ObjectRef, want ateapi.ResourceMetadata`}, + {Subject: "test.Widget", Message: `"metadata" field is substrate.ateapi.v1.ObjectRef, want substrate.ateapi.v1.ResourceMetadata`}, }, }, { name: "scalar", api: messagesAPI(resource("Widget", nil, model.Field{Name: "metadata", Number: 1, Kind: protoreflect.StringKind, TypeDisplay: "string"})), want: []lint.Finding{ - {Subject: "test.Widget", Message: `"metadata" field is string, want ateapi.ResourceMetadata`}, + {Subject: "test.Widget", Message: `"metadata" field is string, want substrate.ateapi.v1.ResourceMetadata`}, }, }, { name: "repeated", - api: messagesAPI(resource("Widget", nil, model.Field{Name: "metadata", Number: 1, Repeated: true, Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ResourceMetadata"})), + api: messagesAPI(resource("Widget", nil, model.Field{Name: "metadata", Number: 1, Repeated: true, Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ResourceMetadata"})), want: []lint.Finding{ - {Subject: "test.Widget", Message: `"metadata" field is repeated ateapi.ResourceMetadata, want ateapi.ResourceMetadata`}, + {Subject: "test.Widget", Message: `"metadata" field is repeated substrate.ateapi.v1.ResourceMetadata, want substrate.ateapi.v1.ResourceMetadata`}, }, }, { name: "wrong field number", - api: messagesAPI(resource("Widget", nil, model.Field{Name: "metadata", Number: 2, Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ResourceMetadata"})), + api: messagesAPI(resource("Widget", nil, model.Field{Name: "metadata", Number: 2, Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ResourceMetadata"})), want: []lint.Finding{ {Subject: "test.Widget", Message: `"metadata" field is number 2, want 1`}, }, @@ -76,7 +76,7 @@ func TestResourceMetadata(t *testing.T) { }, { name: "parent that isn't a resource", - api: messagesAPI(resource("Widget", []string{"Gadget"}, model.Field{Name: "metadata", Number: 1, Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ResourceMetadata"})), + api: messagesAPI(resource("Widget", []string{"Gadget"}, model.Field{Name: "metadata", Number: 1, Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ResourceMetadata"})), wantErr: true, }, } diff --git a/tools/apitool/internal/lint/standard_methods.go b/tools/apitool/internal/lint/standard_methods.go index fd3605765a..dc90389b37 100644 --- a/tools/apitool/internal/lint/standard_methods.go +++ b/tools/apitool/internal/lint/standard_methods.go @@ -17,7 +17,7 @@ package lint import ( "google.golang.org/protobuf/reflect/protoreflect" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/tools/apitool/internal/model" ) @@ -108,7 +108,7 @@ func checkDeleteRequest(m method) []Finding { var DeleteOptionsShape = Rule{ Name: "delete-options-shape", - Description: "The shared ateapi.DeleteOptions message has only version (int64) and uid (string) fields - nothing else.", + Description: "The shared substrate.ateapi.v1.DeleteOptions message has only version (int64) and uid (string) fields - nothing else.", Check: checkDeleteOptionsShape, } @@ -188,7 +188,7 @@ func (m method) listScopeField() wantFields { switch { case m.isSubresource(): return m.parentRefField() - case m.resource.ResourceAnnotation.Scope == ateapipb.Scope_SCOPE_ATESPACE: + case m.resource.ResourceAnnotation.Scope == ateapi.Scope_SCOPE_ATESPACE: return required("atespace", scalar(protoreflect.StringKind)) default: return nil @@ -202,8 +202,8 @@ func (m method) resourcePageField() wantFields { } const ( - objectRefTypeFullName protoreflect.FullName = "ateapi.ObjectRef" - createOptionsTypeFullName protoreflect.FullName = "ateapi.CreateOptions" - deleteOptionsTypeFullName protoreflect.FullName = "ateapi.DeleteOptions" - listOptionsTypeFullName protoreflect.FullName = "ateapi.ListOptions" + objectRefTypeFullName protoreflect.FullName = "substrate.ateapi.v1.ObjectRef" + createOptionsTypeFullName protoreflect.FullName = "substrate.ateapi.v1.CreateOptions" + deleteOptionsTypeFullName protoreflect.FullName = "substrate.ateapi.v1.DeleteOptions" + listOptionsTypeFullName protoreflect.FullName = "substrate.ateapi.v1.ListOptions" ) diff --git a/tools/apitool/internal/lint/standard_methods_test.go b/tools/apitool/internal/lint/standard_methods_test.go index 67e6f3d5e6..86b710bcdc 100644 --- a/tools/apitool/internal/lint/standard_methods_test.go +++ b/tools/apitool/internal/lint/standard_methods_test.go @@ -123,9 +123,9 @@ func TestStandardMethodReturnsResource(t *testing.T) { } func TestGetRequestShape(t *testing.T) { - widgetRef := model.Field{Name: "widget", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"} - misnamedWidgetRef := model.Field{Name: "thing", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"} - gadgetRef := model.Field{Name: "gadget", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"} + widgetRef := model.Field{Name: "widget", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"} + misnamedWidgetRef := model.Field{Name: "thing", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"} + gadgetRef := model.Field{Name: "gadget", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"} name := model.Field{Name: "name", Kind: protoreflect.StringKind, TypeDisplay: "string"} tests := []struct { @@ -146,7 +146,7 @@ func TestGetRequestShape(t *testing.T) { resource("Widget", nil), msg("GetWidgetRequest")), want: []lint.Finding{ - {Subject: "test.Control.GetWidget", Message: `request has no "widget" ateapi.ObjectRef field`}, + {Subject: "test.Control.GetWidget", Message: `request has no "widget" substrate.ateapi.v1.ObjectRef field`}, }, }, { @@ -155,7 +155,7 @@ func TestGetRequestShape(t *testing.T) { resource("Widget", nil), msg("GetWidgetRequest", widgetRef, model.Field{Name: "extra"})), want: []lint.Finding{ - {Subject: "test.Control.GetWidget", Message: `request field "extra" is not allowed - want only "widget" ateapi.ObjectRef`}, + {Subject: "test.Control.GetWidget", Message: `request field "extra" is not allowed - want only "widget" substrate.ateapi.v1.ObjectRef`}, }, }, { @@ -164,8 +164,8 @@ func TestGetRequestShape(t *testing.T) { resource("Widget", nil), msg("GetWidgetRequest", name)), want: []lint.Finding{ - {Subject: "test.Control.GetWidget", Message: `request field "name" is not allowed - want only "widget" ateapi.ObjectRef`}, - {Subject: "test.Control.GetWidget", Message: `request has no "widget" ateapi.ObjectRef field`}, + {Subject: "test.Control.GetWidget", Message: `request field "name" is not allowed - want only "widget" substrate.ateapi.v1.ObjectRef`}, + {Subject: "test.Control.GetWidget", Message: `request has no "widget" substrate.ateapi.v1.ObjectRef field`}, }, }, { @@ -174,7 +174,7 @@ func TestGetRequestShape(t *testing.T) { resource("Widget", nil), msg("GetWidgetRequest", misnamedWidgetRef)), want: []lint.Finding{ - {Subject: "test.Control.GetWidget", Message: `request field "thing" is ateapi.ObjectRef, want it named "widget"`}, + {Subject: "test.Control.GetWidget", Message: `request field "thing" is substrate.ateapi.v1.ObjectRef, want it named "widget"`}, }, }, { @@ -217,7 +217,7 @@ func TestGetRequestShape(t *testing.T) { resource("Gadget", nil), msg("GetGadgetWidgetRequest", name)), want: []lint.Finding{ - {Subject: "test.Control.GetGadgetWidget", Message: `request has no "gadget" ateapi.ObjectRef field`}, + {Subject: "test.Control.GetGadgetWidget", Message: `request has no "gadget" substrate.ateapi.v1.ObjectRef field`}, }, }, { @@ -227,7 +227,7 @@ func TestGetRequestShape(t *testing.T) { resource("Gadget", nil), msg("GetGadgetWidgetRequest", model.Field{Name: "gadget", Kind: protoreflect.StringKind, TypeDisplay: "string"}, name)), want: []lint.Finding{ - {Subject: "test.Control.GetGadgetWidget", Message: `request field "gadget" is string, want ateapi.ObjectRef`}, + {Subject: "test.Control.GetGadgetWidget", Message: `request field "gadget" is string, want substrate.ateapi.v1.ObjectRef`}, }, }, { @@ -237,7 +237,7 @@ func TestGetRequestShape(t *testing.T) { resource("Gadget", nil), msg("GetGadgetWidgetRequest", widgetRef)), want: []lint.Finding{ - {Subject: "test.Control.GetGadgetWidget", Message: `request field "widget" is ateapi.ObjectRef, want it named "gadget"`}, + {Subject: "test.Control.GetGadgetWidget", Message: `request field "widget" is substrate.ateapi.v1.ObjectRef, want it named "gadget"`}, {Subject: "test.Control.GetGadgetWidget", Message: `request has no "name" string field`}, }, }, @@ -248,7 +248,7 @@ func TestGetRequestShape(t *testing.T) { resource("Gadget", nil), msg("GetGadgetWidgetRequest", gadgetRef, name, model.Field{Name: "extra"})), want: []lint.Finding{ - {Subject: "test.Control.GetGadgetWidget", Message: `request field "extra" is not allowed - want only "gadget" ateapi.ObjectRef and "name" string`}, + {Subject: "test.Control.GetGadgetWidget", Message: `request field "extra" is not allowed - want only "gadget" substrate.ateapi.v1.ObjectRef and "name" string`}, }, }, { @@ -270,7 +270,7 @@ func TestGetRequestShape(t *testing.T) { name: "subresource of Global: a parent ObjectRef is a stray field", api: methodAPI(rpc("GetGlobalWidget", "Widget", "Widget"), resource("Widget", []string{"Global"}), - msg("GetGlobalWidgetRequest", model.Field{Name: "global", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"}, name)), + msg("GetGlobalWidgetRequest", model.Field{Name: "global", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"}, name)), want: []lint.Finding{ {Subject: "test.Control.GetGlobalWidget", Message: `request field "global" is not allowed - want only "name" string`}, }, @@ -297,9 +297,9 @@ func TestGetRequestShape(t *testing.T) { } func TestListMethodShape(t *testing.T) { - options := model.Field{Name: "options", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ListOptions"} + options := model.Field{Name: "options", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ListOptions"} atespace := model.Field{Name: "atespace", Kind: protoreflect.StringKind, TypeDisplay: "string"} - gadgetRef := model.Field{Name: "gadget", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"} + gadgetRef := model.Field{Name: "gadget", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"} widgets := model.Field{Name: "widgets", Repeated: true, Kind: protoreflect.MessageKind, TypeFullName: "test.Widget"} nextPageToken := model.Field{Name: "next_page_token", Kind: protoreflect.StringKind, TypeDisplay: "string"} @@ -322,7 +322,7 @@ func TestListMethodShape(t *testing.T) { msg("ListWidgetsRequest", atespace), msg("ListWidgetsResponse", widgets, nextPageToken)), want: []lint.Finding{ - {Subject: "test.Control.ListWidgets", Message: `request has no "options" ateapi.ListOptions field`}, + {Subject: "test.Control.ListWidgets", Message: `request has no "options" substrate.ateapi.v1.ListOptions field`}, }, }, { @@ -334,9 +334,9 @@ func TestListMethodShape(t *testing.T) { model.Field{Name: "page_token", Kind: protoreflect.StringKind, TypeDisplay: "string"}), msg("ListWidgetsResponse", widgets, nextPageToken)), want: []lint.Finding{ - {Subject: "test.Control.ListWidgets", Message: `request field "page_size" is not allowed - want only "atespace" string and "options" ateapi.ListOptions`}, - {Subject: "test.Control.ListWidgets", Message: `request field "page_token" is not allowed - want only "atespace" string and "options" ateapi.ListOptions`}, - {Subject: "test.Control.ListWidgets", Message: `request has no "options" ateapi.ListOptions field`}, + {Subject: "test.Control.ListWidgets", Message: `request field "page_size" is not allowed - want only "atespace" string and "options" substrate.ateapi.v1.ListOptions`}, + {Subject: "test.Control.ListWidgets", Message: `request field "page_token" is not allowed - want only "atespace" string and "options" substrate.ateapi.v1.ListOptions`}, + {Subject: "test.Control.ListWidgets", Message: `request has no "options" substrate.ateapi.v1.ListOptions field`}, }, }, { @@ -406,7 +406,7 @@ func TestListMethodShape(t *testing.T) { msg("ListWidgetsRequest", atespace, options), msg("ListWidgetsResponse", widgets, nextPageToken)), want: []lint.Finding{ - {Subject: "test.Control.ListWidgets", Message: `request field "atespace" is not allowed - want only "options" ateapi.ListOptions`}, + {Subject: "test.Control.ListWidgets", Message: `request field "atespace" is not allowed - want only "options" substrate.ateapi.v1.ListOptions`}, }, }, { @@ -416,7 +416,7 @@ func TestListMethodShape(t *testing.T) { msg("ListWidgetsRequest", atespace, options, model.Field{Name: "filter"}), msg("ListWidgetsResponse", widgets, nextPageToken)), want: []lint.Finding{ - {Subject: "test.Control.ListWidgets", Message: `request field "filter" is not allowed - want only "atespace" string and "options" ateapi.ListOptions`}, + {Subject: "test.Control.ListWidgets", Message: `request field "filter" is not allowed - want only "atespace" string and "options" substrate.ateapi.v1.ListOptions`}, }, }, { @@ -442,7 +442,7 @@ func TestListMethodShape(t *testing.T) { msg("ListWidgetsResponse", widgets, nextPageToken)), want: []lint.Finding{ {Subject: "test.Control.ListWidgets", Message: `request has no "atespace" string field`}, - {Subject: "test.Control.ListWidgets", Message: `request has no "options" ateapi.ListOptions field`}, + {Subject: "test.Control.ListWidgets", Message: `request has no "options" substrate.ateapi.v1.ListOptions field`}, }, }, { @@ -471,7 +471,7 @@ func TestListMethodShape(t *testing.T) { msg("ListGadgetWidgetsRequest", options), msg("ListGadgetWidgetsResponse", widgets, nextPageToken)), want: []lint.Finding{ - {Subject: "test.Control.ListGadgetWidgets", Message: `request has no "gadget" ateapi.ObjectRef field`}, + {Subject: "test.Control.ListGadgetWidgets", Message: `request has no "gadget" substrate.ateapi.v1.ObjectRef field`}, }, }, { @@ -482,7 +482,7 @@ func TestListMethodShape(t *testing.T) { msg("ListGadgetWidgetsRequest", model.Field{Name: "gadget", Kind: protoreflect.StringKind, TypeDisplay: "string"}, options), msg("ListGadgetWidgetsResponse", widgets, nextPageToken)), want: []lint.Finding{ - {Subject: "test.Control.ListGadgetWidgets", Message: `request field "gadget" is string, want ateapi.ObjectRef`}, + {Subject: "test.Control.ListGadgetWidgets", Message: `request field "gadget" is string, want substrate.ateapi.v1.ObjectRef`}, }, }, { @@ -493,7 +493,7 @@ func TestListMethodShape(t *testing.T) { msg("ListGadgetWidgetsRequest", gadgetRef, atespace, options), msg("ListGadgetWidgetsResponse", widgets, nextPageToken)), want: []lint.Finding{ - {Subject: "test.Control.ListGadgetWidgets", Message: `request field "atespace" is not allowed - want only "gadget" ateapi.ObjectRef and "options" ateapi.ListOptions`}, + {Subject: "test.Control.ListGadgetWidgets", Message: `request field "atespace" is not allowed - want only "gadget" substrate.ateapi.v1.ObjectRef and "options" substrate.ateapi.v1.ListOptions`}, }, }, { @@ -518,10 +518,10 @@ func TestListMethodShape(t *testing.T) { name: "subresource of Global: parent field is not allowed", api: methodAPI(rpc("ListGlobalWidgets", "Widget", "ListGlobalWidgetsResponse"), resource("Widget", []string{"Global"}), - msg("ListGlobalWidgetsRequest", model.Field{Name: "global", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"}, options), + msg("ListGlobalWidgetsRequest", model.Field{Name: "global", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"}, options), msg("ListGlobalWidgetsResponse", widgets, nextPageToken)), want: []lint.Finding{ - {Subject: "test.Control.ListGlobalWidgets", Message: `request field "global" is not allowed - want only "options" ateapi.ListOptions`}, + {Subject: "test.Control.ListGlobalWidgets", Message: `request field "global" is not allowed - want only "options" substrate.ateapi.v1.ListOptions`}, }, }, { @@ -530,7 +530,7 @@ func TestListMethodShape(t *testing.T) { resource("Widget", []string{"Gadget", "GadgetBox"}), resource("Gadget", nil), resource("GadgetBox", nil), - msg("ListGadgetBoxWidgetsRequest", model.Field{Name: "gadget_box", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"}, options), + msg("ListGadgetBoxWidgetsRequest", model.Field{Name: "gadget_box", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"}, options), msg("ListGadgetBoxWidgetsResponse", widgets, nextPageToken)), }, } @@ -594,8 +594,8 @@ func TestListResponseNameMatchesMethod(t *testing.T) { func TestCreateRequestShape(t *testing.T) { widget := model.Field{Name: "widget", Kind: protoreflect.MessageKind, TypeFullName: "test.Widget"} misnamedWidget := model.Field{Name: "thing", Kind: protoreflect.MessageKind, TypeFullName: "test.Widget"} - options := model.Field{Name: "options", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.CreateOptions"} - gadgetRef := model.Field{Name: "gadget", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"} + options := model.Field{Name: "options", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.CreateOptions"} + gadgetRef := model.Field{Name: "gadget", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"} tests := []struct { name string @@ -638,16 +638,16 @@ func TestCreateRequestShape(t *testing.T) { resource("Widget", nil), msg("CreateWidgetRequest", widget, options, options)), want: []lint.Finding{ - {Subject: "test.Control.CreateWidget", Message: `request has 2 "options" ateapi.CreateOptions fields, want at most 1`}, + {Subject: "test.Control.CreateWidget", Message: `request has 2 "options" substrate.ateapi.v1.CreateOptions fields, want at most 1`}, }, }, { name: "CreateOptions field misnamed", api: methodAPI(rpc("CreateWidget", "Widget", "Widget"), resource("Widget", nil), - msg("CreateWidgetRequest", widget, model.Field{Name: "opts", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.CreateOptions"})), + msg("CreateWidgetRequest", widget, model.Field{Name: "opts", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.CreateOptions"})), want: []lint.Finding{ - {Subject: "test.Control.CreateWidget", Message: `request field "opts" is ateapi.CreateOptions, want it named "options"`}, + {Subject: "test.Control.CreateWidget", Message: `request field "opts" is substrate.ateapi.v1.CreateOptions, want it named "options"`}, }, }, { @@ -656,7 +656,7 @@ func TestCreateRequestShape(t *testing.T) { resource("Widget", nil), msg("CreateWidgetRequest", widget, model.Field{Name: "dry_run"})), want: []lint.Finding{ - {Subject: "test.Control.CreateWidget", Message: `request field "dry_run" is not allowed - want only "widget" test.Widget and optional "options" ateapi.CreateOptions`}, + {Subject: "test.Control.CreateWidget", Message: `request field "dry_run" is not allowed - want only "widget" test.Widget and optional "options" substrate.ateapi.v1.CreateOptions`}, }, }, { @@ -672,7 +672,7 @@ func TestCreateRequestShape(t *testing.T) { name: "a Delete method is not checked", api: methodAPI(rpc("DeleteWidget", "Widget", "Widget"), resource("Widget", nil), - msg("DeleteWidgetRequest", model.Field{Name: "widget", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"})), + msg("DeleteWidgetRequest", model.Field{Name: "widget", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"})), }, { name: "subresource: parent ObjectRef and resource field", @@ -695,7 +695,7 @@ func TestCreateRequestShape(t *testing.T) { resource("Gadget", nil), msg("CreateGadgetWidgetRequest", widget)), want: []lint.Finding{ - {Subject: "test.Control.CreateGadgetWidget", Message: `request has no "gadget" ateapi.ObjectRef field`}, + {Subject: "test.Control.CreateGadgetWidget", Message: `request has no "gadget" substrate.ateapi.v1.ObjectRef field`}, }, }, { @@ -705,7 +705,7 @@ func TestCreateRequestShape(t *testing.T) { resource("Gadget", nil), msg("CreateGadgetWidgetRequest", model.Field{Name: "gadget", Kind: protoreflect.StringKind, TypeDisplay: "string"}, widget)), want: []lint.Finding{ - {Subject: "test.Control.CreateGadgetWidget", Message: `request field "gadget" is string, want ateapi.ObjectRef`}, + {Subject: "test.Control.CreateGadgetWidget", Message: `request field "gadget" is string, want substrate.ateapi.v1.ObjectRef`}, }, }, { @@ -741,7 +741,7 @@ func TestCreateRequestShape(t *testing.T) { func TestUpdateRequestShape(t *testing.T) { widget := model.Field{Name: "widget", Kind: protoreflect.MessageKind, TypeFullName: "test.Widget"} misnamedWidget := model.Field{Name: "thing", Kind: protoreflect.MessageKind, TypeFullName: "test.Widget"} - gadgetRef := model.Field{Name: "gadget", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"} + gadgetRef := model.Field{Name: "gadget", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"} tests := []struct { name string @@ -794,7 +794,7 @@ func TestUpdateRequestShape(t *testing.T) { name: "a Delete method is not checked", api: methodAPI(rpc("DeleteWidget", "Widget", "Widget"), resource("Widget", nil), - msg("DeleteWidgetRequest", model.Field{Name: "widget", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"})), + msg("DeleteWidgetRequest", model.Field{Name: "widget", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"})), }, { name: "subresource: parent ObjectRef and resource field", @@ -810,7 +810,7 @@ func TestUpdateRequestShape(t *testing.T) { resource("Gadget", nil), msg("UpdateGadgetWidgetRequest", widget)), want: []lint.Finding{ - {Subject: "test.Control.UpdateGadgetWidget", Message: `request has no "gadget" ateapi.ObjectRef field`}, + {Subject: "test.Control.UpdateGadgetWidget", Message: `request has no "gadget" substrate.ateapi.v1.ObjectRef field`}, }, }, { @@ -820,7 +820,7 @@ func TestUpdateRequestShape(t *testing.T) { resource("Gadget", nil), msg("UpdateGadgetWidgetRequest", model.Field{Name: "gadget", Kind: protoreflect.StringKind, TypeDisplay: "string"}, widget)), want: []lint.Finding{ - {Subject: "test.Control.UpdateGadgetWidget", Message: `request field "gadget" is string, want ateapi.ObjectRef`}, + {Subject: "test.Control.UpdateGadgetWidget", Message: `request field "gadget" is string, want substrate.ateapi.v1.ObjectRef`}, }, }, { @@ -854,10 +854,10 @@ func TestUpdateRequestShape(t *testing.T) { } func TestDeleteRequestShape(t *testing.T) { - widgetRef := model.Field{Name: "widget", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"} - misnamedWidgetRef := model.Field{Name: "thing", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"} - options := model.Field{Name: "options", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.DeleteOptions"} - gadgetRef := model.Field{Name: "gadget", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.ObjectRef"} + widgetRef := model.Field{Name: "widget", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"} + misnamedWidgetRef := model.Field{Name: "thing", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"} + options := model.Field{Name: "options", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.DeleteOptions"} + gadgetRef := model.Field{Name: "gadget", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.ObjectRef"} name := model.Field{Name: "name", Kind: protoreflect.StringKind, TypeDisplay: "string"} tests := []struct { @@ -883,7 +883,7 @@ func TestDeleteRequestShape(t *testing.T) { resource("Widget", nil), msg("DeleteWidgetRequest")), want: []lint.Finding{ - {Subject: "test.Control.DeleteWidget", Message: `request has no "widget" ateapi.ObjectRef field`}, + {Subject: "test.Control.DeleteWidget", Message: `request has no "widget" substrate.ateapi.v1.ObjectRef field`}, }, }, { @@ -892,7 +892,7 @@ func TestDeleteRequestShape(t *testing.T) { resource("Widget", nil), msg("DeleteWidgetRequest", widgetRef, widgetRef)), want: []lint.Finding{ - {Subject: "test.Control.DeleteWidget", Message: `request has 2 "widget" ateapi.ObjectRef fields, want at most 1`}, + {Subject: "test.Control.DeleteWidget", Message: `request has 2 "widget" substrate.ateapi.v1.ObjectRef fields, want at most 1`}, }, }, { @@ -901,16 +901,16 @@ func TestDeleteRequestShape(t *testing.T) { resource("Widget", nil), msg("DeleteWidgetRequest", widgetRef, options, options)), want: []lint.Finding{ - {Subject: "test.Control.DeleteWidget", Message: `request has 2 "options" ateapi.DeleteOptions fields, want at most 1`}, + {Subject: "test.Control.DeleteWidget", Message: `request has 2 "options" substrate.ateapi.v1.DeleteOptions fields, want at most 1`}, }, }, { name: "DeleteOptions field misnamed", api: methodAPI(rpc("DeleteWidget", "Widget", "Widget"), resource("Widget", nil), - msg("DeleteWidgetRequest", widgetRef, model.Field{Name: "opts", Kind: protoreflect.MessageKind, TypeFullName: "ateapi.DeleteOptions"})), + msg("DeleteWidgetRequest", widgetRef, model.Field{Name: "opts", Kind: protoreflect.MessageKind, TypeFullName: "substrate.ateapi.v1.DeleteOptions"})), want: []lint.Finding{ - {Subject: "test.Control.DeleteWidget", Message: `request field "opts" is ateapi.DeleteOptions, want it named "options"`}, + {Subject: "test.Control.DeleteWidget", Message: `request field "opts" is substrate.ateapi.v1.DeleteOptions, want it named "options"`}, }, }, { @@ -919,7 +919,7 @@ func TestDeleteRequestShape(t *testing.T) { resource("Widget", nil), msg("DeleteWidgetRequest", widgetRef, model.Field{Name: "dry_run"})), want: []lint.Finding{ - {Subject: "test.Control.DeleteWidget", Message: `request field "dry_run" is not allowed - want only "widget" ateapi.ObjectRef and optional "options" ateapi.DeleteOptions`}, + {Subject: "test.Control.DeleteWidget", Message: `request field "dry_run" is not allowed - want only "widget" substrate.ateapi.v1.ObjectRef and optional "options" substrate.ateapi.v1.DeleteOptions`}, }, }, { @@ -928,7 +928,7 @@ func TestDeleteRequestShape(t *testing.T) { resource("Widget", nil), msg("DeleteWidgetRequest", misnamedWidgetRef)), want: []lint.Finding{ - {Subject: "test.Control.DeleteWidget", Message: `request field "thing" is ateapi.ObjectRef, want it named "widget"`}, + {Subject: "test.Control.DeleteWidget", Message: `request field "thing" is substrate.ateapi.v1.ObjectRef, want it named "widget"`}, }, }, { @@ -968,7 +968,7 @@ func TestDeleteRequestShape(t *testing.T) { resource("Gadget", nil), msg("DeleteGadgetWidgetRequest", name, options)), want: []lint.Finding{ - {Subject: "test.Control.DeleteGadgetWidget", Message: `request has no "gadget" ateapi.ObjectRef field`}, + {Subject: "test.Control.DeleteGadgetWidget", Message: `request has no "gadget" substrate.ateapi.v1.ObjectRef field`}, }, }, { @@ -978,7 +978,7 @@ func TestDeleteRequestShape(t *testing.T) { resource("Gadget", nil), msg("DeleteGadgetWidgetRequest", widgetRef, options)), want: []lint.Finding{ - {Subject: "test.Control.DeleteGadgetWidget", Message: `request field "widget" is ateapi.ObjectRef, want it named "gadget"`}, + {Subject: "test.Control.DeleteGadgetWidget", Message: `request field "widget" is substrate.ateapi.v1.ObjectRef, want it named "gadget"`}, {Subject: "test.Control.DeleteGadgetWidget", Message: `request has no "name" string field`}, }, }, @@ -989,7 +989,7 @@ func TestDeleteRequestShape(t *testing.T) { resource("Gadget", nil), msg("DeleteGadgetWidgetRequest", gadgetRef, name, options, options)), want: []lint.Finding{ - {Subject: "test.Control.DeleteGadgetWidget", Message: `request has 2 "options" ateapi.DeleteOptions fields, want at most 1`}, + {Subject: "test.Control.DeleteGadgetWidget", Message: `request has 2 "options" substrate.ateapi.v1.DeleteOptions fields, want at most 1`}, }, }, { @@ -999,7 +999,7 @@ func TestDeleteRequestShape(t *testing.T) { resource("Gadget", nil), msg("DeleteGadgetWidgetRequest", gadgetRef, name, model.Field{Name: "dry_run"})), want: []lint.Finding{ - {Subject: "test.Control.DeleteGadgetWidget", Message: `request field "dry_run" is not allowed - want only "gadget" ateapi.ObjectRef, "name" string, and optional "options" ateapi.DeleteOptions`}, + {Subject: "test.Control.DeleteGadgetWidget", Message: `request field "dry_run" is not allowed - want only "gadget" substrate.ateapi.v1.ObjectRef, "name" string, and optional "options" substrate.ateapi.v1.DeleteOptions`}, }, }, { @@ -1026,7 +1026,7 @@ func TestDeleteOptionsShape(t *testing.T) { version := model.Field{Name: "version", Kind: protoreflect.Int64Kind, TypeDisplay: "int64"} uid := model.Field{Name: "uid", Kind: protoreflect.StringKind, TypeDisplay: "string"} deleteOptions := func(fields ...model.Field) model.Message { - return model.Message{FullName: "ateapi.DeleteOptions", Name: "DeleteOptions", Fields: fields} + return model.Message{FullName: "substrate.ateapi.v1.DeleteOptions", Name: "DeleteOptions", Fields: fields} } tests := []struct { @@ -1054,21 +1054,21 @@ func TestDeleteOptionsShape(t *testing.T) { name: "version wrong type", api: messagesAPI(deleteOptions(model.Field{Name: "version", Kind: protoreflect.StringKind, TypeDisplay: "string"}, uid)), want: []lint.Finding{ - {Subject: "ateapi.DeleteOptions", Message: `DeleteOptions field "version" is string, want int64`}, + {Subject: "substrate.ateapi.v1.DeleteOptions", Message: `DeleteOptions field "version" is string, want int64`}, }, }, { name: "uid wrong type", api: messagesAPI(deleteOptions(version, model.Field{Name: "uid", Kind: protoreflect.Int64Kind, TypeDisplay: "int64"})), want: []lint.Finding{ - {Subject: "ateapi.DeleteOptions", Message: `DeleteOptions field "uid" is int64, want string`}, + {Subject: "substrate.ateapi.v1.DeleteOptions", Message: `DeleteOptions field "uid" is int64, want string`}, }, }, { name: "extra field beyond version/uid", api: messagesAPI(deleteOptions(version, uid, model.Field{Name: "dry_run", Kind: protoreflect.BoolKind, TypeDisplay: "bool"})), want: []lint.Finding{ - {Subject: "ateapi.DeleteOptions", Message: `DeleteOptions field "dry_run" is not allowed - want only optional "version" int64 and optional "uid" string`}, + {Subject: "substrate.ateapi.v1.DeleteOptions", Message: `DeleteOptions field "dry_run" is not allowed - want only optional "version" int64 and optional "uid" string`}, }, }, { diff --git a/tools/apitool/internal/model/model.go b/tools/apitool/internal/model/model.go index aee7cb5d31..18f505e2e5 100644 --- a/tools/apitool/internal/model/model.go +++ b/tools/apitool/internal/model/model.go @@ -26,7 +26,7 @@ import ( "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" ) // sourceFileName is an arbitrary internal label: Build only ever compiles @@ -44,12 +44,12 @@ type API struct { // ateapi.proto's single "Control" service. Services []Service // Messages lists every message declared in the file, top-level and - // nested, flattened into one slice. For example, "ateapi.Actor" and - // "ateapi.ResourceMetadata" both appear here as top-level entries. + // nested, flattened into one slice. For example, "substrate.ateapi.v1.Actor" and + // "substrate.ateapi.v1.ResourceMetadata" both appear here as top-level entries. Messages []Message // Enums lists every enum declared in the file, top-level and nested, // flattened the same way as Messages. For example, the top-level - // "ateapi.ActorState" appears here. + // "substrate.ateapi.v1.ActorState" appears here. Enums []Enum } @@ -65,7 +65,7 @@ func (a API) MessagesByFullName() map[protoreflect.FullName]Message { // Service is one RPC service. For example, ateapi.proto's "Control" service. type Service struct { - // FullName is the service's proto full name. For example, "ateapi.Control". + // FullName is the service's proto full name. For example, "substrate.ateapi.v1.Control". FullName protoreflect.FullName // Name is the service's short name. For example, "Control". Name protoreflect.Name @@ -86,20 +86,20 @@ type Method struct { // new Actor deriving from a given ActorTemplate." Comment string // InputName is the full name of the request message, for linking. For - // example, "ateapi.CreateActorRequest" for CreateActor. + // example, "substrate.ateapi.v1.CreateActorRequest" for CreateActor. InputName protoreflect.FullName // OutputName is the full name of the response message, for linking. - // For example, "ateapi.Actor" for CreateActor - most standard methods + // For example, "substrate.ateapi.v1.Actor" for CreateActor - most standard methods // return the resource itself rather than a wrapper message. OutputName protoreflect.FullName - // Resource is the resource the method's (ateapi.method) annotation + // Resource is the resource the method's (substrate.ateapi.v1.method) annotation // names, or "" if the method has none. For example, "Actor" for // SuspendActor, or "EgressPolicy" for GetActorEgressPolicy. Resource string // ServiceFullName is the declaring service's full name. For example, - // "ateapi.Control". + // "substrate.ateapi.v1.Control". ServiceFullName protoreflect.FullName // ServiceName is the declaring service's short name. For example, "Control". ServiceName protoreflect.Name @@ -108,7 +108,7 @@ type Method struct { // Message is one message declared in the file, top-level or nested. type Message struct { // FullName is the message's proto full name. For example, - // "ateapi.ResourceMetadata". + // "substrate.ateapi.v1.ResourceMetadata". FullName protoreflect.FullName // Name is the message's short name, with its enclosing message's name // dotted in front for a nested type. For example, "ResourceMetadata" @@ -117,7 +117,7 @@ type Message struct { // here. Name string // ParentFullName is the enclosing message's full name, or "" for a - // top-level message. For example, "" for "ateapi.ResourceMetadata". + // top-level message. For example, "" for "substrate.ateapi.v1.ResourceMetadata". ParentFullName protoreflect.FullName // Comment is the message's leading doc comment. For example, // "ResourceMetadata holds the common fields carried by every Substrate @@ -127,9 +127,9 @@ type Message struct { // example, ResourceMetadata's atespace, name, uid, version, // create_time, update_time. Fields []Field - // ResourceAnnotation is the message's (ateapi.resource) annotation, or + // ResourceAnnotation is the message's (substrate.ateapi.v1.resource) annotation, or // nil if the message isn't a resource. For example, non-nil for - // "ateapi.Actor"; nil for "ateapi.ResourceMetadata". + // "substrate.ateapi.v1.Actor"; nil for "substrate.ateapi.v1.ResourceMetadata". ResourceAnnotation *ResourceAnnotation } @@ -138,7 +138,7 @@ func (m Message) IsResource() bool { return m.ResourceAnnotation != nil } -// ResourceAnnotation is a resource message's (ateapi.resource) annotation. +// ResourceAnnotation is a resource message's (substrate.ateapi.v1.resource) annotation. type ResourceAnnotation struct { // Parents lists the resource types this resource is a subresource of: // another resource's message name, or GlobalParent. For example, @@ -151,7 +151,7 @@ type ResourceAnnotation struct { // Scope is whether a top-level resource belongs to an atespace. For // example, SCOPE_ATESPACE for Actor, or SCOPE_GLOBAL for Worker. Set // only on a top-level resource: a subresource has its parent's scope. - Scope ateapipb.Scope + Scope ateapi.Scope // Plural is the resource's plural name. For example, "AccessPolicies" // for AccessPolicy. Plural string @@ -189,15 +189,15 @@ type Field struct { Kind protoreflect.Kind // TypeFullName is set only for a singular or repeated message/enum // field. Empty for scalars and maps - see MapValueFullName for a map's - // value type. For example, "ateapi.ResourceMetadata" for Actor.metadata - // (`ResourceMetadata metadata = 1;`), or "ateapi.ActorState" for + // value type. For example, "substrate.ateapi.v1.ResourceMetadata" for Actor.metadata + // (`ResourceMetadata metadata = 1;`), or "substrate.ateapi.v1.ActorState" for // ActorStatus.state (`ActorState state = 1;`). TypeFullName protoreflect.FullName // TypeIsExternal is true when the type isn't declared in this proto // file (for example, an imported well-known type). For example, true // for ResourceMetadata.create_time (google.protobuf.Timestamp, // imported from google/protobuf/timestamp.proto); false for - // Actor.metadata (ateapi.ResourceMetadata, declared in ateapi.proto + // Actor.metadata (substrate.ateapi.v1.ResourceMetadata, declared in ateapi.proto // itself). TypeIsExternal bool @@ -225,8 +225,8 @@ type Field struct { // Enum is one enum declared in the file, top-level or nested. type Enum struct { - // FullName is the enum's proto full name. For example, "ateapi.ActorState" - // for a top-level enum, or "ateapi.Parent.Status" for one nested inside + // FullName is the enum's proto full name. For example, "substrate.ateapi.v1.ActorState" + // for a top-level enum, or "substrate.ateapi.v1.Parent.Status" for one nested inside // a Parent message. FullName protoreflect.FullName // Name is the enum's short name, with its enclosing message's name @@ -234,8 +234,8 @@ type Enum struct { // the top-level enum, or "Parent.Status" for one nested inside Parent. Name string // ParentFullName is the enclosing message's full name, or "" for a - // top-level enum. For example, "" for "ateapi.ActorState", or - // "ateapi.Parent" for "ateapi.Parent.Status". + // top-level enum. For example, "" for "substrate.ateapi.v1.ActorState", or + // "substrate.ateapi.v1.Parent" for "substrate.ateapi.v1.Parent.Status". ParentFullName protoreflect.FullName // Comment is the enum's leading doc comment. ateapi.proto's ActorState // has none today, so this is often "" in practice even though the field @@ -446,7 +446,7 @@ func buildMessage(fd protoreflect.FileDescriptor, md protoreflect.MessageDescrip // into this binary under d's full name, or nil if there's none. Build reads // annotations from there rather than from d: protocompile, compiling the // annotations' own definitions from source, fills them in as dynamic -// messages that the generated ateapipb extension types can't read. +// messages that the generated ateapi extension types can't read. func generatedOptions(d protoreflect.Descriptor) proto.Message { g, err := protoregistry.GlobalFiles.FindDescriptorByName(d.FullName()) if err != nil { @@ -460,15 +460,15 @@ func methodResource(md protoreflect.MethodDescriptor) string { if opts == nil { return "" } - return proto.GetExtension(opts, ateapipb.E_Method).(*ateapipb.MethodAnnotation).GetResource() + return proto.GetExtension(opts, ateapi.E_Method).(*ateapi.MethodAnnotation).GetResource() } func resourceAnnotation(md protoreflect.MessageDescriptor) *ResourceAnnotation { opts := generatedOptions(md) - if opts == nil || !proto.HasExtension(opts, ateapipb.E_Resource) { + if opts == nil || !proto.HasExtension(opts, ateapi.E_Resource) { return nil } - a := proto.GetExtension(opts, ateapipb.E_Resource).(*ateapipb.ResourceAnnotation) + a := proto.GetExtension(opts, ateapi.E_Resource).(*ateapi.ResourceAnnotation) return &ResourceAnnotation{ Parents: a.GetParents(), Singleton: a.GetSingleton(), @@ -561,7 +561,7 @@ func scalarOrTypeName(fd protoreflect.FileDescriptor, mapField protoreflect.Fiel } // shortName strips fd's package prefix from a full name. For example, -// "ateapi.Actor.Status" -> "Actor.Status". +// "substrate.ateapi.v1.Actor.Status" -> "Actor.Status". func shortName(fd protoreflect.FileDescriptor, full protoreflect.FullName) string { return strings.TrimPrefix(string(full), string(fd.Package())+".") } @@ -615,11 +615,11 @@ func Resources(api *API) ([]Resource, error) { for _, svc := range api.Services { for _, method := range svc.Methods { if method.Resource == "" { - return nil, fmt.Errorf("%s.%s: no resource annotation - add `option (ateapi.method).resource = \"\";`", svc.Name, method.Name) + return nil, fmt.Errorf("%s.%s: no resource annotation - add `option (substrate.ateapi.v1.method).resource = \"\";`", svc.Name, method.Name) } r, ok := byName[method.Resource] if !ok { - return nil, fmt.Errorf("%s.%s: annotated resource %q is not a resource in this API - annotate its message with (ateapi.resource)", svc.Name, method.Name, method.Resource) + return nil, fmt.Errorf("%s.%s: annotated resource %q is not a resource in this API - annotate its message with (substrate.ateapi.v1.resource)", svc.Name, method.Name, method.Resource) } r.Methods = append(r.Methods, method) } @@ -628,7 +628,7 @@ func Resources(api *API) ([]Resource, error) { return resources, nil } -// validateAnnotation checks resource's (ateapi.resource) annotation: each +// validateAnnotation checks resource's (substrate.ateapi.v1.resource) annotation: each // parent is GlobalParent or a resource in byName, the plural is set, and a // scope is set exactly when resource is top-level. func validateAnnotation(resource Message, byName map[string]*Resource) error { @@ -639,12 +639,12 @@ func validateAnnotation(resource Message, byName map[string]*Resource) error { } } if annotation.Plural == "" { - return fmt.Errorf("%s: resource has no plural - set `plural` in its (ateapi.resource) annotation", resource.FullName) + return fmt.Errorf("%s: resource has no plural - set `plural` in its (substrate.ateapi.v1.resource) annotation", resource.FullName) } - if len(annotation.Parents) == 0 && annotation.Scope == ateapipb.Scope_SCOPE_UNSPECIFIED { - return fmt.Errorf("%s: top-level resource has no scope - set `scope` in its (ateapi.resource) annotation", resource.FullName) + if len(annotation.Parents) == 0 && annotation.Scope == ateapi.Scope_SCOPE_UNSPECIFIED { + return fmt.Errorf("%s: top-level resource has no scope - set `scope` in its (substrate.ateapi.v1.resource) annotation", resource.FullName) } - if len(annotation.Parents) > 0 && annotation.Scope != ateapipb.Scope_SCOPE_UNSPECIFIED { + if len(annotation.Parents) > 0 && annotation.Scope != ateapi.Scope_SCOPE_UNSPECIFIED { return fmt.Errorf("%s: subresource has scope %s - a subresource has its parent's scope, so leave `scope` unset", resource.FullName, annotation.Scope) } return nil diff --git a/tools/apitool/internal/model/model_test.go b/tools/apitool/internal/model/model_test.go index 8b3e9ab74a..b421161ee1 100644 --- a/tools/apitool/internal/model/model_test.go +++ b/tools/apitool/internal/model/model_test.go @@ -21,7 +21,7 @@ import ( "github.com/google/go-cmp/cmp" "google.golang.org/protobuf/reflect/protoreflect" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/tools/apitool/internal/model" ) @@ -206,7 +206,7 @@ message Widget { } func TestBuild_Annotations(t *testing.T) { - api, err := model.Build(t.Context(), ateapipb.Source) + api, err := model.Build(t.Context(), ateapi.Source) if err != nil { t.Fatalf("Build() error = %v", err) } @@ -218,12 +218,12 @@ func TestBuild_Annotations(t *testing.T) { } } wantResources := map[string]*model.ResourceAnnotation{ - "Actor": {Scope: ateapipb.Scope_SCOPE_ATESPACE, Plural: "Actors"}, + "Actor": {Scope: ateapi.Scope_SCOPE_ATESPACE, Plural: "Actors"}, "EgressPolicy": {Parents: []string{"Actor"}, Singleton: true, Plural: "EgressPolicies"}, - "Tag": {Scope: ateapipb.Scope_SCOPE_ATESPACE, Plural: "Tags"}, - "Atespace": {Scope: ateapipb.Scope_SCOPE_GLOBAL, Plural: "Atespaces"}, - "ActorTemplate": {Scope: ateapipb.Scope_SCOPE_ATESPACE, Plural: "ActorTemplates"}, - "Worker": {Scope: ateapipb.Scope_SCOPE_GLOBAL, Plural: "Workers"}, + "Tag": {Scope: ateapi.Scope_SCOPE_ATESPACE, Plural: "Tags"}, + "Atespace": {Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "Atespaces"}, + "ActorTemplate": {Scope: ateapi.Scope_SCOPE_ATESPACE, Plural: "ActorTemplates"}, + "Worker": {Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "Workers"}, "ActorAssignment": {Parents: []string{"Worker"}, Plural: "ActorAssignments"}, "AccessPolicy": {Parents: []string{"Global", "Atespace"}, Singleton: true, Plural: "AccessPolicies"}, } @@ -264,8 +264,8 @@ func TestResources(t *testing.T) { }}, Messages: []model.Message{ {FullName: "test.GetActorRequest", Name: "GetActorRequest"}, - {FullName: "test.Worker", Name: "Worker", ResourceAnnotation: &model.ResourceAnnotation{Scope: ateapipb.Scope_SCOPE_GLOBAL, Plural: "Workers"}}, - {FullName: "test.Actor", Name: "Actor", ResourceAnnotation: &model.ResourceAnnotation{Scope: ateapipb.Scope_SCOPE_ATESPACE, Plural: "Actors"}}, + {FullName: "test.Worker", Name: "Worker", ResourceAnnotation: &model.ResourceAnnotation{Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "Workers"}}, + {FullName: "test.Actor", Name: "Actor", ResourceAnnotation: &model.ResourceAnnotation{Scope: ateapi.Scope_SCOPE_ATESPACE, Plural: "Actors"}}, {FullName: "test.EgressPolicy", Name: "EgressPolicy", ResourceAnnotation: &model.ResourceAnnotation{Parents: []string{"Global", "Actor"}, Plural: "EgressPolicies"}}, }, } @@ -307,7 +307,7 @@ func TestResources_Invalid(t *testing.T) { name: "method without annotation", api: &model.API{ Services: []model.Service{{Name: "Control", Methods: []model.Method{{Name: "GetActor"}}}}, - Messages: []model.Message{{FullName: "test.Actor", Name: "Actor", ResourceAnnotation: &model.ResourceAnnotation{Scope: ateapipb.Scope_SCOPE_ATESPACE, Plural: "Actors"}}}, + Messages: []model.Message{{FullName: "test.Actor", Name: "Actor", ResourceAnnotation: &model.ResourceAnnotation{Scope: ateapi.Scope_SCOPE_ATESPACE, Plural: "Actors"}}}, }, wantErr: "Control.GetActor: no resource annotation", }, @@ -338,7 +338,7 @@ func TestResources_Invalid(t *testing.T) { { name: "resource without plural", api: &model.API{ - Messages: []model.Message{{FullName: "test.Actor", Name: "Actor", ResourceAnnotation: &model.ResourceAnnotation{Scope: ateapipb.Scope_SCOPE_ATESPACE}}}, + Messages: []model.Message{{FullName: "test.Actor", Name: "Actor", ResourceAnnotation: &model.ResourceAnnotation{Scope: ateapi.Scope_SCOPE_ATESPACE}}}, }, wantErr: "test.Actor: resource has no plural", }, @@ -353,8 +353,8 @@ func TestResources_Invalid(t *testing.T) { name: "subresource with scope", api: &model.API{ Messages: []model.Message{ - {FullName: "test.Actor", Name: "Actor", ResourceAnnotation: &model.ResourceAnnotation{Scope: ateapipb.Scope_SCOPE_ATESPACE, Plural: "Actors"}}, - {FullName: "test.EgressPolicy", Name: "EgressPolicy", ResourceAnnotation: &model.ResourceAnnotation{Parents: []string{"Actor"}, Scope: ateapipb.Scope_SCOPE_ATESPACE, Plural: "EgressPolicies"}}, + {FullName: "test.Actor", Name: "Actor", ResourceAnnotation: &model.ResourceAnnotation{Scope: ateapi.Scope_SCOPE_ATESPACE, Plural: "Actors"}}, + {FullName: "test.EgressPolicy", Name: "EgressPolicy", ResourceAnnotation: &model.ResourceAnnotation{Parents: []string{"Actor"}, Scope: ateapi.Scope_SCOPE_ATESPACE, Plural: "EgressPolicies"}}, }, }, wantErr: "test.EgressPolicy: subresource has scope SCOPE_ATESPACE", @@ -374,7 +374,7 @@ func TestScopeToService(t *testing.T) { control := model.Service{Name: "Control", Methods: []model.Method{ {Name: "GetActorEgressPolicy", ServiceName: "Control", InputName: "test.GetActorEgressPolicyRequest", OutputName: "test.EgressPolicy", Resource: "EgressPolicy"}, }} - actor := model.Message{FullName: "test.Actor", Name: "Actor", ResourceAnnotation: &model.ResourceAnnotation{Scope: ateapipb.Scope_SCOPE_ATESPACE, Plural: "Actors"}} + actor := model.Message{FullName: "test.Actor", Name: "Actor", ResourceAnnotation: &model.ResourceAnnotation{Scope: ateapi.Scope_SCOPE_ATESPACE, Plural: "Actors"}} egressPolicy := model.Message{FullName: "test.EgressPolicy", Name: "EgressPolicy", ResourceAnnotation: &model.ResourceAnnotation{Parents: []string{"Global", "Actor"}, Plural: "EgressPolicies"}} request := model.Message{FullName: "test.GetActorEgressPolicyRequest", Name: "GetActorEgressPolicyRequest"} unused := model.Message{FullName: "test.Unused", Name: "Unused"} diff --git a/tools/apitool/internal/validate/validate.go b/tools/apitool/internal/validate/validate.go index ae7b5f5555..ca53f1f0d5 100644 --- a/tools/apitool/internal/validate/validate.go +++ b/tools/apitool/internal/validate/validate.go @@ -25,7 +25,7 @@ import ( "path/filepath" "strings" - "go.ate.dev/substrate/pkg/proto/ateapipb" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/tools/apitool/internal/exemption" "go.ate.dev/substrate/tools/apitool/internal/lint" "go.ate.dev/substrate/tools/apitool/internal/model" @@ -40,7 +40,7 @@ const serviceName = "Control" // from, so which service and proto file that is stays this package's own // concern. func API(ctx context.Context) (*model.API, error) { - api, err := model.Build(ctx, ateapipb.Source) + api, err := model.Build(ctx, ateapi.Source) if err != nil { return nil, fmt.Errorf("while building API model: %w", err) } diff --git a/tools/setup-gcp/README.md b/tools/setup-gcp/README.md index 3a6b41883e..981a1bd307 100644 --- a/tools/setup-gcp/README.md +++ b/tools/setup-gcp/README.md @@ -74,25 +74,42 @@ add-on setting. > ClusterTrustBundle discovery prefers `certificates.k8s.io/v1`, falling back > to `certificates.k8s.io/v1beta1` only when the stable resource is not served. > PodCertificateRequest discovery independently prefers `v1` over `v1beta1`. -> For GKE deployments, the supported configurations are: +> GKE 1.37 and higher serve both under `v1` by default. GKE 1.36 serves them +> only under `v1beta1`, as beta APIs that must be enabled. Versions below 1.36 +> are not supported. > -> * **GKE 1.36 with the beta APIs enabled at cluster creation.** GKE only -> honors `enableK8sBetaApis` **at creation time**. Enabling the APIs later -> on an existing cluster is not recoverable in place: the tool's reconcile -> path issues the update, but the APIs do not become served — the cluster -> must be **recreated** with them enabled. -> * **GKE 1.37 or higher**, where the APIs are served by default and no beta -> enablement is needed. -> -> Versions below 1.36 are not supported. `create cluster` handles the -> enablement for you; if you bring your own 1.36 cluster, create it with both -> APIs enabled from the start, e.g.: +> `create cluster` enables the beta APIs on every cluster it creates, whatever +> its version. If you bring your own 1.36 cluster, create it with them: > > ```bash > gcloud container clusters create "${CLUSTER_NAME}" ... \ > --enable-kubernetes-unstable-apis=certificates.k8s.io/v1beta1/podcertificaterequests,certificates.k8s.io/v1beta1/clustertrustbundles > ``` > +> A 1.36 cluster created without them can be fixed in place: `create cluster` +> and `bootstrap` turn them on for an existing cluster, or run `gcloud +> container clusters update` with the same flag yourself. The APIs are served +> once the update finishes. **That is not enough on its own:** pod +> certificate projection is a kubelet feature, gated through 1.36, and nodes +> that were already running do not pick it up. Pods scheduled onto them fail +> with `MountVolume.SetUp failed: unimplemented`. Replace each such pool: +> create a new one, let workloads move to it, then delete the old one. The +> tool logs both commands for every pool it finds, with the new pool's +> machine type, disk, node count and nested virtualization copied from the +> old one; carry over anything else you customized (taints, service account, +> autoscaling) yourself: +> +> ```bash +> gcloud container node-pools create "${NODE_POOL}-2" --cluster="${CLUSTER_NAME}" \ +> --location="${CLUSTER_LOCATION}" --machine-type="${NODE_MACHINE_TYPE}" ... +> gcloud container node-pools delete "${NODE_POOL}" --cluster="${CLUSTER_NAME}" \ +> --location="${CLUSTER_LOCATION}" +> ``` +> +> Upgrading a pool to the version it already runs does **not** help: GKE +> skips a same-version upgrade without recreating any nodes. Node pools on +> 1.37 or higher need nothing further. +> > The symptom of a cluster without the APIs: the install hangs at "Waiting for > podcertificate ClusterTrustBundles to be ready" and `kubectl get > clustertrustbundles` reports the resource type is not served. diff --git a/tools/setup-gcp/cmd/cluster.go b/tools/setup-gcp/cmd/cluster.go index 9225a7c356..d8be40dd50 100644 --- a/tools/setup-gcp/cmd/cluster.go +++ b/tools/setup-gcp/cmd/cluster.go @@ -21,6 +21,7 @@ import ( "log/slog" "maps" "slices" + "strconv" "strings" "time" @@ -151,6 +152,114 @@ func nodeSysctlsConfigured(cluster *containerpb.Cluster) bool { return false } +// podCertificateProjectionGAMinor is the first Kubernetes 1.x minor whose +// kubelet serves pod certificate projection without a feature gate. +const podCertificateProjectionGAMinor = 37 + +// nodePoolsWithoutPodCertificateProjection returns the pools whose nodes will +// not mount pod certificate volumes after the beta APIs are turned on in place. +// +// Turning the APIs on is a control-plane change, and it is enough on its own: +// the APIs are served afterward. But projection is a kubelet feature, gated +// through 1.36, and a kubelet that was already running when the APIs were +// turned on never picks it up. Pods with a pod certificate volume scheduled +// onto such a node fail with "MountVolume.SetUp failed: unimplemented" while +// the control plane looks healthy. Nodes created afterward are fine, as is +// any kubelet on 1.37 or later, where projection is GA. +// +// It is the pool's version that decides this, not the control plane's: a 1.37 +// control plane can still be running 1.36 nodes. A version that cannot be +// parsed is reported too, since a spurious warning costs far less than a +// silent mount failure. +func nodePoolsWithoutPodCertificateProjection(cluster *containerpb.Cluster) []*containerpb.NodePool { + var stale []*containerpb.NodePool + for _, pool := range cluster.GetNodePools() { + if minor, ok := kubernetesMinor(pool.GetVersion()); ok && minor >= podCertificateProjectionGAMinor { + continue + } + stale = append(stale, pool) + } + return stale +} + +// kubernetesMinor extracts the minor from a GKE version such as +// "1.36.4-gke.1247000". It only understands Kubernetes 1.x. +func kubernetesMinor(version string) (int, bool) { + major, rest, ok := strings.Cut(version, ".") + if !ok || major != "1" { + return 0, false + } + minor, _, _ := strings.Cut(rest, ".") + n, err := strconv.Atoi(minor) + if err != nil { + return 0, false + } + return n, true +} + +// replacementNodePoolCommand is the command that adds a pool to take over +// from one whose nodes predate the beta APIs. A new pool is the remedy because +// it is the one GKE operation that is certain to produce new kubelets: an +// upgrade to the version a pool already runs is skipped outright, and a pool +// can only be upgraded forward when GKE happens to offer a newer patch. +// +// It copies what this tool sets on the pools it creates, so for a cluster +// this tool made the new pool is equivalent. Anything else customized on the +// old pool (taints, service account, autoscaling) has to be carried over by +// hand, which the warning says. +func replacementNodePoolCommand(cfg *Config, pool *containerpb.NodePool) string { + nodeConfig := pool.GetConfig() + args := []string{ + "gcloud container node-pools create " + replacementNodePoolName(pool.GetName()), + "--cluster=" + cfg.ClusterName, + "--project=" + cfg.ProjectID, + "--location=" + cfg.ClusterLocation, + "--node-version=" + pool.GetVersion(), + "--machine-type=" + nodeConfig.GetMachineType(), + fmt.Sprintf("--num-nodes=%d", max(pool.GetInitialNodeCount(), 1)), + } + if nodeConfig.GetDiskSizeGb() > 0 { + args = append(args, fmt.Sprintf("--disk-size=%d", nodeConfig.GetDiskSizeGb())) + } + if nodeConfig.GetDiskType() != "" { + args = append(args, "--disk-type="+nodeConfig.GetDiskType()) + } + if nodeConfig.GetAdvancedMachineFeatures().GetEnableNestedVirtualization() { + args = append(args, "--enable-nested-virtualization") + } + return strings.Join(args, " ") +} + +// replacementNodePoolName derives a name for the replacement pool. GKE caps +// pool names at 40 characters. +func replacementNodePoolName(name string) string { + const suffix = "-2" + if len(name)+len(suffix) > 40 { + name = strings.TrimRight(name[:40-len(suffix)], "-") + } + return name + suffix +} + +// deleteNodePoolCommand removes the old pool once its workloads have moved. +func deleteNodePoolCommand(cfg *Config, pool *containerpb.NodePool) string { + return fmt.Sprintf("gcloud container node-pools delete %s --cluster=%s --project=%s --location=%s", + pool.GetName(), cfg.ClusterName, cfg.ProjectID, cfg.ClusterLocation) +} + +// warnNodePoolsWithoutPodCertificateProjection is called after this tool has +// turned the beta APIs on for an existing cluster. Replacing a pool moves +// running workloads, so it is left to the user rather than done here. +func warnNodePoolsWithoutPodCertificateProjection(cfg *Config, cluster *containerpb.Cluster) { + for _, pool := range nodePoolsWithoutPodCertificateProjection(cluster) { + slog.Warn("Node pool predates the beta APIs and its nodes cannot mount pod certificate volumes; replace it with a new pool, copying over any settings of its own such as taints, service account, or autoscaling", + slog.String("cluster", cfg.ClusterName), + slog.String("node_pool", pool.GetName()), + slog.String("version", pool.GetVersion()), + slog.String("create_replacement", replacementNodePoolCommand(cfg, pool)), + slog.String("then_delete_old", deleteNodePoolCommand(cfg, pool))) + } +} + func createClusterInternal(ctx context.Context, cfg *Config, client *container.ClusterManagerClient, parent string) error { slog.Info("Cluster does not exist. Creating...", slog.String("cluster", cfg.ClusterName)) req := buildCreateClusterRequest(parent, cfg) @@ -276,6 +385,7 @@ func createClusterIdempotent(ctx context.Context, cfg *Config) error { if err := waitContainerOperation(ctx, client, op.Name, cfg); err != nil { return err } + warnNodePoolsWithoutPodCertificateProjection(cfg, cluster) } else { slog.Info("Cluster EnableK8SBetaApis match perfectly.", slog.String("cluster", cfg.ClusterName)) } diff --git a/tools/setup-gcp/cmd/cluster_test.go b/tools/setup-gcp/cmd/cluster_test.go index e59d98e2fa..8fba804a01 100644 --- a/tools/setup-gcp/cmd/cluster_test.go +++ b/tools/setup-gcp/cmd/cluster_test.go @@ -440,3 +440,143 @@ func TestValidateClusterLocation(t *testing.T) { }) } } + +func TestNodePoolsWithoutPodCertificateProjection(t *testing.T) { + pool := func(name, version string) *containerpb.NodePool { + return &containerpb.NodePool{Name: name, Version: version} + } + tests := []struct { + name string + pools []*containerpb.NodePool + want []string + }{ + { + name: "1.36 pool needs its nodes recreated", + pools: []*containerpb.NodePool{pool("default-pool", "1.36.4-gke.1247000")}, + want: []string{"default-pool"}, + }, + { + name: "1.37 pool is fine, projection is GA in its kubelet", + pools: []*containerpb.NodePool{pool("default-pool", "1.37.0-gke.3503000")}, + }, + { + // A 1.37 control plane does not help 1.36 kubelets, so only the + // old pool is reported. + name: "only the pools below 1.37 are reported", + pools: []*containerpb.NodePool{ + pool("old", "1.36.4-gke.1247000"), + pool("new", "1.37.0-gke.3503000"), + }, + want: []string{"old"}, + }, + { + name: "an unreadable version is reported rather than assumed fine", + pools: []*containerpb.NodePool{pool("mystery", "")}, + want: []string{"mystery"}, + }, + { + name: "no pools, nothing to report", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var got []string + for _, p := range nodePoolsWithoutPodCertificateProjection(&containerpb.Cluster{NodePools: tt.pools}) { + got = append(got, p.GetName()) + } + if strings.Join(got, ",") != strings.Join(tt.want, ",") { + t.Errorf("got %v, want %v", got, tt.want) + } + }) + } +} + +func TestKubernetesMinor(t *testing.T) { + tests := []struct { + version string + want int + wantOK bool + }{ + {version: "1.36.4-gke.1247000", want: 36, wantOK: true}, + {version: "1.37", want: 37, wantOK: true}, + {version: "1.100.0", want: 100, wantOK: true}, + {version: ""}, + {version: "latest"}, + {version: "2.0.0"}, + {version: "1.x.0"}, + } + + for _, tt := range tests { + t.Run(tt.version, func(t *testing.T) { + got, ok := kubernetesMinor(tt.version) + if ok != tt.wantOK || got != tt.want { + t.Errorf("kubernetesMinor(%q) = %d, %v; want %d, %v", tt.version, got, ok, tt.want, tt.wantOK) + } + }) + } +} + +func TestReplacementNodePoolCommand(t *testing.T) { + cfg := &Config{ProjectID: "my-project", ClusterName: "substrate-poc", ClusterLocation: "us-west1-c"} + tests := []struct { + name string + pool *containerpb.NodePool + want string + }{ + { + name: "a pool this tool created carries its disk and nested virtualization over", + pool: &containerpb.NodePool{ + Name: "substrate-node-pool", + Version: "1.36.4-gke.1247000", + InitialNodeCount: 2, + Config: &containerpb.NodeConfig{ + MachineType: "c3-standard-4", + DiskSizeGb: 500, + DiskType: "pd-balanced", + AdvancedMachineFeatures: &containerpb.AdvancedMachineFeatures{EnableNestedVirtualization: proto.Bool(true)}, + }, + }, + want: "gcloud container node-pools create substrate-node-pool-2 --cluster=substrate-poc --project=my-project --location=us-west1-c --node-version=1.36.4-gke.1247000 --machine-type=c3-standard-4 --num-nodes=2 --disk-size=500 --disk-type=pd-balanced --enable-nested-virtualization", + }, + { + // Autoscaled pools can report zero; a pool with no nodes would + // leave nothing for the workloads to move to. + name: "defaults stay defaults, and the pool gets at least one node", + pool: &containerpb.NodePool{ + Name: "default-pool", + Version: "1.36.4-gke.1082000", + Config: &containerpb.NodeConfig{MachineType: "e2-standard-4"}, + }, + want: "gcloud container node-pools create default-pool-2 --cluster=substrate-poc --project=my-project --location=us-west1-c --node-version=1.36.4-gke.1082000 --machine-type=e2-standard-4 --num-nodes=1", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := replacementNodePoolCommand(cfg, tt.pool); got != tt.want { + t.Errorf("got %q\nwant %q", got, tt.want) + } + }) + } +} + +func TestReplacementNodePoolNameFitsGKELimit(t *testing.T) { + long := strings.Repeat("a", 39) + "-b" + got := replacementNodePoolName(long) + if len(got) > 40 { + t.Errorf("replacementNodePoolName(%q) = %q, %d characters; GKE allows 40", long, got, len(got)) + } + if got == long { + t.Errorf("replacement pool name %q collides with the original", got) + } +} + +func TestDeleteNodePoolCommand(t *testing.T) { + cfg := &Config{ProjectID: "my-project", ClusterName: "substrate-poc", ClusterLocation: "us-west1-c"} + got := deleteNodePoolCommand(cfg, &containerpb.NodePool{Name: "substrate-node-pool"}) + want := "gcloud container node-pools delete substrate-node-pool --cluster=substrate-poc --project=my-project --location=us-west1-c" + if got != want { + t.Errorf("got %q\nwant %q", got, want) + } +} diff --git a/tools/setup-gcp/dashboards/ate-e2e-latency-dashboard.json b/tools/setup-gcp/dashboards/ate-e2e-latency-dashboard.json index f964ce1ebc..4aba20dc1b 100644 --- a/tools/setup-gcp/dashboards/ate-e2e-latency-dashboard.json +++ b/tools/setup-gcp/dashboards/ate-e2e-latency-dashboard.json @@ -67,7 +67,7 @@ }, { "timeSeriesQuery": { - "prometheusQuery": "histogram_quantile(0.99, sum by (le) (rate({\"rpc.server.call.duration_bucket\", top_level_controller_name=\"ate-api-server\", \"rpc.method\"=\"ateapi.Control/ResumeActor\"}[5m])))", + "prometheusQuery": "histogram_quantile(0.99, sum by (le) (rate({\"rpc.server.call.duration_bucket\", top_level_controller_name=\"ate-api-server\", \"rpc.method\"=\"substrate.ateapi.v1.Control/ResumeActor\"}[5m])))", "unitOverride": "s" }, "plotType": "LINE",