From 1c24dc14f653991b2770464b041a4030d6fee6b1 Mon Sep 17 00:00:00 2001 From: Elijah Rodriguez Date: Fri, 25 Sep 2026 09:51:45 -0700 Subject: [PATCH] ateapi: add the ExternalVolume resource An ExternalVolume is an atespace-scoped CSI volume whose lifetime is independent of any actor. It is provisioned from a StorageClass or registers a volume that already exists, carries an immutable access mode, and is removed either manually or when the last actor referencing it is deleted, according to its delete trigger. Deleting the record also deletes the storage. This adds the resource, its Postgres table and store methods, the create/get/list/update/delete RPCs, and kubectl-ate commands. Nothing references a volume yet; actor references arrive separately. Co-Authored-By: Claude Fable 5.1 --- .../internal/apivalidation/external_volume.go | 124 + .../apivalidation/external_volume_test.go | 117 + .../apivalidation/zz_generated.validation.go | 962 ++++++- .../internal/controlapi/external_volume.go | 151 + .../controlapi/external_volume_test.go | 304 ++ .../functionaltest/external_volume_test.go | 271 ++ cmd/ateapi/internal/controlapi/service.go | 31 +- cmd/ateapi/internal/controlapi/workflow.go | 4 + .../controlapi/workflow_external_volume.go | 290 ++ cmd/ateapi/internal/defaults/defaults.go | 11 + cmd/ateapi/internal/defaults/defaults_test.go | 8 + .../internal/store/atepg/common_test.go | 2 +- .../internal/store/atepg/external_volume.go | 297 ++ .../migrations/000004_external_volumes.sql | 27 + cmd/ateapi/internal/store/atepg/pagetoken.go | 1 + .../internal/store/atepg/partition_test.go | 2 +- cmd/ateapi/internal/store/store.go | 20 + .../internal/store/storecontract/contract.go | 299 ++ .../internal/store/storetest/storetest.go | 13 + .../internal/cmd/external_volume.go | 268 ++ .../internal/cmd/external_volume_test.go | 138 + cmd/kubectl-ate/internal/printer/printer.go | 79 + .../internal/printer/printer_test.go | 110 + internal/resources/resourceref.go | 17 + pkg/proto/ateapipb/ateapi.pb.go | 2434 +++++++++++------ pkg/proto/ateapipb/ateapi.proto | 242 ++ pkg/proto/ateapipb/ateapi_grpc.pb.go | 200 ++ tools/apitool/internal/model/model.go | 1 + 28 files changed, 5607 insertions(+), 816 deletions(-) create mode 100644 cmd/ateapi/internal/apivalidation/external_volume.go create mode 100644 cmd/ateapi/internal/apivalidation/external_volume_test.go create mode 100644 cmd/ateapi/internal/controlapi/external_volume.go create mode 100644 cmd/ateapi/internal/controlapi/external_volume_test.go create mode 100644 cmd/ateapi/internal/controlapi/functionaltest/external_volume_test.go create mode 100644 cmd/ateapi/internal/controlapi/workflow_external_volume.go create mode 100644 cmd/ateapi/internal/store/atepg/external_volume.go create mode 100644 cmd/ateapi/internal/store/atepg/migrations/000004_external_volumes.sql create mode 100644 cmd/kubectl-ate/internal/cmd/external_volume.go create mode 100644 cmd/kubectl-ate/internal/cmd/external_volume_test.go diff --git a/cmd/ateapi/internal/apivalidation/external_volume.go b/cmd/ateapi/internal/apivalidation/external_volume.go new file mode 100644 index 0000000000..45662c3b68 --- /dev/null +++ b/cmd/ateapi/internal/apivalidation/external_volume.go @@ -0,0 +1,124 @@ +// 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 apivalidation + +import ( + "context" + "fmt" + + "github.com/agent-substrate/substrate/pkg/proto/ateapipb" + "k8s.io/apimachinery/pkg/api/operation" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/api/validate" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +func ValidateCreateExternalVolumeRequest(ctx context.Context, req *ateapipb.CreateExternalVolumeRequest) field.ErrorList { + op := operation.Operation{Type: operation.Create} + return Validate_CreateExternalVolumeRequest(ctx, op, nil, req, nil) +} + +func ValidateGetExternalVolumeRequest(ctx context.Context, req *ateapipb.GetExternalVolumeRequest) field.ErrorList { + op := operation.Operation{Type: operation.Create} + return Validate_GetExternalVolumeRequest(ctx, op, nil, req, nil) +} + +func ValidateListExternalVolumesRequest(ctx context.Context, req *ateapipb.ListExternalVolumesRequest) field.ErrorList { + op := operation.Operation{Type: operation.Create} + return Validate_ListExternalVolumesRequest(ctx, op, nil, req, nil) +} + +// The request is validated as a create; the result is validated as an update +// once the stored value is known, like UpdateTagRequest. +func ValidateUpdateExternalVolumeRequest(ctx context.Context, req *ateapipb.UpdateExternalVolumeRequest) field.ErrorList { + op := operation.Operation{Type: operation.Create} + return Validate_UpdateExternalVolumeRequest(ctx, op, nil, req, nil) +} + +func ValidateDeleteExternalVolumeRequest(ctx context.Context, req *ateapipb.DeleteExternalVolumeRequest) field.ErrorList { + op := operation.Operation{Type: operation.Create} + return Validate_DeleteExternalVolumeRequest(ctx, op, nil, req, nil) +} + +func ValidateExternalVolumeUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapipb.ExternalVolume) field.ErrorList { + op := operation.Operation{Type: operation.Update} + return Validate_ExternalVolume(ctx, op, fldPath, newVal, oldVal) +} + +func ValidateCustom_CreateExternalVolumeRequest(_ context.Context, _ operation.Operation, p *field.Path, req, _ *ateapipb.CreateExternalVolumeRequest) field.ErrorList { + volume := req.GetExternalVolume() + if volume == nil { + return nil + } + volumePath := p.Child("external_volume") + storageClassName, volumeID := volume.GetStorageClassName(), volume.GetVolumeId() + + var errs field.ErrorList + // TODO: accept READ_WRITE_MANY once concurrent holders are supported. + if mode := volume.GetAccessMode(); mode != ateapipb.AccessMode_ACCESS_MODE_UNSPECIFIED && mode != ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_ONCE { + errs = append(errs, field.NotSupported(volumePath.Child("access_mode"), mode.String(), []string{ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_ONCE.String()})) + } + switch { + case storageClassName == "" && volumeID == "": + errs = append(errs, field.Required(volumePath.Child("storage_class_name"), "one of storage_class_name or volume_id is required")) + case volumeID != "": + if volume.GetCapacity() != "" { + errs = append(errs, field.Forbidden(volumePath.Child("capacity"), "must not be set with volume_id")) + } + if volume.GetVolumeType() == "" && storageClassName == "" { + errs = append(errs, field.Required(volumePath.Child("volume_type"), "required with volume_id unless storage_class_name is set")) + } + default: + if volume.GetVolumeType() != "" { + errs = append(errs, field.Forbidden(volumePath.Child("volume_type"), "must not be set with storage_class_name; it is taken from the class's provisioner")) + } + if len(volume.GetVolumeContext()) > 0 { + errs = append(errs, field.Forbidden(volumePath.Child("volume_context"), "must not be set with storage_class_name; it is returned by the storage system")) + } + if volume.GetCapacity() == "" { + errs = append(errs, field.Required(volumePath.Child("capacity"), "required with storage_class_name")) + } + } + return errs +} + +func ValidateCustom_ExternalVolume_Capacity(_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *string) field.ErrorList { + if value == nil || *value == "" { + return nil + } + if _, err := resource.ParseQuantity(*value); err != nil { + return field.ErrorList{field.Invalid(fldPath, *value, fmt.Sprintf("must be a Kubernetes resource quantity: %v", err))} + } + return nil +} + +// This exists only because nested subfield tags are not supported yet. +func ValidateCustom_UpdateExternalVolumeRequest_ExternalVolume(ctx context.Context, op operation.Operation, fldPath *field.Path, volume, _ *ateapipb.ExternalVolume) field.ErrorList { + if volume == nil || volume.Metadata == nil { + return nil + } + errs := Validate_ResourceMetadata(ctx, op, fldPath.Child("metadata"), volume.Metadata, nil) + errs = append(errs, validate.RequiredValue(ctx, op, fldPath.Child("metadata", "atespace"), &volume.Metadata.Atespace, nil)...) + return errs +} + +// An ExternalVolume names its storage the same way an ActorVolumeStatus does. +func ValidateCustom_ExternalVolume_VolumeType(ctx context.Context, op operation.Operation, fldPath *field.Path, value, oldValue *string) field.ErrorList { + return ValidateCustom_ActorVolumeStatus_VolumeType(ctx, op, fldPath, value, oldValue) +} + +func ValidateCustom_ExternalVolume_VolumeId(ctx context.Context, op operation.Operation, fldPath *field.Path, value, oldValue *string) field.ErrorList { + return ValidateCustom_ActorVolumeStatus_StorageVolumeId(ctx, op, fldPath, value, oldValue) +} diff --git a/cmd/ateapi/internal/apivalidation/external_volume_test.go b/cmd/ateapi/internal/apivalidation/external_volume_test.go new file mode 100644 index 0000000000..6bdabc124f --- /dev/null +++ b/cmd/ateapi/internal/apivalidation/external_volume_test.go @@ -0,0 +1,117 @@ +// 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 apivalidation + +import ( + "context" + "testing" + + "github.com/agent-substrate/substrate/pkg/proto/ateapipb" + "github.com/google/go-cmp/cmp" + "k8s.io/apimachinery/pkg/api/operation" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +func TestValidateCustomCreateExternalVolumeRequest(t *testing.T) { + tests := []struct { + name string + volume *ateapipb.ExternalVolume + wantFields []string + }{ + { + name: "provisioning from a class", + volume: &ateapipb.ExternalVolume{StorageClassName: "standard", Capacity: "10Gi"}, + }, + { + name: "registering an existing volume", + volume: &ateapipb.ExternalVolume{VolumeId: "disk-1", VolumeType: "mock"}, + }, + { + name: "registering an existing volume under a named class", + volume: &ateapipb.ExternalVolume{VolumeId: "disk-1", StorageClassName: "standard"}, + }, + { + name: "neither a class nor an ID", + volume: &ateapipb.ExternalVolume{}, + wantFields: []string{"external_volume.storage_class_name"}, + }, + { + name: "a size for a volume that already exists", + volume: &ateapipb.ExternalVolume{VolumeId: "disk-1", VolumeType: "mock", Capacity: "10Gi"}, + wantFields: []string{"external_volume.capacity"}, + }, + { + name: "an ID with no driver to reach it through", + volume: &ateapipb.ExternalVolume{VolumeId: "disk-1"}, + wantFields: []string{"external_volume.volume_type"}, + }, + { + name: "a driver alongside the class that supplies one", + volume: &ateapipb.ExternalVolume{StorageClassName: "standard", VolumeType: "mock", Capacity: "10Gi"}, + wantFields: []string{"external_volume.volume_type"}, + }, + { + name: "driver metadata for a volume that does not exist yet", + volume: &ateapipb.ExternalVolume{StorageClassName: "standard", Capacity: "10Gi", VolumeContext: map[string]string{"fsType": "ext4"}}, + wantFields: []string{"external_volume.volume_context"}, + }, + { + name: "provisioning without a size", + volume: &ateapipb.ExternalVolume{StorageClassName: "standard"}, + wantFields: []string{"external_volume.capacity"}, + }, + { + name: "read write many is not supported yet", + volume: &ateapipb.ExternalVolume{StorageClassName: "standard", Capacity: "10Gi", AccessMode: ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_MANY}, + wantFields: []string{"external_volume.access_mode"}, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + req := &ateapipb.CreateExternalVolumeRequest{ExternalVolume: tc.volume} + errs := ValidateCustom_CreateExternalVolumeRequest(context.Background(), operation.Operation{Type: operation.Create}, nil, req, nil) + + var gotFields []string + for _, err := range errs { + gotFields = append(gotFields, err.Field) + } + if diff := cmp.Diff(tc.wantFields, gotFields); diff != "" { + t.Errorf("offending fields mismatch (-want +got):\n%s", diff) + } + }) + } +} + +func TestValidateCustomExternalVolumeCapacity(t *testing.T) { + tests := []struct { + value string + wantErr bool + }{ + {value: ""}, + {value: "10Gi"}, + {value: "1500m"}, + {value: "ten gigs", wantErr: true}, + {value: "10GiB", wantErr: true}, + } + for _, tc := range tests { + t.Run(tc.value, func(t *testing.T) { + value := tc.value + errs := ValidateCustom_ExternalVolume_Capacity(context.Background(), operation.Operation{Type: operation.Create}, field.NewPath("capacity"), &value, nil) + if gotErr := len(errs) > 0; gotErr != tc.wantErr { + t.Errorf("ValidateCustom_ExternalVolume_Capacity(%q) errors = %v, wantErr %v", tc.value, errs, tc.wantErr) + } + }) + } +} diff --git a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go index ec7348a780..1ce71bcaa1 100644 --- a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go +++ b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go @@ -631,6 +631,107 @@ func Validate_ActorMetadataItem( return errs } +// Validate_ActorRef validates an instance of ActorRef according +// to declarative validation rules in the API schema. +func Validate_ActorRef( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *ateapipb.ActorRef) (errs field.ErrorList) { + + { // field ateapipb.ActorRef.ActorUid + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.MaxLength(ctx, op, fldPath, obj, oldObj, 253); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ActorRef) *string { + return &oldObj.ActorUid + }) + errs = append(errs, fn(fldPath.Child("actor_uid"), &obj.ActorUid, oldVal, oldObj != nil)...) + } + + { // field ateapipb.ActorRef.ActorName + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.ShortName(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ActorRef) *string { + return &oldObj.ActorName + }) + errs = append(errs, fn(fldPath.Child("actor_name"), &obj.ActorName, oldVal, oldObj != nil)...) + } + + { // field ateapipb.ActorRef.Active + fn := func( + fldPath *field.Path, + obj, oldObj *bool, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ActorRef) *bool { + return &oldObj.Active + }) + errs = append(errs, fn(fldPath.Child("active"), &obj.Active, oldVal, oldObj != nil)...) + } + + return errs +} + // Validate_ActorStatus validates an instance of ActorStatus according // to declarative validation rules in the API schema. func Validate_ActorStatus( @@ -2404,6 +2505,51 @@ func Validate_CreateAtespaceRequest( return errs } +// Validate_CreateExternalVolumeRequest validates an instance of CreateExternalVolumeRequest according +// to declarative validation rules in the API schema. +func Validate_CreateExternalVolumeRequest( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *ateapipb.CreateExternalVolumeRequest) (errs field.ErrorList) { + + // custom validation + if e := ValidateCustom_CreateExternalVolumeRequest(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + + { // field ateapipb.CreateExternalVolumeRequest.ExternalVolume + fn := func( + fldPath *field.Path, + obj, oldObj *ateapipb.ExternalVolume, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if ateDeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // call the type's validation function + errs = append(errs, Validate_ExternalVolume(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.CreateExternalVolumeRequest) *ateapipb.ExternalVolume { + return oldObj.ExternalVolume + }) + errs = append(errs, fn(fldPath.Child("external_volume"), obj.ExternalVolume, oldVal, oldObj != nil)...) + } + + return errs +} + // Validate_CreateGlobalAccessPolicyRequest validates an instance of CreateGlobalAccessPolicyRequest according // to declarative validation rules in the API schema. func Validate_CreateGlobalAccessPolicyRequest( @@ -3145,6 +3291,91 @@ func Validate_DeleteAtespaceRequest( return errs } +// Validate_DeleteExternalVolumeRequest validates an instance of DeleteExternalVolumeRequest according +// to declarative validation rules in the API schema. +func Validate_DeleteExternalVolumeRequest( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *ateapipb.DeleteExternalVolumeRequest) (errs field.ErrorList) { + + { // field ateapipb.DeleteExternalVolumeRequest.ExternalVolume + fn := func( + fldPath *field.Path, + obj, oldObj *ateapipb.ObjectRef, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if ateDeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + 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 { + 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 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + }() + // call the type's validation function + errs = append(errs, Validate_ObjectRef(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.DeleteExternalVolumeRequest) *ateapipb.ObjectRef { + return oldObj.ExternalVolume + }) + errs = append(errs, fn(fldPath.Child("external_volume"), obj.ExternalVolume, oldVal, oldObj != nil)...) + } + + { // field ateapipb.DeleteExternalVolumeRequest.Options + fn := func( + fldPath *field.Path, + obj, oldObj *ateapipb.DeleteOptions, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if ateDeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // call the type's validation function + errs = append(errs, Validate_DeleteOptions(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.DeleteExternalVolumeRequest) *ateapipb.DeleteOptions { + return oldObj.Options + }) + errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) + } + + return errs +} + // Validate_DeleteOptions validates an instance of DeleteOptions according // to declarative validation rules in the API schema. func Validate_DeleteOptions( @@ -3635,60 +3866,498 @@ func Validate_EgressRule( if earlyReturn { return // do not proceed } - // call the type's validation function - errs = append(errs, Validate_HTTPSRule(ctx, op, fldPath, obj, oldObj)...) + // call the type's validation function + errs = append(errs, Validate_HTTPSRule(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.EgressRule) *ateapipb.HTTPSRule { + return oldObj.Https + }) + errs = append(errs, fn(fldPath.Child("https"), obj.Https, oldVal, oldObj != nil)...) + } + + { // field ateapipb.EgressRule.TlsPassthrough + fn := func( + fldPath *field.Path, + obj, oldObj *ateapipb.TLSPassthroughRule, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if ateDeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // call the type's validation function + errs = append(errs, Validate_TLSPassthroughRule(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.EgressRule) *ateapipb.TLSPassthroughRule { + return oldObj.TlsPassthrough + }) + errs = append(errs, fn(fldPath.Child("tls_passthrough"), obj.TlsPassthrough, oldVal, oldObj != nil)...) + } + + return errs +} + +// Validate_EnvVar validates an instance of EnvVar according +// 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) { + + { // field ateapipb.EnvVar.Name + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // custom validation + if e := ValidateCustom_EnvVar_Name(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + if e := validate.MaxLength(ctx, op, fldPath, obj, oldObj, 256); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.EnvVar) *string { + return &oldObj.Name + }) + errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) + } + + { // field ateapipb.EnvVar.Value + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.MaxLength(ctx, op, fldPath, obj, oldObj, 32768); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.EnvVar) *string { + return &oldObj.Value + }) + errs = append(errs, fn(fldPath.Child("value"), &obj.Value, oldVal, oldObj != nil)...) + } + + return errs +} + +// Validate_ExternalVolume validates an instance of ExternalVolume according +// to declarative validation rules in the API schema. +func Validate_ExternalVolume( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *ateapipb.ExternalVolume) (errs field.ErrorList) { + + { // field ateapipb.ExternalVolume.Metadata + fn := func( + fldPath *field.Path, + obj, oldObj *ateapipb.ResourceMetadata, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if ateDeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + 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 { + 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 { + 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 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + }() + // call the type's validation function + errs = append(errs, Validate_ResourceMetadata(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ExternalVolume) *ateapipb.ResourceMetadata { + return oldObj.Metadata + }) + errs = append(errs, fn(fldPath.Child("metadata"), obj.Metadata, oldVal, oldObj != nil)...) + } + + { // field ateapipb.ExternalVolume.DeleteTrigger + fn := func( + fldPath *field.Path, + obj, oldObj *ateapipb.DeleteTrigger, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.Maximum(ctx, op, fldPath, obj, oldObj, 2); len(e) != 0 { + errs = append(errs, e...) + } + if e := validate.Minimum(ctx, op, fldPath, obj, oldObj, 1); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ExternalVolume) *ateapipb.DeleteTrigger { + return &oldObj.DeleteTrigger + }) + errs = append(errs, fn(fldPath.Child("delete_trigger"), &obj.DeleteTrigger, oldVal, oldObj != nil)...) + } + + { // field ateapipb.ExternalVolume.StorageClassName + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.UpdateValue(ctx, op, fldPath, obj, oldObj, + func(a string, b string) bool { return a == b }, validate.NoUnset, validate.NoModify).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.LongName(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ExternalVolume) *string { + return &oldObj.StorageClassName + }) + errs = append(errs, fn(fldPath.Child("storage_class_name"), &obj.StorageClassName, oldVal, oldObj != nil)...) + } + + { // field ateapipb.ExternalVolume.VolumeId + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.UpdateValue(ctx, op, fldPath, obj, oldObj, + func(a string, b string) bool { return a == b }, validate.NoUnset, validate.NoModify).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // custom validation + if e := ValidateCustom_ExternalVolume_VolumeId(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + if e := validate.MaxLength(ctx, op, fldPath, obj, oldObj, 256); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ExternalVolume) *string { + return &oldObj.VolumeId + }) + errs = append(errs, fn(fldPath.Child("volume_id"), &obj.VolumeId, oldVal, oldObj != nil)...) + } + + { // field ateapipb.ExternalVolume.VolumeType + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.UpdateValue(ctx, op, fldPath, obj, oldObj, + func(a string, b string) bool { return a == b }, validate.NoUnset, validate.NoModify).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // custom validation + if e := ValidateCustom_ExternalVolume_VolumeType(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + if e := validate.MaxLength(ctx, op, fldPath, obj, oldObj, 253); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ExternalVolume) *string { + return &oldObj.VolumeType + }) + errs = append(errs, fn(fldPath.Child("volume_type"), &obj.VolumeType, oldVal, oldObj != nil)...) + } + + { // field ateapipb.ExternalVolume.VolumeContext + fn := func( + fldPath *field.Path, + obj, oldObj map[string]string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if ateDeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.MaxProperties(ctx, op, fldPath, obj, oldObj, 32).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.OptionalMap(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.EachMapKey(ctx, op, fldPath, obj, oldObj, + func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList { + return validate.MaxLength(ctx, op, fldPath, obj, oldObj, 128) + }); len(e) != 0 { + errs = append(errs, e...) + } + if e := validate.EachMapVal(ctx, op, fldPath, obj, oldObj, validate.DirectEqual, + func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList { + return validate.MaxLength(ctx, op, fldPath, obj, oldObj, 256) + }); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ExternalVolume) map[string]string { + return oldObj.VolumeContext + }) + errs = append(errs, fn(fldPath.Child("volume_context"), obj.VolumeContext, oldVal, oldObj != nil)...) + } + + { // field ateapipb.ExternalVolume.Status + fn := func( + fldPath *field.Path, + obj, oldObj *ateapipb.ExternalVolumeStatus, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if ateDeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // call the type's validation function + errs = append(errs, Validate_ExternalVolumeStatus(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ExternalVolume) *ateapipb.ExternalVolumeStatus { + return oldObj.Status + }) + errs = append(errs, fn(fldPath.Child("status"), obj.Status, oldVal, oldObj != nil)...) + } + + { // field ateapipb.ExternalVolume.Capacity + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.UpdateValue(ctx, op, fldPath, obj, oldObj, + func(a string, b string) bool { return a == b }, validate.NoUnset, validate.NoModify).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // custom validation + if e := ValidateCustom_ExternalVolume_Capacity(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + if e := validate.MaxLength(ctx, op, fldPath, obj, oldObj, 64); len(e) != 0 { + errs = append(errs, e...) + } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.EgressRule) *ateapipb.HTTPSRule { - return oldObj.Https + func(oldObj *ateapipb.ExternalVolume) *string { + return &oldObj.Capacity }) - errs = append(errs, fn(fldPath.Child("https"), obj.Https, oldVal, oldObj != nil)...) + errs = append(errs, fn(fldPath.Child("capacity"), &obj.Capacity, oldVal, oldObj != nil)...) } - { // field ateapipb.EgressRule.TlsPassthrough + { // field ateapipb.ExternalVolume.AccessMode fn := func( fldPath *field.Path, - obj, oldObj *ateapipb.TLSPassthroughRule, + obj, oldObj *ateapipb.AccessMode, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { - if ateDeepEqual(obj, oldObj) { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { return nil } } // call field-attached validations earlyReturn := false - if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.UpdateValue(ctx, op, fldPath, obj, oldObj, + func(a ateapipb.AccessMode, b ateapipb.AccessMode) bool { return a == b }, validate.NoUnset, validate.NoModify).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) earlyReturn = true } if earlyReturn { return // do not proceed } - // call the type's validation function - errs = append(errs, Validate_TLSPassthroughRule(ctx, op, fldPath, obj, oldObj)...) + if e := validate.Maximum(ctx, op, fldPath, obj, oldObj, 2); len(e) != 0 { + errs = append(errs, e...) + } + if e := validate.Minimum(ctx, op, fldPath, obj, oldObj, 1); len(e) != 0 { + errs = append(errs, e...) + } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.EgressRule) *ateapipb.TLSPassthroughRule { - return oldObj.TlsPassthrough + func(oldObj *ateapipb.ExternalVolume) *ateapipb.AccessMode { + return &oldObj.AccessMode }) - errs = append(errs, fn(fldPath.Child("tls_passthrough"), obj.TlsPassthrough, oldVal, oldObj != nil)...) + errs = append(errs, fn(fldPath.Child("access_mode"), &obj.AccessMode, oldVal, oldObj != nil)...) } return errs } -// Validate_EnvVar validates an instance of EnvVar according +// Validate_ExternalVolumeStatus validates an instance of ExternalVolumeStatus according // to declarative validation rules in the API schema. -func Validate_EnvVar( +func Validate_ExternalVolumeStatus( ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *ateapipb.EnvVar) (errs field.ErrorList) { + obj, oldObj *ateapipb.ExternalVolumeStatus) (errs field.ErrorList) { - { // field ateapipb.EnvVar.Name + { // field ateapipb.ExternalVolumeStatus.State fn := func( fldPath *field.Path, - obj, oldObj *string, + obj, oldObj *ateapipb.ExternalVolumeState, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { @@ -3698,58 +4367,71 @@ func Validate_EnvVar( } // call field-attached validations earlyReturn := false - if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { - errs = append(errs, e...) + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { return // do not proceed } - // custom validation - if e := ValidateCustom_EnvVar_Name(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + if e := validate.Maximum(ctx, op, fldPath, obj, oldObj, 2); len(e) != 0 { errs = append(errs, e...) } - if e := validate.MaxLength(ctx, op, fldPath, obj, oldObj, 256); len(e) != 0 { + if e := validate.Minimum(ctx, op, fldPath, obj, oldObj, 1); len(e) != 0 { errs = append(errs, e...) } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.EnvVar) *string { - return &oldObj.Name + func(oldObj *ateapipb.ExternalVolumeStatus) *ateapipb.ExternalVolumeState { + return &oldObj.State }) - errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) + errs = append(errs, fn(fldPath.Child("state"), &obj.State, oldVal, oldObj != nil)...) } - { // field ateapipb.EnvVar.Value + { // field ateapipb.ExternalVolumeStatus.Refs fn := func( fldPath *field.Path, - obj, oldObj *string, + obj, oldObj []*ateapipb.ActorRef, oldValueCorrelated bool) (errs field.ErrorList) { // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update { - if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + if ateDeepEqual(obj, oldObj) { return nil } } // call field-attached validations earlyReturn := false - if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.PtrSliceNoNils[ateapipb.ActorRef](ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.MaxItems(ctx, op, fldPath, obj, oldObj, 256).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { return // do not proceed } - if e := validate.MaxLength(ctx, op, fldPath, obj, oldObj, 32768); len(e) != 0 { + // lists with map semantics require unique keys + if e := validate.PtrSliceUnique(ctx, op, fldPath, obj, oldObj, + func(a *ateapipb.ActorRef, b *ateapipb.ActorRef) bool { return a.ActorUid == b.ActorUid }); 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.ActorRef, b *ateapipb.ActorRef) bool { return a.ActorUid == b.ActorUid }, ateDeepEqual, Validate_ActorRef); len(e) != 0 { errs = append(errs, e...) } return } oldVal := safe.Field(oldObj, - func(oldObj *ateapipb.EnvVar) *string { - return &oldObj.Value + func(oldObj *ateapipb.ExternalVolumeStatus) []*ateapipb.ActorRef { + return oldObj.Refs }) - errs = append(errs, fn(fldPath.Child("value"), &obj.Value, oldVal, oldObj != nil)...) + errs = append(errs, fn(fldPath.Child("refs"), obj.Refs, oldVal, oldObj != nil)...) } return errs @@ -4115,6 +4797,61 @@ func Validate_GetAtespaceRequest( return errs } +// Validate_GetExternalVolumeRequest validates an instance of GetExternalVolumeRequest according +// to declarative validation rules in the API schema. +func Validate_GetExternalVolumeRequest( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *ateapipb.GetExternalVolumeRequest) (errs field.ErrorList) { + + { // field ateapipb.GetExternalVolumeRequest.ExternalVolume + fn := func( + fldPath *field.Path, + obj, oldObj *ateapipb.ObjectRef, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if ateDeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + 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 { + 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 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + }() + // call the type's validation function + errs = append(errs, Validate_ObjectRef(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.GetExternalVolumeRequest) *ateapipb.ObjectRef { + return oldObj.ExternalVolume + }) + errs = append(errs, fn(fldPath.Child("external_volume"), obj.ExternalVolume, oldVal, oldObj != nil)...) + } + + return errs +} + // Validate_GetTagRequest validates an instance of GetTagRequest according // to declarative validation rules in the API schema. func Validate_GetTagRequest( @@ -5153,6 +5890,108 @@ func Validate_ListAtespacesRequest( return errs } +// Validate_ListExternalVolumesRequest validates an instance of ListExternalVolumesRequest according +// to declarative validation rules in the API schema. +func Validate_ListExternalVolumesRequest( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *ateapipb.ListExternalVolumesRequest) (errs field.ErrorList) { + + { // field ateapipb.ListExternalVolumesRequest.Atespace + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.ShortName(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ListExternalVolumesRequest) *string { + return &oldObj.Atespace + }) + errs = append(errs, fn(fldPath.Child("atespace"), &obj.Atespace, oldVal, oldObj != nil)...) + } + + { // field ateapipb.ListExternalVolumesRequest.PageSize + fn := func( + fldPath *field.Path, + obj, oldObj *int32, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.Minimum(ctx, op, fldPath, obj, oldObj, 1); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ListExternalVolumesRequest) *int32 { + return &oldObj.PageSize + }) + errs = append(errs, fn(fldPath.Child("page_size"), &obj.PageSize, oldVal, oldObj != nil)...) + } + + { // field ateapipb.ListExternalVolumesRequest.PageToken + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.MaxLength(ctx, op, fldPath, obj, oldObj, 256); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ListExternalVolumesRequest) *string { + return &oldObj.PageToken + }) + errs = append(errs, fn(fldPath.Child("page_token"), &obj.PageToken, oldVal, oldObj != nil)...) + } + + return errs +} + // Validate_ListTagsRequest validates an instance of ListTagsRequest according // to declarative validation rules in the API schema. func Validate_ListTagsRequest( @@ -8213,6 +9052,59 @@ func Validate_UpdateAtespaceAccessPolicyRequest( return errs } +// Validate_UpdateExternalVolumeRequest validates an instance of UpdateExternalVolumeRequest according +// to declarative validation rules in the API schema. +func Validate_UpdateExternalVolumeRequest( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *ateapipb.UpdateExternalVolumeRequest) (errs field.ErrorList) { + + { // field ateapipb.UpdateExternalVolumeRequest.ExternalVolume + fn := func( + fldPath *field.Path, + obj, oldObj *ateapipb.ExternalVolume, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if ateDeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // custom validation + if e := ValidateCustom_UpdateExternalVolumeRequest_ExternalVolume(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + func() { // cohort = "metadata" + earlyReturn := false + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "metadata", + func(o *ateapipb.ExternalVolume) *ateapipb.ResourceMetadata { return o.Metadata }, ateDeepEqual, validate.RequiredPointer).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + }() + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.UpdateExternalVolumeRequest) *ateapipb.ExternalVolume { + return oldObj.ExternalVolume + }) + errs = append(errs, fn(fldPath.Child("external_volume"), obj.ExternalVolume, oldVal, oldObj != nil)...) + } + + return errs +} + // Validate_UpdateGlobalAccessPolicyRequest validates an instance of UpdateGlobalAccessPolicyRequest according // to declarative validation rules in the API schema. func Validate_UpdateGlobalAccessPolicyRequest( diff --git a/cmd/ateapi/internal/controlapi/external_volume.go b/cmd/ateapi/internal/controlapi/external_volume.go new file mode 100644 index 0000000000..65d11053bd --- /dev/null +++ b/cmd/ateapi/internal/controlapi/external_volume.go @@ -0,0 +1,151 @@ +// 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 controlapi + +import ( + "context" + "errors" + "fmt" + + "github.com/agent-substrate/substrate/cmd/ateapi/internal/apivalidation" + "github.com/agent-substrate/substrate/cmd/ateapi/internal/defaults" + "github.com/agent-substrate/substrate/cmd/ateapi/internal/store" + "github.com/agent-substrate/substrate/internal/apierror" + "github.com/agent-substrate/substrate/internal/resources" + "github.com/agent-substrate/substrate/pkg/proto/ateapipb" + "google.golang.org/protobuf/proto" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +func (s *RPCService) CreateExternalVolume(ctx context.Context, req *ateapipb.CreateExternalVolumeRequest) (*ateapipb.ExternalVolume, error) { + inVolume := req.ExternalVolume + if inVolume != nil { + scrubResourceMetadataForCreate(inVolume.Metadata) + inVolume.Status = nil + defaults.Apply(inVolume) + } + if errs := apivalidation.ValidateCreateExternalVolumeRequest(ctx, req); len(errs) > 0 { + return nil, resources.ToAPIError(errs) + } + return s.externalVolumeWorkflow.CreateExternalVolume(ctx, inVolume) +} + +func (s *ServiceImpl) CreateExternalVolume(ctx context.Context, volume *ateapipb.ExternalVolume) (*ateapipb.ExternalVolume, error) { + return s.store.CreateExternalVolume(ctx, volume) +} + +func (s *RPCService) GetExternalVolume(ctx context.Context, req *ateapipb.GetExternalVolumeRequest) (*ateapipb.ExternalVolume, error) { + if errs := apivalidation.ValidateGetExternalVolumeRequest(ctx, req); len(errs) > 0 { + return nil, resources.ToAPIError(errs) + } + volumeRef := resources.ExternalVolumeRefFromObjectRef(req.GetExternalVolume()) + volume, err := s.impl.GetExternalVolume(ctx, volumeRef) + if err != nil { + if errors.Is(err, store.ErrNotFound) { + return nil, apierror.NotFound("ExternalVolume %s not found", volumeRef) + } + return nil, fmt.Errorf("while getting external volume: %w", err) + } + return volume, nil +} + +func (s *ServiceImpl) GetExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef) (*ateapipb.ExternalVolume, error) { + return s.store.GetExternalVolume(ctx, volumeRef) +} + +func (s *RPCService) ListExternalVolumes(ctx context.Context, req *ateapipb.ListExternalVolumesRequest) (*ateapipb.ListExternalVolumesResponse, error) { + if errs := apivalidation.ValidateListExternalVolumesRequest(ctx, req); len(errs) > 0 { + return nil, resources.ToAPIError(errs) + } + page, err := s.impl.ListExternalVolumes(ctx, req.GetAtespace(), store.ListOptions{PageSize: effectivePageSize(req.GetPageSize()), PageToken: req.GetPageToken()}) + if err != nil { + return nil, mapListError(fmt.Errorf("while listing external volumes: %w", err)) + } + return &ateapipb.ListExternalVolumesResponse{ExternalVolumes: page.Items, NextPageToken: page.NextPageToken}, nil +} + +func (s *ServiceImpl) ListExternalVolumes(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapipb.ExternalVolume], error) { + return s.store.ListExternalVolumes(ctx, atespace, opts) +} + +var errExternalVolumePending = errors.New("external volume is still being created") + +func (s *RPCService) UpdateExternalVolume(ctx context.Context, req *ateapipb.UpdateExternalVolumeRequest) (*ateapipb.ExternalVolume, error) { + inVolume := req.ExternalVolume + if inVolume != nil { + scrubResourceMetadataForUpdate(inVolume.Metadata) + inVolume.Status = nil + } + if errs := apivalidation.ValidateUpdateExternalVolumeRequest(ctx, req); len(errs) > 0 { + return nil, resources.ToAPIError(errs) + } + in := req.GetExternalVolume() + volumeRef := resources.ExternalVolumeRefFromExternalVolume(in) + + stored, err := s.impl.UpdateExternalVolume(ctx, volumeRef, store.PreconditionFrom(in), func(toUpdate *ateapipb.ExternalVolume) error { + if toUpdate.GetStatus().GetState() != ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY { + return errExternalVolumePending + } + metadata, volumeStatus := toUpdate.GetMetadata(), toUpdate.GetStatus() + proto.Reset(toUpdate) + proto.Merge(toUpdate, in) + toUpdate.Metadata, toUpdate.Status = metadata, volumeStatus + defaults.Apply(toUpdate) + return nil + }) + if err != nil { + if errors.Is(err, errExternalVolumePending) { + return nil, apierror.FailedPrecondition("ExternalVolume %s is still being created", volumeRef) + } + if errors.Is(err, store.ErrImmutableField) || errors.Is(err, store.ErrPreconditionRequired) { + return nil, apierror.InvalidArgument("while updating external volume %s: %v", volumeRef, err) + } + if errors.Is(err, store.ErrVersionConflict) { + return nil, apierror.Aborted("concurrent update conflict, please retry") + } + if errors.Is(err, store.ErrUIDConflict) { + return nil, apierror.Aborted("ExternalVolume %s not found with uid %s", volumeRef, in.GetMetadata().GetUid()) + } + if errors.Is(err, store.ErrNotFound) { + return nil, apierror.NotFound("ExternalVolume %s not found", volumeRef) + } + return nil, fmt.Errorf("while updating external volume: %w", err) + } + return stored, nil +} + +func (s *ServiceImpl) UpdateExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef, precondition store.Precondition, mutate func(toUpdate *ateapipb.ExternalVolume) error) (*ateapipb.ExternalVolume, error) { + return s.store.UpdateExternalVolume(ctx, volumeRef, precondition, func(toUpdate *ateapipb.ExternalVolume) error { + oldVal := proto.CloneOf(toUpdate) + if err := mutate(toUpdate); err != nil { + return err + } + if errs := apivalidation.ValidateExternalVolumeUpdate(ctx, field.NewPath("external_volume"), toUpdate, oldVal); len(errs) > 0 { + return resources.ToAPIError(errs) + } + return nil + }) +} + +func (s *RPCService) DeleteExternalVolume(ctx context.Context, req *ateapipb.DeleteExternalVolumeRequest) (*ateapipb.ExternalVolume, error) { + if errs := apivalidation.ValidateDeleteExternalVolumeRequest(ctx, req); len(errs) > 0 { + return nil, resources.ToAPIError(errs) + } + return s.externalVolumeWorkflow.DeleteExternalVolume(ctx, resources.ExternalVolumeRefFromObjectRef(req.GetExternalVolume()), toDeletePreconditions(req.GetOptions())) +} + +func (s *ServiceImpl) DeleteExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef, precondition store.DeletePreconditions) (*ateapipb.ExternalVolume, error) { + return s.store.DeleteExternalVolume(ctx, volumeRef, precondition) +} diff --git a/cmd/ateapi/internal/controlapi/external_volume_test.go b/cmd/ateapi/internal/controlapi/external_volume_test.go new file mode 100644 index 0000000000..d521e8a584 --- /dev/null +++ b/cmd/ateapi/internal/controlapi/external_volume_test.go @@ -0,0 +1,304 @@ +// 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 controlapi + +import ( + "context" + "testing" + + "github.com/agent-substrate/substrate/cmd/ateapi/internal/store" + "github.com/agent-substrate/substrate/internal/apierror" + "github.com/agent-substrate/substrate/internal/resources" + "github.com/agent-substrate/substrate/internal/volume" + "github.com/agent-substrate/substrate/pkg/proto/ateapipb" + "github.com/google/go-cmp/cmp" + "google.golang.org/grpc/codes" + storagev1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// recordingVolumePlugin answers CreateVolume with a handle derived from the +// name it was asked for, and records both calls so a test can assert on what +// the workflow asked the storage system to do. +type recordingVolumePlugin struct { + volume.VolumePluginControlPlane + + createErr error + deleteErr error + createdIDs []string + deletedIDs []string +} + +func (p *recordingVolumePlugin) CreateVolume(_ context.Context, req volume.CreateVolumeRequest) (volume.CreateVolumeResponse, error) { + if p.createErr != nil { + return volume.CreateVolumeResponse{}, p.createErr + } + p.createdIDs = append(p.createdIDs, req.Name) + return volume.CreateVolumeResponse{VolumeID: "disk/" + req.Name, VolumeContext: map[string]string{"capacity": req.Capacity}}, nil +} + +func (p *recordingVolumePlugin) DeleteVolume(_ context.Context, volumeID string) error { + if p.deleteErr != nil { + return p.deleteErr + } + p.deletedIDs = append(p.deletedIDs, volumeID) + return nil +} + +// newTestExternalVolumeWorkflow builds an ExternalVolumeWorkflow over a real +// store, with one StorageClass named "standard" whose reclaim policy the caller +// chooses, and a plugin registered under that class's provisioner. +func newTestExternalVolumeWorkflow(t *testing.T) (*ExternalVolumeWorkflow, store.Interface, *recordingVolumePlugin) { + t.Helper() + persistence := newTestPersistence(t) + plugin := &recordingVolumePlugin{} + scLister := &fakeStorageClassLister{ + storageClasses: map[string]*storagev1.StorageClass{ + "standard": { + ObjectMeta: metav1.ObjectMeta{Name: "standard"}, + Provisioner: "mock", + Parameters: map[string]string{"type": "pd-ssd"}, + }, + }, + } + registry := &mockPluginRegistry{plugins: map[string]volume.VolumePluginControlPlane{"mock": plugin}} + return NewExternalVolumeWorkflow(persistence, scLister, registry), persistence, plugin +} + +// TestCreateExternalVolume_Provisioned checks the whole create: the record is +// reserved, the disk is asked for under an ID derived from the record's UID, +// and the handle the driver returned is stamped back. +func TestCreateExternalVolume_Provisioned(t *testing.T) { + ctx := context.Background() + w, _, plugin := newTestExternalVolumeWorkflow(t) + + got, err := w.CreateExternalVolume(ctx, &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "shared"}, + StorageClassName: "standard", + Capacity: "10Gi", + }) + if err != nil { + t.Fatalf("CreateExternalVolume: %v", err) + } + + wantID := externalVolumeID(got.GetMetadata().GetUid()) + if diff := cmp.Diff([]string{wantID}, plugin.createdIDs); diff != "" { + t.Errorf("provisioned volume names mismatch (-want +got):\n%s", diff) + } + if want := "disk/" + wantID; got.GetVolumeId() != want { + t.Errorf("volume_id = %q, want the handle the driver returned %q", got.GetVolumeId(), want) + } + if got.GetVolumeType() != "mock" { + t.Errorf("volume_type = %q, want the class's provisioner %q", got.GetVolumeType(), "mock") + } + if want := ateapipb.DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR; got.GetDeleteTrigger() != want { + t.Errorf("delete_trigger = %v, want %v", got.GetDeleteTrigger(), want) + } + if want := ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY; got.GetStatus().GetState() != want { + t.Errorf("state = %v, want %v", got.GetStatus().GetState(), want) + } + if got.GetVolumeContext()["capacity"] != "10Gi" { + t.Errorf("volume_context = %v, want the context the driver returned for a 10Gi disk", got.GetVolumeContext()) + } +} + +func TestCreateExternalVolume_Registered(t *testing.T) { + ctx := context.Background() + w, _, plugin := newTestExternalVolumeWorkflow(t) + + got, err := w.CreateExternalVolume(ctx, &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "adopted"}, + VolumeId: "projects/p/zones/z/disks/preexisting", + VolumeType: "mock", + VolumeContext: map[string]string{"fsType": "ext4"}, + }) + if err != nil { + t.Fatalf("CreateExternalVolume: %v", err) + } + + if len(plugin.createdIDs) != 0 { + t.Errorf("provisioned %v, want nothing provisioned for a volume that already exists", plugin.createdIDs) + } + if want := "projects/p/zones/z/disks/preexisting"; got.GetVolumeId() != want { + t.Errorf("volume_id = %q, want the supplied %q", got.GetVolumeId(), want) + } + if want := ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY; got.GetStatus().GetState() != want { + t.Errorf("state = %v, want %v", got.GetStatus().GetState(), want) + } + if want := ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL; got.GetDeleteTrigger() != want { + t.Errorf("delete_trigger = %v, want %v", got.GetDeleteTrigger(), want) + } +} + +func TestCreateExternalVolume_Errors(t *testing.T) { + ctx := context.Background() + + tests := []struct { + name string + volume *ateapipb.ExternalVolume + wantCode codes.Code + }{ + { + name: "unknown storage class", + volume: &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "vol"}, + StorageClassName: "nonexistent", + Capacity: "1Gi", + }, + wantCode: codes.FailedPrecondition, + }, + { + name: "unknown atespace", + volume: &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: "no-such-space", Name: "vol"}, + StorageClassName: "standard", + Capacity: "1Gi", + }, + wantCode: codes.FailedPrecondition, + }, + { + name: "no source at all", + volume: &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "vol"}, + }, + wantCode: codes.InvalidArgument, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + w, _, _ := newTestExternalVolumeWorkflow(t) + _, err := w.CreateExternalVolume(ctx, tc.volume) + if got := apierror.Code(err); got != tc.wantCode { + t.Fatalf("CreateExternalVolume error = %v (code %v), want code %v", err, got, tc.wantCode) + } + }) + } +} + +func TestCreateExternalVolume_ReusedName(t *testing.T) { + ctx := context.Background() + w, _, plugin := newTestExternalVolumeWorkflow(t) + + toCreate := func() *ateapipb.ExternalVolume { + return &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "shared"}, + StorageClassName: "standard", + Capacity: "10Gi", + } + } + if _, err := w.CreateExternalVolume(ctx, toCreate()); err != nil { + t.Fatalf("CreateExternalVolume: %v", err) + } + _, err := w.CreateExternalVolume(ctx, toCreate()) + if got := apierror.Code(err); got != codes.AlreadyExists { + t.Fatalf("second CreateExternalVolume error = %v (code %v), want code %v", err, got, codes.AlreadyExists) + } + if len(plugin.createdIDs) != 1 { + t.Errorf("provisioned %v, want only the first create to reach the storage system", plugin.createdIDs) + } +} + +func TestDeleteExternalVolume(t *testing.T) { + ctx := context.Background() + w, persistence, plugin := newTestExternalVolumeWorkflow(t) + created, err := w.CreateExternalVolume(ctx, &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "shared"}, + StorageClassName: "standard", + Capacity: "10Gi", + }) + if err != nil { + t.Fatalf("CreateExternalVolume: %v", err) + } + volumeRef := resources.ExternalVolumeRefFromExternalVolume(created) + + if _, err := w.DeleteExternalVolume(ctx, volumeRef, store.DeletePreconditions{Version: created.GetMetadata().GetVersion() + 1}); apierror.Code(err) != codes.Aborted { + t.Fatalf("DeleteExternalVolume with a stale version error = %v, want code %v", err, codes.Aborted) + } + if len(plugin.deletedIDs) != 0 { + t.Fatalf("collected %v before the precondition check passed", plugin.deletedIDs) + } + + if _, err := w.DeleteExternalVolume(ctx, volumeRef, store.DeletePreconditions{UID: created.GetMetadata().GetUid()}); err != nil { + t.Fatalf("DeleteExternalVolume: %v", err) + } + if diff := cmp.Diff([]string{created.GetVolumeId()}, plugin.deletedIDs); diff != "" { + t.Errorf("collected disks mismatch (-want +got):\n%s", diff) + } + if _, err := persistence.GetExternalVolume(ctx, volumeRef); err == nil { + t.Errorf("GetExternalVolume after delete succeeded, want the row gone") + } +} + +func TestDeleteExternalVolume_StillReferenced(t *testing.T) { + ctx := context.Background() + w, persistence, plugin := newTestExternalVolumeWorkflow(t) + + created, err := w.CreateExternalVolume(ctx, &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "shared"}, + StorageClassName: "standard", + Capacity: "10Gi", + }) + if err != nil { + t.Fatalf("CreateExternalVolume: %v", err) + } + volumeRef := resources.ExternalVolumeRefFromExternalVolume(created) + if _, err := persistence.UpdateExternalVolume(ctx, volumeRef, store.PreconditionFrom(created), func(toUpdate *ateapipb.ExternalVolume) error { + toUpdate.Status.Refs = []*ateapipb.ActorRef{{ActorUid: "uid-1", ActorName: "producer"}} + return nil + }); err != nil { + t.Fatalf("UpdateExternalVolume: %v", err) + } + + _, err = w.DeleteExternalVolume(ctx, volumeRef, store.DeletePreconditions{}) + if got := apierror.Code(err); got != codes.FailedPrecondition { + t.Fatalf("DeleteExternalVolume error = %v (code %v), want code %v", err, got, codes.FailedPrecondition) + } + if len(plugin.deletedIDs) != 0 { + t.Errorf("collected %v, want the disk left alone while an actor holds it", plugin.deletedIDs) + } +} + +func TestDeleteExternalVolume_Pending(t *testing.T) { + ctx := context.Background() + w, persistence, plugin := newTestExternalVolumeWorkflow(t) + + pending, err := persistence.CreateExternalVolume(ctx, &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "stranded"}, + StorageClassName: "standard", + VolumeType: "mock", + Status: &ateapipb.ExternalVolumeStatus{State: ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_PENDING}, + }) + if err != nil { + t.Fatalf("CreateExternalVolume: %v", err) + } + + if _, err := w.DeleteExternalVolume(ctx, resources.ExternalVolumeRefFromExternalVolume(pending), store.DeletePreconditions{}); err != nil { + t.Fatalf("DeleteExternalVolume: %v", err) + } + want := []string{externalVolumeID(pending.GetMetadata().GetUid())} + if diff := cmp.Diff(want, plugin.deletedIDs); diff != "" { + t.Errorf("collected disks mismatch (-want +got):\n%s", diff) + } +} + +func TestDeleteExternalVolume_NotFound(t *testing.T) { + ctx := context.Background() + w, _, _ := newTestExternalVolumeWorkflow(t) + + _, err := w.DeleteExternalVolume(ctx, resources.ExternalVolumeRef{Atespace: "team-a", Name: "nope"}, store.DeletePreconditions{}) + if got := apierror.Code(err); got != codes.NotFound { + t.Fatalf("DeleteExternalVolume error = %v (code %v), want code %v", err, got, codes.NotFound) + } +} diff --git a/cmd/ateapi/internal/controlapi/functionaltest/external_volume_test.go b/cmd/ateapi/internal/controlapi/functionaltest/external_volume_test.go new file mode 100644 index 0000000000..27e30a6fe6 --- /dev/null +++ b/cmd/ateapi/internal/controlapi/functionaltest/external_volume_test.go @@ -0,0 +1,271 @@ +// 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 functionaltest + +import ( + "context" + "fmt" + "sync" + "testing" + + "github.com/agent-substrate/substrate/internal/volume" + "github.com/agent-substrate/substrate/pkg/proto/ateapipb" + "github.com/google/go-cmp/cmp" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/testing/protocmp" +) + +// sharedVolumePlugin records every storage operation the control plane makes. +type sharedVolumePlugin struct { + volume.VolumePluginControlPlane + + mu sync.Mutex + created []string + deleted []string + attached []string + detached []string +} + +func (p *sharedVolumePlugin) CreateVolume(_ context.Context, req volume.CreateVolumeRequest) (volume.CreateVolumeResponse, error) { + p.mu.Lock() + defer p.mu.Unlock() + p.created = append(p.created, req.Name) + return volume.CreateVolumeResponse{VolumeID: "disk/" + req.Name, VolumeContext: req.Parameters}, nil +} + +func (p *sharedVolumePlugin) DeleteVolume(_ context.Context, volumeID string) error { + p.mu.Lock() + defer p.mu.Unlock() + p.deleted = append(p.deleted, volumeID) + return nil +} + +func (p *sharedVolumePlugin) AttachVolume(_ context.Context, req volume.AttachVolumeRequest) (volume.AttachVolumeResponse, error) { + p.mu.Lock() + defer p.mu.Unlock() + p.attached = append(p.attached, req.VolumeID+"@"+req.Node) + return volume.AttachVolumeResponse{}, nil +} + +func (p *sharedVolumePlugin) DetachVolume(_ context.Context, volumeID, node string) error { + p.mu.Lock() + defer p.mu.Unlock() + p.detached = append(p.detached, volumeID+"@"+node) + return nil +} + +func (p *sharedVolumePlugin) snapshot() (created, deleted, attached, detached []string) { + p.mu.Lock() + defer p.mu.Unlock() + return append([]string(nil), p.created...), append([]string(nil), p.deleted...), + append([]string(nil), p.attached...), append([]string(nil), p.detached...) +} + +func setupExternalVolumeTest(t *testing.T, ns string) (*testContext, *sharedVolumePlugin) { + t.Helper() + plugin := &sharedVolumePlugin{} + tc := setupTestWithVolumePlugins(t, ns, map[string]volume.VolumePluginControlPlane{ + "substrate.io/mock": plugin, + }) + return tc, plugin +} + +func createExternalVolume(t *testing.T, tc *testContext, name string, trigger ateapipb.DeleteTrigger) *ateapipb.ExternalVolume { + t.Helper() + created, err := tc.client.CreateExternalVolume(context.Background(), &ateapipb.CreateExternalVolumeRequest{ + ExternalVolume: &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, + StorageClassName: "standard", + Capacity: "10Gi", + DeleteTrigger: trigger, + }, + }) + if err != nil { + t.Fatalf("CreateExternalVolume(%s) failed: %v", name, err) + } + if got := created.GetStatus().GetState(); got != ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY { + t.Fatalf("CreateExternalVolume(%s) left the volume in %v, want READY", name, got) + } + return created +} + +func getExternalVolume(t *testing.T, tc *testContext, name string) *ateapipb.ExternalVolume { + t.Helper() + stored, err := tc.client.GetExternalVolume(context.Background(), &ateapipb.GetExternalVolumeRequest{ + ExternalVolume: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + }) + if err != nil { + t.Fatalf("GetExternalVolume(%s) failed: %v", name, err) + } + return stored +} + +func TestCreateExternalVolume_Provisioned(t *testing.T) { + ns := namespaceForTest("ns-extvol-provisioned") + tc, plugin := setupExternalVolumeTest(t, ns) + defer tc.cleanup() + + created := createExternalVolume(t, tc, "shared", ateapipb.DeleteTrigger_DELETE_TRIGGER_UNSPECIFIED) + + wantDiskName := "substrate-" + created.GetMetadata().GetUid() + gotCreated, _, _, _ := plugin.snapshot() + if diff := cmp.Diff([]string{wantDiskName}, gotCreated); diff != "" { + t.Errorf("provisioned disks mismatch (-want +got):\n%s", diff) + } + if got, want := created.GetVolumeId(), "disk/"+wantDiskName; got != want { + t.Errorf("volume_id = %q, want %q", got, want) + } + if got, want := created.GetVolumeType(), "substrate.io/mock"; got != want { + t.Errorf("volume_type = %q, want %q", got, want) + } + if got := created.GetDeleteTrigger(); got != ateapipb.DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR { + t.Errorf("delete_trigger = %v, want LAST_ACTOR", got) + } + if got := created.GetAccessMode(); got != ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_ONCE { + t.Errorf("access_mode = %v, want READ_WRITE_ONCE", got) + } + + if diff := cmp.Diff(created, getExternalVolume(t, tc, "shared"), protocmp.Transform()); diff != "" { + t.Errorf("GetExternalVolume mismatch (-want +got):\n%s", diff) + } + listed, err := tc.client.ListExternalVolumes(context.Background(), &ateapipb.ListExternalVolumesRequest{Atespace: testAtespace}) + if err != nil { + t.Fatalf("ListExternalVolumes failed: %v", err) + } + if diff := cmp.Diff([]*ateapipb.ExternalVolume{created}, listed.GetExternalVolumes(), protocmp.Transform()); diff != "" { + t.Errorf("ListExternalVolumes mismatch (-want +got):\n%s", diff) + } +} + +func TestCreateExternalVolume_Registered(t *testing.T) { + ns := namespaceForTest("ns-extvol-registered") + tc, plugin := setupExternalVolumeTest(t, ns) + defer tc.cleanup() + + created, err := tc.client.CreateExternalVolume(context.Background(), &ateapipb.CreateExternalVolumeRequest{ + ExternalVolume: &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "adopted"}, + VolumeId: "disk/made-elsewhere", + VolumeType: "substrate.io/mock", + }, + }) + if err != nil { + t.Fatalf("CreateExternalVolume failed: %v", err) + } + if got := created.GetStatus().GetState(); got != ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY { + t.Errorf("state = %v, want READY", got) + } + if got := created.GetDeleteTrigger(); got != ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL { + t.Errorf("delete_trigger = %v, want MANUAL", got) + } + if gotCreated, _, _, _ := plugin.snapshot(); len(gotCreated) != 0 { + t.Errorf("provisioned %v, want nothing provisioned for a registered volume", gotCreated) + } +} + +func TestCreateExternalVolume_Rejected(t *testing.T) { + ns := namespaceForTest("ns-extvol-rejected") + tc, _ := setupExternalVolumeTest(t, ns) + defer tc.cleanup() + + first := createExternalVolume(t, tc, "shared", ateapipb.DeleteTrigger_DELETE_TRIGGER_UNSPECIFIED) + + _, err := tc.client.CreateExternalVolume(context.Background(), &ateapipb.CreateExternalVolumeRequest{ + ExternalVolume: &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "shared"}, + StorageClassName: "fast", + Capacity: "20Gi", + }, + }) + assertGrpcError(t, err, codes.AlreadyExists, + fmt.Sprintf("ExternalVolume %s/shared already exists; delete it and create it again to retry", testAtespace)) + if diff := cmp.Diff(first, getExternalVolume(t, tc, "shared"), protocmp.Transform()); diff != "" { + t.Errorf("the rejected create changed the stored volume (-want +got):\n%s", diff) + } + + _, err = tc.client.CreateExternalVolume(context.Background(), &ateapipb.CreateExternalVolumeRequest{ + ExternalVolume: &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "many"}, + StorageClassName: "standard", + Capacity: "10Gi", + AccessMode: ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_MANY, + }, + }) + assertGrpcErrorRegex(t, err, codes.InvalidArgument, "access_mode") +} + +func TestUpdateExternalVolume(t *testing.T) { + ns := namespaceForTest("ns-extvol-update") + tc, _ := setupExternalVolumeTest(t, ns) + defer tc.cleanup() + + created := createExternalVolume(t, tc, "shared", ateapipb.DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR) + toUpdate := func(in *ateapipb.ExternalVolume) *ateapipb.ExternalVolume { + return &ateapipb.ExternalVolume{ + Metadata: in.GetMetadata(), + DeleteTrigger: in.GetDeleteTrigger(), + AccessMode: in.GetAccessMode(), + StorageClassName: in.GetStorageClassName(), + Capacity: in.GetCapacity(), + VolumeId: in.GetVolumeId(), + VolumeType: in.GetVolumeType(), + VolumeContext: in.GetVolumeContext(), + } + } + + req := toUpdate(created) + req.DeleteTrigger = ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL + updated, err := tc.client.UpdateExternalVolume(context.Background(), &ateapipb.UpdateExternalVolumeRequest{ExternalVolume: req}) + if err != nil { + t.Fatalf("UpdateExternalVolume failed: %v", err) + } + if got := updated.GetDeleteTrigger(); got != ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL { + t.Errorf("delete_trigger = %v, want MANUAL", got) + } + + req = toUpdate(updated) + req.VolumeId = "disk/somewhere-else" + _, err = tc.client.UpdateExternalVolume(context.Background(), &ateapipb.UpdateExternalVolumeRequest{ExternalVolume: req}) + assertGrpcErrorRegex(t, err, codes.InvalidArgument, "volume_id") + + req = toUpdate(updated) + req.AccessMode = ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_MANY + _, err = tc.client.UpdateExternalVolume(context.Background(), &ateapipb.UpdateExternalVolumeRequest{ExternalVolume: req}) + assertGrpcErrorRegex(t, err, codes.InvalidArgument, "access_mode") +} + +func TestDeleteExternalVolume(t *testing.T) { + ns := namespaceForTest("ns-extvol-delete") + tc, plugin := setupExternalVolumeTest(t, ns) + defer tc.cleanup() + + created := createExternalVolume(t, tc, "shared", ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL) + ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "shared"} + + _, err := tc.client.DeleteExternalVolume(context.Background(), &ateapipb.DeleteExternalVolumeRequest{ + ExternalVolume: ref, + Options: &ateapipb.DeleteOptions{Version: created.GetMetadata().GetVersion() + 1}, + }) + assertGrpcError(t, err, codes.Aborted, "concurrent update conflict, please retry") + + if _, err := tc.client.DeleteExternalVolume(context.Background(), &ateapipb.DeleteExternalVolumeRequest{ExternalVolume: ref}); err != nil { + t.Fatalf("DeleteExternalVolume failed: %v", err) + } + if _, deleted, _, _ := plugin.snapshot(); !cmp.Equal([]string{created.GetVolumeId()}, deleted) { + t.Errorf("deleted disks = %v, want %v", deleted, []string{created.GetVolumeId()}) + } + _, err = tc.client.DeleteExternalVolume(context.Background(), &ateapipb.DeleteExternalVolumeRequest{ExternalVolume: ref}) + assertGrpcError(t, err, codes.NotFound, fmt.Sprintf("ExternalVolume %s/shared not found", testAtespace)) +} diff --git a/cmd/ateapi/internal/controlapi/service.go b/cmd/ateapi/internal/controlapi/service.go index f40caa3bb1..7b0b526768 100644 --- a/cmd/ateapi/internal/controlapi/service.go +++ b/cmd/ateapi/internal/controlapi/service.go @@ -38,18 +38,19 @@ import ( // ServiceImpl for business logic and invariants. type RPCService struct { ateapipb.UnimplementedControlServer - impl serviceStore - persistence serviceStore - workerCache *workercache.Cache - dialer *AteletDialer - sandboxConfigLister listersv1alpha1.SandboxConfigLister - csiDriverConfigLister listersv1alpha1.CSIDriverConfigLister - actorWorkflow *ActorWorkflow - workerWorkflow *WorkerWorkflow - instruments *Instruments - mu sync.RWMutex - volumePlugins map[string]volume.VolumePluginControlPlane - snapshotPlugin objectstoresnapshotv1.ControlProviderClient + impl serviceStore + persistence serviceStore + workerCache *workercache.Cache + dialer *AteletDialer + sandboxConfigLister listersv1alpha1.SandboxConfigLister + csiDriverConfigLister listersv1alpha1.CSIDriverConfigLister + actorWorkflow *ActorWorkflow + workerWorkflow *WorkerWorkflow + externalVolumeWorkflow *ExternalVolumeWorkflow + instruments *Instruments + mu sync.RWMutex + volumePlugins map[string]volume.VolumePluginControlPlane + snapshotPlugin objectstoresnapshotv1.ControlProviderClient actorJWTIssuer string actorIDJWTPool localjwtauthority.Pool @@ -105,6 +106,7 @@ func NewRPCService( } s.actorWorkflow = NewActorWorkflow(impl, workerCache, dialer, sandboxConfigLister, storageClassLister, instruments, egressGatewayAddress, s, snapshotPlugin) s.workerWorkflow = NewWorkerWorkflow(impl) + s.externalVolumeWorkflow = NewExternalVolumeWorkflow(impl, storageClassLister, s) return s } @@ -123,6 +125,11 @@ type serviceStore interface { 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) + CreateExternalVolume(ctx context.Context, volume *ateapipb.ExternalVolume) (*ateapipb.ExternalVolume, error) + GetExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef) (*ateapipb.ExternalVolume, error) + ListExternalVolumes(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapipb.ExternalVolume], error) + UpdateExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef, precondition store.Precondition, mutate func(toUpdate *ateapipb.ExternalVolume) error) (*ateapipb.ExternalVolume, error) + DeleteExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef, precondition store.DeletePreconditions) (*ateapipb.ExternalVolume, 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) diff --git a/cmd/ateapi/internal/controlapi/workflow.go b/cmd/ateapi/internal/controlapi/workflow.go index 552b97c7a0..d830f8804d 100644 --- a/cmd/ateapi/internal/controlapi/workflow.go +++ b/cmd/ateapi/internal/controlapi/workflow.go @@ -241,3 +241,7 @@ func (w *ActorWorkflow) acquireActorLease(ctx context.Context, actorRef resource func acquireTagLease(ctx context.Context, holder leaseHolder, tagRef resources.TagRef) (context.Context, *store.Lease, error) { return acquireLease(ctx, holder, "lease:tag:"+tagRef.Atespace+":"+tagRef.Name, "Tag") } + +func acquireExternalVolumeLease(ctx context.Context, holder leaseHolder, volumeRef resources.ExternalVolumeRef) (context.Context, *store.Lease, error) { + return acquireLease(ctx, holder, "lease:externalvolume:"+volumeRef.Atespace+":"+volumeRef.Name, "ExternalVolume") +} diff --git a/cmd/ateapi/internal/controlapi/workflow_external_volume.go b/cmd/ateapi/internal/controlapi/workflow_external_volume.go new file mode 100644 index 0000000000..35e7491d66 --- /dev/null +++ b/cmd/ateapi/internal/controlapi/workflow_external_volume.go @@ -0,0 +1,290 @@ +// 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 controlapi + +import ( + "context" + "errors" + "fmt" + "log/slog" + + "github.com/agent-substrate/substrate/cmd/ateapi/internal/store" + "github.com/agent-substrate/substrate/internal/apierror" + "github.com/agent-substrate/substrate/internal/resources" + "github.com/agent-substrate/substrate/internal/volume" + "github.com/agent-substrate/substrate/pkg/proto/ateapipb" + "google.golang.org/grpc/codes" + storagev1 "k8s.io/api/storage/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + storagev1listers "k8s.io/client-go/listers/storage/v1" +) + +// ExternalVolumeWorkflow handles the multi-step create and delete of an +// ExternalVolume, each of which spans a store write and a CSI call. +type ExternalVolumeWorkflow struct { + store externalVolumeWorkflowStore + storageClassLister storagev1listers.StorageClassLister + pluginRegistry VolumePluginRegistry +} + +// NewExternalVolumeWorkflow creates a new ExternalVolumeWorkflow. +func NewExternalVolumeWorkflow( + store externalVolumeWorkflowStore, + storageClassLister storagev1listers.StorageClassLister, + pluginRegistry VolumePluginRegistry, +) *ExternalVolumeWorkflow { + return &ExternalVolumeWorkflow{ + store: store, + storageClassLister: storageClassLister, + pluginRegistry: pluginRegistry, + } +} + +type externalVolumeWorkflowStore interface { + CreateExternalVolume(ctx context.Context, volume *ateapipb.ExternalVolume) (*ateapipb.ExternalVolume, error) + GetExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef) (*ateapipb.ExternalVolume, error) + UpdateExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef, precondition store.Precondition, mutate func(toUpdate *ateapipb.ExternalVolume) error) (*ateapipb.ExternalVolume, error) + DeleteExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef, precondition store.DeletePreconditions) (*ateapipb.ExternalVolume, error) + AcquireLease(ctx context.Context, key string) (*store.Lease, error) +} + +// CreateExternalVolume reserves the name, provisions the volume under an ID +// derived from the record's UID, and stamps the handle the driver returned. +// A create that dies leaves a PENDING record; delete it to retry. +func (w *ExternalVolumeWorkflow) CreateExternalVolume(ctx context.Context, volume *ateapipb.ExternalVolume) (*ateapipb.ExternalVolume, error) { + volumeRef := resources.ExternalVolumeRefFromExternalVolume(volume) + + ctx, lease, err := acquireExternalVolumeLease(ctx, w.store, volumeRef) + if err != nil { + return nil, err + } + defer lease.Close() + + toCreate, provisioning, err := w.resolveExternalVolumeSource(ctx, volume) + if err != nil { + return nil, err + } + reserved, err := w.ensureExternalVolumeReserved(ctx, volumeRef, toCreate) + if err != nil { + return nil, err + } + if provisioning == nil { + return reserved, nil + } + volumeID, volumeContext, err := w.ensureExternalVolumeProvisioned(ctx, reserved, provisioning) + if err != nil { + return nil, err + } + return w.ensureExternalVolumeFinalized(ctx, reserved, volumeID, volumeContext) +} + +type externalVolumeProvisioning struct { + provisioner string + parameters map[string]string +} + +// resolveExternalVolumeSource returns the record to reserve and, unless the +// request registers an existing volume, what provisioning it needs. +func (w *ExternalVolumeWorkflow) resolveExternalVolumeSource(ctx context.Context, volume *ateapipb.ExternalVolume) (_ *ateapipb.ExternalVolume, _ *externalVolumeProvisioning, err error) { + _, done := stepSpan(ctx, "ResolveExternalVolumeSource") + defer func() { err = done(err) }() + + toCreate := &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{ + Atespace: volume.GetMetadata().GetAtespace(), + Name: volume.GetMetadata().GetName(), + }, + DeleteTrigger: volume.GetDeleteTrigger(), + AccessMode: volume.GetAccessMode(), + StorageClassName: volume.GetStorageClassName(), + VolumeId: volume.GetVolumeId(), + VolumeType: volume.GetVolumeType(), + VolumeContext: volume.GetVolumeContext(), + Capacity: volume.GetCapacity(), + Status: &ateapipb.ExternalVolumeStatus{State: ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_PENDING}, + } + + var sc *storagev1.StorageClass + if scName := volume.GetStorageClassName(); scName != "" { + var err error + if sc, err = w.storageClassLister.Get(scName); err != nil { + if k8serrors.IsNotFound(err) { + return nil, nil, apierror.FailedPrecondition("StorageClass %q not found", scName) + } + return nil, nil, apierror.Internal("failed to get StorageClass %q: %v", scName, err) + } + } + + if toCreate.VolumeId != "" { + if toCreate.DeleteTrigger == ateapipb.DeleteTrigger_DELETE_TRIGGER_UNSPECIFIED { + toCreate.DeleteTrigger = ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL + } + if toCreate.VolumeType == "" && sc != nil { + toCreate.VolumeType = sc.Provisioner + } + toCreate.Status.State = ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY + return toCreate, nil, nil + } + if sc == nil { + return nil, nil, apierror.InvalidArgument("one of storage_class_name or volume_id is required") + } + if toCreate.DeleteTrigger == ateapipb.DeleteTrigger_DELETE_TRIGGER_UNSPECIFIED { + toCreate.DeleteTrigger = ateapipb.DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR + } + toCreate.VolumeType = sc.Provisioner + return toCreate, &externalVolumeProvisioning{provisioner: sc.Provisioner, parameters: sc.Parameters}, nil +} + +func (w *ExternalVolumeWorkflow) ensureExternalVolumeReserved(ctx context.Context, volumeRef resources.ExternalVolumeRef, toCreate *ateapipb.ExternalVolume) (_ *ateapipb.ExternalVolume, err error) { + ctx, done := stepSpan(ctx, "ReserveExternalVolume") + defer func() { err = done(err) }() + + stored, err := w.store.CreateExternalVolume(ctx, toCreate) + switch { + case err == nil: + return stored, nil + case errors.Is(err, store.ErrFailedPrecondition): + return nil, apierror.FailedPrecondition("Atespace %s not found", volumeRef.Atespace) + case errors.Is(err, store.ErrAlreadyExists): + return nil, apierror.AlreadyExists("ExternalVolume %s already exists; delete it and create it again to retry", volumeRef) + } + return nil, fmt.Errorf("while reserving external volume %s: %w", volumeRef, err) +} + +// TODO: pass access_mode to CreateVolume as the volume capability once +// READ_WRITE_MANY is accepted. +func (w *ExternalVolumeWorkflow) ensureExternalVolumeProvisioned(ctx context.Context, volume *ateapipb.ExternalVolume, provisioning *externalVolumeProvisioning) (_ string, _ map[string]string, err error) { + ctx, done := stepSpan(ctx, "ProvisionExternalVolume") + defer func() { err = done(err) }() + + volumeRef := resources.ExternalVolumeRefFromExternalVolume(volume) + plugin, err := w.pluginRegistry.GetPlugin(ctx, provisioning.provisioner) + if err != nil { + return "", nil, apierror.FailedPrecondition("failed to get volume plugin for driver %q (StorageClass %q): %v", provisioning.provisioner, volume.GetStorageClassName(), err) + } + resp, err := plugin.CreateVolume(ctx, createVolumeRequest(externalVolumeID(volume.GetMetadata().GetUid()), volume.GetCapacity(), provisioning.parameters)) + if err != nil { + return "", nil, apierror.Internal("failed to create external volume %s: %v", volumeRef, err) + } + return resp.VolumeID, resp.VolumeContext, nil +} + +// createVolumeRequest keeps the request construction out of callers whose +// parameters shadow the volume package. +func createVolumeRequest(name, capacity string, parameters map[string]string) volume.CreateVolumeRequest { + return volume.CreateVolumeRequest{Name: name, Capacity: capacity, Parameters: parameters} +} + +func (w *ExternalVolumeWorkflow) ensureExternalVolumeFinalized(ctx context.Context, volume *ateapipb.ExternalVolume, volumeID string, volumeContext map[string]string) (_ *ateapipb.ExternalVolume, err error) { + ctx, done := stepSpan(ctx, "FinalizeExternalVolume") + defer func() { err = done(err) }() + + volumeRef := resources.ExternalVolumeRefFromExternalVolume(volume) + stored, err := w.store.UpdateExternalVolume(ctx, volumeRef, store.PreconditionFrom(volume), func(toUpdate *ateapipb.ExternalVolume) error { + toUpdate.VolumeId = volumeID + toUpdate.VolumeContext = volumeContext + toUpdate.Status.State = ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY + return nil + }) + if err != nil { + if errors.Is(err, store.ErrVersionConflict) { + return nil, apierror.Aborted("concurrent update conflict, please retry") + } + if errors.Is(err, store.ErrNotFound) || errors.Is(err, store.ErrUIDConflict) { + return nil, apierror.Aborted("ExternalVolume %s was deleted while it was being created, please retry", volumeRef) + } + return nil, fmt.Errorf("while finalizing external volume %s: %w", volumeRef, err) + } + return stored, nil +} + +// DeleteExternalVolume deletes the storage and then removes the record, so a +// failure part way is retried by deleting again. Rejected while any actor +// references the volume. +func (w *ExternalVolumeWorkflow) DeleteExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef, precondition store.DeletePreconditions) (*ateapipb.ExternalVolume, error) { + ctx, lease, err := acquireExternalVolumeLease(ctx, w.store, volumeRef) + if err != nil { + return nil, err + } + defer lease.Close() + + stored, err := w.store.GetExternalVolume(ctx, volumeRef) + if err != nil { + if errors.Is(err, store.ErrNotFound) { + return nil, apierror.NotFound("ExternalVolume %s not found", volumeRef) + } + return nil, fmt.Errorf("while getting external volume: %w", err) + } + if err := precondition.Check(stored.GetMetadata()); err != nil { + return nil, externalVolumeDeleteConflict(err, volumeRef, precondition) + } + if refs := stored.GetStatus().GetRefs(); len(refs) > 0 { + return nil, apierror.FailedPrecondition("ExternalVolume %s is still referenced by %d actor(s), starting with %q", volumeRef, len(refs), refs[0].GetActorName()) + } + if err := w.reclaimExternalVolume(ctx, stored); err != nil { + return nil, err + } + + volume, err := w.store.DeleteExternalVolume(ctx, volumeRef, precondition) + if err != nil { + if errors.Is(err, store.ErrNotFound) { + return nil, apierror.NotFound("ExternalVolume %s not found", volumeRef) + } + if errors.Is(err, store.ErrUIDConflict) || errors.Is(err, store.ErrVersionConflict) { + return nil, externalVolumeDeleteConflict(err, volumeRef, precondition) + } + return nil, fmt.Errorf("while deleting external volume: %w", err) + } + return volume, nil +} + +func externalVolumeDeleteConflict(err error, volumeRef resources.ExternalVolumeRef, precondition store.DeletePreconditions) error { + if errors.Is(err, store.ErrUIDConflict) { + return apierror.Aborted("ExternalVolume %s does not have uid %s", volumeRef, precondition.UID) + } + return apierror.Aborted("concurrent update conflict, please retry") +} + +// TODO: add a reclaim policy that leaves the storage in place. +func (w *ExternalVolumeWorkflow) reclaimExternalVolume(ctx context.Context, volume *ateapipb.ExternalVolume) (err error) { + ctx, done := stepSpan(ctx, "ReclaimExternalVolume") + defer func() { err = done(err) }() + + volumeRef := resources.ExternalVolumeRefFromExternalVolume(volume) + if volume.GetVolumeType() == "" { + markSkipped(ctx, "volume names no driver") + return nil + } + volumeID := volume.GetVolumeId() + if volumeID == "" { + volumeID = externalVolumeID(volume.GetMetadata().GetUid()) + } + plugin, err := w.pluginRegistry.GetPlugin(ctx, volume.GetVolumeType()) + if err != nil { + return fmt.Errorf("while getting the volume plugin for %q of external volume %s: %w", volume.GetVolumeType(), volumeRef, err) + } + if err := plugin.DeleteVolume(ctx, volumeID); err != nil { + if apierror.Code(err) == codes.NotFound { + slog.WarnContext(ctx, "Volume not found during delete, assuming already deleted", slog.String("volume_id", volumeID)) + return nil + } + return fmt.Errorf("while reclaiming the storage %q of external volume %s: %w", volumeID, volumeRef, err) + } + return nil +} + +func externalVolumeID(volumeUID string) string { + return "substrate-" + volumeUID +} diff --git a/cmd/ateapi/internal/defaults/defaults.go b/cmd/ateapi/internal/defaults/defaults.go index 76c8bb2c7b..39c5f20555 100644 --- a/cmd/ateapi/internal/defaults/defaults.go +++ b/cmd/ateapi/internal/defaults/defaults.go @@ -38,6 +38,8 @@ func Apply(m proto.Message) { applyAtespaceDefaults(v) case *ateapipb.EgressPolicy: applyEgressPolicyDefaults(v) + case *ateapipb.ExternalVolume: + applyExternalVolumeDefaults(v) case *ateapipb.Tag: applyTagDefaults(v) case *ateapipb.Worker: @@ -105,6 +107,15 @@ func applyEgressPolicyDefaults(p *ateapipb.EgressPolicy) { } } +func applyExternalVolumeDefaults(v *ateapipb.ExternalVolume) { + if v == nil { + return + } + if v.AccessMode == ateapipb.AccessMode_ACCESS_MODE_UNSPECIFIED { + v.AccessMode = ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_ONCE + } +} + func applyTagDefaults(*ateapipb.Tag) {} func applyWorkerDefaults(*ateapipb.Worker) {} diff --git a/cmd/ateapi/internal/defaults/defaults_test.go b/cmd/ateapi/internal/defaults/defaults_test.go index ca8082713b..5a82ea16f7 100644 --- a/cmd/ateapi/internal/defaults/defaults_test.go +++ b/cmd/ateapi/internal/defaults/defaults_test.go @@ -54,6 +54,14 @@ func TestApply(t *testing.T) { want: &ateapipb.ActorTemplate{SnapshotConfig: &ateapipb.SnapshotConfig{ PreferredFidelity: scopeData, }}, + }, { + name: "external volume without an access mode gets read write once", + in: &ateapipb.ExternalVolume{}, + want: &ateapipb.ExternalVolume{AccessMode: ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_ONCE}, + }, { + name: "external volume keeps its access mode", + in: &ateapipb.ExternalVolume{AccessMode: ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_MANY}, + want: &ateapipb.ExternalVolume{AccessMode: ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_MANY}, }, { name: "container without wakeup probe stays without one", in: &ateapipb.ActorTemplate{Containers: []*ateapipb.Container{{Name: "main"}}}, diff --git a/cmd/ateapi/internal/store/atepg/common_test.go b/cmd/ateapi/internal/store/atepg/common_test.go index 6edd774f3e..b5cb28aeaf 100644 --- a/cmd/ateapi/internal/store/atepg/common_test.go +++ b/cmd/ateapi/internal/store/atepg/common_test.go @@ -27,7 +27,7 @@ import ( // state, so the statement lives here rather than on Persistence. func clearAll(t *testing.T, p *Persistence) { t.Helper() - if _, err := p.pool.Exec(context.Background(), `TRUNCATE atespaces, global_access_policy, atespace_access_policies, actors, actor_egress_policies, actor_templates, tags, workers, worker_assignments, leases, worker_outbox, worker_outbox_trim, tuple, changelog`); err != nil { + if _, err := p.pool.Exec(context.Background(), `TRUNCATE atespaces, global_access_policy, atespace_access_policies, actors, actor_egress_policies, actor_templates, tags, external_volumes, workers, worker_assignments, leases, worker_outbox, worker_outbox_trim, tuple, changelog`); err != nil { t.Fatalf("truncating tables: %v", err) } } diff --git a/cmd/ateapi/internal/store/atepg/external_volume.go b/cmd/ateapi/internal/store/atepg/external_volume.go new file mode 100644 index 0000000000..b40e47d763 --- /dev/null +++ b/cmd/ateapi/internal/store/atepg/external_volume.go @@ -0,0 +1,297 @@ +// 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 atepg + +import ( + "context" + "errors" + "fmt" + "maps" + + "github.com/agent-substrate/substrate/cmd/ateapi/internal/store" + "github.com/agent-substrate/substrate/internal/resources" + "github.com/agent-substrate/substrate/pkg/proto/ateapipb" + "github.com/jackc/pgx/v5" + "google.golang.org/protobuf/proto" +) + +func (p *Persistence) GetExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef) (*ateapipb.ExternalVolume, error) { + atespace, name := volumeRef.Atespace, volumeRef.Name + var protoBytes []byte + if err := p.pool.QueryRow(ctx, ` + SELECT proto FROM external_volumes + WHERE atespace = $1 AND name = $2`, atespace, name).Scan(&protoBytes); err != nil { + if errors.Is(err, pgx.ErrNoRows) { + return nil, store.ErrNotFound + } + return nil, fmt.Errorf("getting external volume %s/%s: %w", atespace, name, err) + } + volume := &ateapipb.ExternalVolume{} + if err := unmarshalStored(protoBytes, volume); err != nil { + return nil, fmt.Errorf("unmarshaling external volume: %w", err) + } + return volume, nil +} + +func (p *Persistence) ListExternalVolumes(ctx context.Context, atespace string, opts store.ListOptions) (store.ListResponse[*ateapipb.ExternalVolume], error) { + opts, err := store.NormalizeListOptions(opts) + if err != nil { + return store.ListResponse[*ateapipb.ExternalVolume]{}, err + } + var items []*ateapipb.ExternalVolume + var nextToken string + if atespace != "" { + items, nextToken, err = p.listExternalVolumesScoped(ctx, atespace, opts.PageSize, opts.PageToken) + } else { + items, nextToken, err = p.listExternalVolumesGlobal(ctx, opts.PageSize, opts.PageToken) + } + if err != nil { + return store.ListResponse[*ateapipb.ExternalVolume]{}, err + } + return store.ListResponse[*ateapipb.ExternalVolume]{Items: items, NextPageToken: nextToken}, nil +} + +func (p *Persistence) listExternalVolumesScoped(ctx context.Context, atespace string, pageSize int32, pageTokenStr string) ([]*ateapipb.ExternalVolume, string, error) { + token, err := decodePageToken(pageTokenStr, kindExternalVol, atespace, 1) + if err != nil { + return nil, "", err + } + var last *string + if len(token.Last) > 0 { + last = &token.Last[0] + } + rows, err := p.pool.Query(ctx, ` + SELECT name, proto FROM external_volumes + WHERE atespace = $1 AND ($2::text IS NULL OR name > $2) + ORDER BY name + LIMIT $3`, atespace, last, int64(pageSize)+1) + if err != nil { + return nil, "", fmt.Errorf("listing external volumes in %q: %w", atespace, err) + } + defer rows.Close() + + var names []string + var result []*ateapipb.ExternalVolume + for rows.Next() { + var name string + var protoBytes []byte + if err := rows.Scan(&name, &protoBytes); err != nil { + return nil, "", fmt.Errorf("scanning external volume row: %w", err) + } + volume := &ateapipb.ExternalVolume{} + if err := unmarshalStored(protoBytes, volume); err != nil { + return nil, "", fmt.Errorf("unmarshaling external volume: %w", err) + } + result = append(result, volume) + names = append(names, name) + } + if err := rows.Err(); err != nil { + return nil, "", fmt.Errorf("listing external volumes in %q: %w", atespace, err) + } + var nextToken string + if len(result) > int(pageSize) { + result = result[:pageSize] + nextToken = encodePageToken(kindExternalVol, atespace, []string{names[pageSize-1]}) + } + return result, nextToken, nil +} + +func (p *Persistence) listExternalVolumesGlobal(ctx context.Context, pageSize int32, pageTokenStr string) ([]*ateapipb.ExternalVolume, string, error) { + token, err := decodePageToken(pageTokenStr, kindExternalVol, "", 2) + if err != nil { + return nil, "", err + } + var lastAtespace, lastName *string + if len(token.Last) == 2 { + lastAtespace, lastName = &token.Last[0], &token.Last[1] + } + rows, err := p.pool.Query(ctx, ` + SELECT atespace, name, proto FROM external_volumes + WHERE $1::text IS NULL OR (atespace, name) > ($1, $2) + ORDER BY atespace, name + LIMIT $3`, lastAtespace, lastName, int64(pageSize)+1) + if err != nil { + return nil, "", fmt.Errorf("listing external volumes: %w", err) + } + defer rows.Close() + + type key struct{ atespace, name string } + var keys []key + var result []*ateapipb.ExternalVolume + 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 external volume row: %w", err) + } + volume := &ateapipb.ExternalVolume{} + if err := unmarshalStored(protoBytes, volume); err != nil { + return nil, "", fmt.Errorf("unmarshaling external volume: %w", err) + } + result = append(result, volume) + keys = append(keys, k) + } + if err := rows.Err(); err != nil { + return nil, "", fmt.Errorf("listing external volumes: %w", err) + } + var nextToken string + if len(result) > int(pageSize) { + result = result[:pageSize] + last := keys[pageSize-1] + nextToken = encodePageToken(kindExternalVol, "", []string{last.atespace, last.name}) + } + return result, nextToken, nil +} + +func (p *Persistence) CreateExternalVolume(ctx context.Context, volume *ateapipb.ExternalVolume) (*ateapipb.ExternalVolume, error) { + atespace := volume.GetMetadata().GetAtespace() + name := volume.GetMetadata().GetName() + dbVolume := proto.CloneOf(volume) + setCreateMetadata(dbVolume.Metadata) + protoBytes, err := proto.Marshal(dbVolume) + if err != nil { + return nil, fmt.Errorf("marshaling external volume: %w", err) + } + + _, err = p.pool.Exec(ctx, ` + INSERT INTO external_volumes (atespace, name, uid, version, proto) + VALUES ($1, $2, $3, $4, $5)`, atespace, name, + dbVolume.GetMetadata().GetUid(), dbVolume.GetMetadata().GetVersion(), protoBytes) + if err != nil { + if isUniqueViolation(err) { + return nil, store.ErrAlreadyExists + } + if isForeignKeyViolation(err) { + switch pgErrConstraint(err) { + case "external_volumes_atespace_fk": + return nil, store.ErrFailedPrecondition + default: + return nil, fmt.Errorf("inserting external volume %s/%s violated unknown foreign key %q: %w", atespace, name, pgErrConstraint(err), err) + } + } + return nil, fmt.Errorf("inserting external volume %s/%s: %w", atespace, name, err) + } + return dbVolume, nil +} + +func validateUpdateExternalVolumeMutation(storedVolume, mutatedVolume *ateapipb.ExternalVolume) error { + if stored, mutated := storedVolume.GetMetadata().GetAtespace(), mutatedVolume.GetMetadata().GetAtespace(); stored != mutated { + return fmt.Errorf("metadata.atespace is immutable: mutation changed it from %q to %q", stored, mutated) + } + if stored, mutated := storedVolume.GetMetadata().GetName(), mutatedVolume.GetMetadata().GetName(); stored != mutated { + return fmt.Errorf("metadata.name is immutable: mutation changed it from %q to %q", stored, mutated) + } + if stored, mutated := storedVolume.GetAccessMode(), mutatedVolume.GetAccessMode(); stored != ateapipb.AccessMode_ACCESS_MODE_UNSPECIFIED && stored != mutated { + return fmt.Errorf("access_mode is immutable once set: mutation changed it from %v to %v", stored, mutated) + } + if stored, mutated := storedVolume.GetStorageClassName(), mutatedVolume.GetStorageClassName(); stored != "" && stored != mutated { + return fmt.Errorf("storage_class_name is immutable once set: mutation changed it from %q to %q", stored, mutated) + } + if stored, mutated := storedVolume.GetCapacity(), mutatedVolume.GetCapacity(); stored != "" && stored != mutated { + return fmt.Errorf("capacity is immutable once set: mutation changed it from %q to %q", stored, mutated) + } + if stored, mutated := storedVolume.GetVolumeId(), mutatedVolume.GetVolumeId(); stored != "" && stored != mutated { + return fmt.Errorf("volume_id is immutable once set: mutation changed it from %q to %q", stored, mutated) + } + if stored, mutated := storedVolume.GetVolumeType(), mutatedVolume.GetVolumeType(); stored != "" && stored != mutated { + return fmt.Errorf("volume_type is immutable once set: mutation changed it from %q to %q", stored, mutated) + } + if stored, mutated := storedVolume.GetVolumeContext(), mutatedVolume.GetVolumeContext(); len(stored) > 0 && !maps.Equal(stored, mutated) { + return fmt.Errorf("volume_context is immutable once set: mutation changed it from %v to %v", stored, mutated) + } + return nil +} + +func (p *Persistence) UpdateExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef, precondition store.Precondition, mutate func(*ateapipb.ExternalVolume) error) (*ateapipb.ExternalVolume, error) { + if err := precondition.Validate(); err != nil { + return nil, err + } + atespace, name := volumeRef.Atespace, volumeRef.Name + var currentUID string + var currentVersion int64 + var currentBytes []byte + if err := p.pool.QueryRow(ctx, ` + SELECT uid, version, proto FROM external_volumes + WHERE atespace = $1 AND name = $2`, atespace, name).Scan(¤tUID, ¤tVersion, ¤tBytes); err != nil { + if errors.Is(err, pgx.ErrNoRows) { + return nil, store.ErrNotFound + } + return nil, fmt.Errorf("getting external volume %s/%s for update: %w", atespace, name, err) + } + + dbVolume := &ateapipb.ExternalVolume{} + if err := unmarshalStored(currentBytes, dbVolume); err != nil { + return nil, fmt.Errorf("unmarshaling external volume: %w", err) + } + if err := validateProtoMetadataMatchesColumns(fmt.Sprintf("external volume %s/%s", atespace, name), dbVolume.GetMetadata(), currentUID, currentVersion); err != nil { + return nil, err + } + if err := precondition.Check(dbVolume.GetMetadata()); err != nil { + return nil, err + } + volumeBeforeMutation := proto.CloneOf(dbVolume) + if err := mutate(dbVolume); err != nil { + return nil, err + } + if err := validateUpdateExternalVolumeMutation(volumeBeforeMutation, dbVolume); err != nil { + return nil, fmt.Errorf("%w: %w", store.ErrImmutableField, err) + } + setUpdateMetadata(dbVolume.Metadata, volumeBeforeMutation.GetMetadata()) + + updatedBytes, err := proto.Marshal(dbVolume) + if err != nil { + return nil, fmt.Errorf("marshaling external volume: %w", err) + } + commandTag, err := p.pool.Exec(ctx, ` + UPDATE external_volumes + SET version = $1, proto = $2 + WHERE atespace = $3 AND name = $4 AND uid = $5 AND version = $6`, + dbVolume.GetMetadata().GetVersion(), updatedBytes, atespace, name, currentUID, currentVersion) + if err != nil { + return nil, fmt.Errorf("updating external volume %s/%s: %w", atespace, name, err) + } + if commandTag.RowsAffected() == 0 { + return nil, store.ErrVersionConflict + } + if commandTag.RowsAffected() != 1 { + return nil, fmt.Errorf("updating external volume %s/%s affected %d rows, want 1", atespace, name, commandTag.RowsAffected()) + } + return dbVolume, nil +} + +func (p *Persistence) DeleteExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef, precondition store.DeletePreconditions) (*ateapipb.ExternalVolume, error) { + atespace, name := volumeRef.Atespace, volumeRef.Name + var protoBytes []byte + err := p.pool.QueryRow(ctx, ` + DELETE FROM external_volumes + WHERE atespace = $1 AND name = $2 + AND ($3::text = '' OR uid = $3::text) + AND ($4::bigint = 0 OR version = $4::bigint) + RETURNING proto`, atespace, name, precondition.UID, precondition.Version).Scan(&protoBytes) + if errors.Is(err, pgx.ErrNoRows) { + var uid string + var version int64 + err := p.pool.QueryRow(ctx, `SELECT uid, version FROM external_volumes WHERE atespace = $1 AND name = $2`, atespace, name).Scan(&uid, &version) + return nil, mapDeleteError(err, uid, version, precondition) + } + if err != nil { + return nil, fmt.Errorf("deleting external volume %s/%s: %w", atespace, name, err) + } + volume := &ateapipb.ExternalVolume{} + if err := unmarshalStored(protoBytes, volume); err != nil { + return nil, fmt.Errorf("unmarshaling deleted external volume: %w", err) + } + return volume, nil +} diff --git a/cmd/ateapi/internal/store/atepg/migrations/000004_external_volumes.sql b/cmd/ateapi/internal/store/atepg/migrations/000004_external_volumes.sql new file mode 100644 index 0000000000..f8c317a8ee --- /dev/null +++ b/cmd/ateapi/internal/store/atepg/migrations/000004_external_volumes.sql @@ -0,0 +1,27 @@ +-- 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. + +-- +goose Up + +-- RESTRICT so that deleting an atespace cannot strand provisioned storage. +CREATE TABLE external_volumes ( + atespace text NOT NULL, + name text NOT NULL, + uid text NOT NULL, + version bigint NOT NULL, + proto bytea NOT NULL, + PRIMARY KEY (atespace, name), + CONSTRAINT external_volumes_atespace_fk + FOREIGN KEY (atespace) REFERENCES atespaces(name) ON DELETE RESTRICT +); diff --git a/cmd/ateapi/internal/store/atepg/pagetoken.go b/cmd/ateapi/internal/store/atepg/pagetoken.go index ebf56b5ae2..a282938339 100644 --- a/cmd/ateapi/internal/store/atepg/pagetoken.go +++ b/cmd/ateapi/internal/store/atepg/pagetoken.go @@ -35,6 +35,7 @@ const ( kindActor resourceKind = "actor" kindActorTemplate resourceKind = "actor-template" kindTag resourceKind = "tag" + kindExternalVol resourceKind = "external-volume" kindWorker resourceKind = "worker" kindWorkerAssign resourceKind = "worker-assignment" ) diff --git a/cmd/ateapi/internal/store/atepg/partition_test.go b/cmd/ateapi/internal/store/atepg/partition_test.go index 20ba51fd29..765a152296 100644 --- a/cmd/ateapi/internal/store/atepg/partition_test.go +++ b/cmd/ateapi/internal/store/atepg/partition_test.go @@ -45,7 +45,7 @@ func TestActorsTablePartitionable(t *testing.T) { // by definition, under each partition key. spansPartitions := map[string][]string{ // A global list walks every atespace. - "atespace": {globalList("actors"), globalList("actor_templates"), globalList("tags")}, + "atespace": {globalList("actors"), globalList("actor_templates"), globalList("tags"), globalList("external_volumes")}, // A global list walks every name, and a list within one atespace // spans every name hash. "name": {globalList("actors"), scopedActorList}, diff --git a/cmd/ateapi/internal/store/store.go b/cmd/ateapi/internal/store/store.go index cc494082c1..0421025fb9 100644 --- a/cmd/ateapi/internal/store/store.go +++ b/cmd/ateapi/internal/store/store.go @@ -159,6 +159,26 @@ type Interface interface { // tag the caller observed. DeleteTag(ctx context.Context, tagRef resources.TagRef, precondition DeletePreconditions) (*ateapipb.Tag, error) + // Stores a new external volume and returns it with server-assigned metadata. + // Returns ErrAlreadyExists if the name is taken, or ErrFailedPrecondition if + // the atespace does not exist. + CreateExternalVolume(ctx context.Context, volume *ateapipb.ExternalVolume) (*ateapipb.ExternalVolume, error) + + // Fetches an external volume by reference. Returns ErrNotFound if missing. + GetExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef) (*ateapipb.ExternalVolume, error) + + // Lists external volumes in one atespace, or all atespaces when empty. + ListExternalVolumes(ctx context.Context, atespace string, opts ListOptions) (ListResponse[*ateapipb.ExternalVolume], error) + + // UpdateExternalVolume performs a guarded read-modify-write like UpdateTag. + // Everything naming the storage, and access_mode, is set-once and returns + // ErrImmutableField when changed. + UpdateExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef, precondition Precondition, mutate func(toUpdate *ateapipb.ExternalVolume) error) (*ateapipb.ExternalVolume, error) + + // Deletes and returns an external volume record; the storage is the caller's + // job. + DeleteExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef, precondition DeletePreconditions) (*ateapipb.ExternalVolume, 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. diff --git a/cmd/ateapi/internal/store/storecontract/contract.go b/cmd/ateapi/internal/store/storecontract/contract.go index 3589e6849c..ab10123063 100644 --- a/cmd/ateapi/internal/store/storecontract/contract.go +++ b/cmd/ateapi/internal/store/storecontract/contract.go @@ -209,6 +209,7 @@ func RunContractTests(t *testing.T, setup func(t *testing.T) store.Interface) { runAtespaceContractTests(t, setup) runActorTemplateContractTests(t, setup) runTagContractTests(t, setup) + runExternalVolumeContractTests(t, setup) runLeaseContractTests(t, setup) runListOptionsContractTests(t, setup) runUnknownFieldContractTests(t, setup) @@ -394,6 +395,7 @@ func runListOptionsContractTests(t *testing.T, setup func(t *testing.T) store.In {"actors", func(opts store.ListOptions) error { _, err := s.ListActors(ctx, "", opts); return err }}, {"actor templates", func(opts store.ListOptions) error { _, err := s.ListActorTemplates(ctx, "", opts); return err }}, {"tags", func(opts store.ListOptions) error { _, err := s.ListTags(ctx, "", opts); return err }}, + {"external volumes", func(opts store.ListOptions) error { _, err := s.ListExternalVolumes(ctx, "", opts); return err }}, {"workers", func(opts store.ListOptions) error { _, err := s.ListWorkers(ctx, opts); return err }}, } for _, call := range calls { @@ -419,6 +421,7 @@ func runListOptionsContractTests(t *testing.T, setup func(t *testing.T) store.In {"actors", func(opts store.ListOptions) error { _, err := s.ListActors(ctx, "", opts); return err }}, {"actor templates", func(opts store.ListOptions) error { _, err := s.ListActorTemplates(ctx, "", opts); return err }}, {"tags", func(opts store.ListOptions) error { _, err := s.ListTags(ctx, "", opts); return err }}, + {"external volumes", func(opts store.ListOptions) error { _, err := s.ListExternalVolumes(ctx, "", opts); return err }}, {"workers", func(opts store.ListOptions) error { _, err := s.ListWorkers(ctx, opts); return err }}, } for _, call := range calls { @@ -1547,6 +1550,302 @@ func storeTag(t *testing.T, s store.Interface, tag *ateapipb.Tag) *ateapipb.Tag return stored } +func newTestPendingExternalVolume(atespace, name string) *ateapipb.ExternalVolume { + return &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: name}, + DeleteTrigger: ateapipb.DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR, + AccessMode: ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_ONCE, + StorageClassName: "standard-rwx", + Status: &ateapipb.ExternalVolumeStatus{State: ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_PENDING}, + } +} + +func finalizeExternalVolume(toUpdate *ateapipb.ExternalVolume) error { + toUpdate.VolumeId = "substrate-" + toUpdate.GetMetadata().GetUid() + toUpdate.VolumeType = "filestore.csi.storage.gke.io" + toUpdate.VolumeContext = map[string]string{"ip": "10.0.0.2"} + toUpdate.Status.State = ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY + return nil +} + +func storeExternalVolume(t *testing.T, s store.Interface, volume *ateapipb.ExternalVolume) *ateapipb.ExternalVolume { + t.Helper() + reserved, err := s.CreateExternalVolume(context.Background(), volume) + if err != nil { + t.Fatalf("CreateExternalVolume(%q) failed: %v", volume.GetMetadata().GetName(), err) + } + stored, err := s.UpdateExternalVolume(context.Background(), resources.ExternalVolumeRefFromExternalVolume(reserved), store.PreconditionFrom(reserved), finalizeExternalVolume) + if err != nil { + t.Fatalf("finalizing external volume %q failed: %v", volume.GetMetadata().GetName(), err) + } + return stored +} + +func runExternalVolumeContractTests(t *testing.T, setup func(t *testing.T) store.Interface) { + t.Helper() + + t.Run("ExternalVolume_Lifecycle", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + mustCreateAtespace(t, s, "team-a") + + input := newTestPendingExternalVolume("team-a", "scratch") + pending, err := s.CreateExternalVolume(ctx, input) + if err != nil { + t.Fatalf("CreateExternalVolume failed: %v", err) + } + if pending.GetMetadata().GetVersion() != 1 || pending.GetMetadata().GetUid() == "" { + t.Errorf("created volume metadata = %v, want server-owned uid and version 1", pending.GetMetadata()) + } + if input.GetMetadata().GetUid() != "" || input.GetMetadata().GetVersion() != 0 { + t.Errorf("CreateExternalVolume mutated its input metadata: %v", input.GetMetadata()) + } + + volumeRef := resources.ExternalVolumeRef{Atespace: "team-a", Name: "scratch"} + volume, err := s.GetExternalVolume(ctx, volumeRef) + if err != nil { + t.Fatalf("GetExternalVolume failed: %v", err) + } + if volume.GetVolumeId() != "" { + t.Errorf("reserved volume id = %q, want unset", volume.GetVolumeId()) + } + if diff := cmp.Diff(input, volume, protocmp.Transform(), ignoreUID, ignoreVersion, ignoreTimestamps); diff != "" { + t.Errorf("stored external volume mismatch (-want +got):\n%s", diff) + } + if _, err := s.GetExternalVolume(ctx, resources.ExternalVolumeRef{Atespace: "team-a", Name: "missing"}); !errors.Is(err, store.ErrNotFound) { + t.Errorf("missing GetExternalVolume = %v, want ErrNotFound", err) + } + + ready, err := s.UpdateExternalVolume(ctx, volumeRef, store.PreconditionFrom(volume), finalizeExternalVolume) + if err != nil { + t.Fatalf("finalizing external volume failed: %v", err) + } + if got, want := ready.GetVolumeId(), "substrate-"+volume.GetMetadata().GetUid(); got != want { + t.Errorf("finalized volume id = %q, want %q", got, want) + } + if ready.GetStatus().GetState() != ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY { + t.Errorf("finalized volume state = %v, want READY", ready.GetStatus().GetState()) + } + + claimed, err := s.UpdateExternalVolume(ctx, volumeRef, store.PreconditionFrom(ready), func(toUpdate *ateapipb.ExternalVolume) error { + toUpdate.DeleteTrigger = ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL + toUpdate.Status.Refs = append(toUpdate.Status.Refs, &ateapipb.ActorRef{ActorUid: "actor-uid-1", ActorName: "producer", Active: true}) + return nil + }) + if err != nil { + t.Fatalf("UpdateExternalVolume failed: %v", err) + } + if claimed.GetDeleteTrigger() != ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL || len(claimed.GetStatus().GetRefs()) != 1 { + t.Errorf("updated volume = %v, want MANUAL and one ref", claimed) + } + if claimed.GetMetadata().GetVersion() != ready.GetMetadata().GetVersion()+1 { + t.Errorf("updated volume version = %d, want %d", claimed.GetMetadata().GetVersion(), ready.GetMetadata().GetVersion()+1) + } + if _, err := s.UpdateExternalVolume(ctx, volumeRef, store.PreconditionFrom(ready), func(toUpdate *ateapipb.ExternalVolume) error { + return nil + }); !errors.Is(err, store.ErrVersionConflict) { + t.Errorf("stale UpdateExternalVolume = %v, want ErrVersionConflict", err) + } + if _, err := s.DeleteAtespace(ctx, "team-a", store.DeletePreconditions{}); !errors.Is(err, store.ErrFailedPrecondition) { + t.Errorf("DeleteAtespace with an external volume = %v, want ErrFailedPrecondition", err) + } + + if _, err := s.DeleteExternalVolume(ctx, volumeRef, store.DeletePreconditions{Version: ready.GetMetadata().GetVersion()}); !errors.Is(err, store.ErrVersionConflict) { + t.Errorf("stale DeleteExternalVolume = %v, want ErrVersionConflict", err) + } + deleted, err := s.DeleteExternalVolume(ctx, volumeRef, store.DeletePreconditions{UID: claimed.GetMetadata().GetUid()}) + if err != nil || !proto.Equal(deleted, claimed) { + t.Errorf("DeleteExternalVolume = (%v, %v), want the claimed volume", deleted, err) + } + if _, err := s.GetExternalVolume(ctx, volumeRef); !errors.Is(err, store.ErrNotFound) { + t.Errorf("deleted GetExternalVolume = %v, want ErrNotFound", err) + } + }) + + t.Run("ExternalVolume_ImmutableFields", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + mustCreateAtespace(t, s, "team-a") + volume := storeExternalVolume(t, s, newTestPendingExternalVolume("team-a", "scratch")) + + tests := []struct { + name string + mutate func(*ateapipb.ExternalVolume) + }{ + { + name: "access mode", + mutate: func(toUpdate *ateapipb.ExternalVolume) { + toUpdate.AccessMode = ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_MANY + }, + }, + { + name: "storage class name", + mutate: func(toUpdate *ateapipb.ExternalVolume) { toUpdate.StorageClassName = "premium-rwx" }, + }, + { + name: "clearing the storage class name", + mutate: func(toUpdate *ateapipb.ExternalVolume) { toUpdate.StorageClassName = "" }, + }, + { + name: "volume id", + mutate: func(toUpdate *ateapipb.ExternalVolume) { toUpdate.VolumeId = "substrate-somewhere-else" }, + }, + { + name: "clearing the volume id", + mutate: func(toUpdate *ateapipb.ExternalVolume) { toUpdate.VolumeId = "" }, + }, + { + name: "volume type", + mutate: func(toUpdate *ateapipb.ExternalVolume) { toUpdate.VolumeType = "pd.csi.storage.gke.io" }, + }, + { + name: "volume context", + mutate: func(toUpdate *ateapipb.ExternalVolume) { toUpdate.VolumeContext = map[string]string{"ip": "10.0.0.3"} }, + }, + { + name: "clearing the volume context", + mutate: func(toUpdate *ateapipb.ExternalVolume) { toUpdate.VolumeContext = nil }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := s.UpdateExternalVolume(ctx, resources.ExternalVolumeRef{Atespace: "team-a", Name: "scratch"}, store.PreconditionFrom(volume), func(toUpdate *ateapipb.ExternalVolume) error { + tt.mutate(toUpdate) + return nil + }) + if !errors.Is(err, store.ErrImmutableField) { + t.Errorf("UpdateExternalVolume error = %v, want one matching store.ErrImmutableField", err) + } + }) + } + }) + + t.Run("CreateExternalVolume_ReusedName", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + mustCreateAtespace(t, s, "team-a") + input := newTestPendingExternalVolume("team-a", "scratch") + if _, err := s.CreateExternalVolume(ctx, input); err != nil { + t.Fatalf("CreateExternalVolume failed: %v", err) + } + if _, err := s.CreateExternalVolume(ctx, input); !errors.Is(err, store.ErrAlreadyExists) { + t.Errorf("duplicate CreateExternalVolume = %v, want ErrAlreadyExists", err) + } + + stored, err := s.GetExternalVolume(ctx, resources.ExternalVolumeRef{Atespace: "team-a", Name: "scratch"}) + if err != nil { + t.Fatalf("GetExternalVolume failed: %v", err) + } + if stored.GetMetadata().GetVersion() != 1 { + t.Errorf("volume version after rejected create = %d, want 1", stored.GetMetadata().GetVersion()) + } + }) + + t.Run("CreateExternalVolume_UnknownAtespace", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + + if _, err := s.CreateExternalVolume(ctx, newTestPendingExternalVolume("team-missing", "scratch")); !errors.Is(err, store.ErrFailedPrecondition) { + t.Errorf("CreateExternalVolume in an unknown atespace = %v, want ErrFailedPrecondition", err) + } + }) + + t.Run("UpdateExternalVolume_MissingPrecondition", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + mustCreateAtespace(t, s, "team-a") + created := storeExternalVolume(t, s, newTestPendingExternalVolume("team-a", "scratch")) + + tests := []struct { + name string + precondition store.Precondition + }{ + { + name: "no precondition", + precondition: store.Precondition{}, + }, + { + name: "guarding on only a uid", + precondition: store.Precondition{UID: created.GetMetadata().GetUid()}, + }, + { + name: "guarding on only a version", + precondition: store.Precondition{Version: created.GetMetadata().GetVersion()}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := s.UpdateExternalVolume(ctx, resources.ExternalVolumeRef{Atespace: "team-a", Name: "scratch"}, tt.precondition, func(toUpdate *ateapipb.ExternalVolume) error { + t.Fatal("mutate ran for a blind write") + return nil + }) + if !errors.Is(err, store.ErrPreconditionRequired) { + t.Errorf("UpdateExternalVolume error = %v, want one matching store.ErrPreconditionRequired", err) + } + }) + } + }) + + t.Run("UpdateExternalVolume_NotFound", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + mustCreateAtespace(t, s, "team-a") + + _, err := s.UpdateExternalVolume(ctx, resources.ExternalVolumeRef{Atespace: "team-a", Name: "missing"}, store.Precondition{UID: "u", Version: 1}, func(*ateapipb.ExternalVolume) error { return nil }) + if !errors.Is(err, store.ErrNotFound) { + t.Errorf("UpdateExternalVolume on a missing volume = %v, want ErrNotFound", err) + } + if _, err := s.DeleteExternalVolume(ctx, resources.ExternalVolumeRef{Atespace: "team-a", Name: "missing"}, store.DeletePreconditions{}); !errors.Is(err, store.ErrNotFound) { + t.Errorf("DeleteExternalVolume on a missing volume = %v, want ErrNotFound", err) + } + }) + + t.Run("ListExternalVolumes_PaginationAndScope", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + for _, atespace := range []string{"team-a", "team-b"} { + mustCreateAtespace(t, s, atespace) + for i := 0; i < 3; i++ { + storeExternalVolume(t, s, newTestPendingExternalVolume(atespace, fmt.Sprintf("volume-%d", i))) + } + } + + var scoped []*ateapipb.ExternalVolume + for token := ""; ; { + page, err := s.ListExternalVolumes(ctx, "team-a", store.ListOptions{PageSize: 2, PageToken: token}) + if err != nil { + t.Fatalf("scoped ListExternalVolumes failed: %v", err) + } + scoped = append(scoped, page.Items...) + if page.NextPageToken == "" { + break + } + token = page.NextPageToken + } + if len(scoped) != 3 { + t.Errorf("scoped ListExternalVolumes returned %d volumes, want 3", len(scoped)) + } + + var global []*ateapipb.ExternalVolume + for token := ""; ; { + page, err := s.ListExternalVolumes(ctx, "", store.ListOptions{PageSize: 2, PageToken: token}) + if err != nil { + t.Fatalf("global ListExternalVolumes failed: %v", err) + } + global = append(global, page.Items...) + if page.NextPageToken == "" { + break + } + token = page.NextPageToken + } + if len(global) != 6 { + t.Errorf("global ListExternalVolumes returned %d volumes, want 6", len(global)) + } + }) +} + func runWorkerContractTests(t *testing.T, setup func(t *testing.T) store.Interface) { t.Helper() diff --git a/cmd/ateapi/internal/store/storetest/storetest.go b/cmd/ateapi/internal/store/storetest/storetest.go index ed8e457d7b..28f22c476b 100644 --- a/cmd/ateapi/internal/store/storetest/storetest.go +++ b/cmd/ateapi/internal/store/storetest/storetest.go @@ -136,6 +136,19 @@ func MustCreateTag(t *testing.T, ctx context.Context, s store.Interface, tag *at return created } +// MustCreateExternalVolume ensures volume's parent atespace exists, then stores volume as given. +func MustCreateExternalVolume(t *testing.T, ctx context.Context, s store.Interface, volume *ateapipb.ExternalVolume) *ateapipb.ExternalVolume { + t.Helper() + atespace := volume.GetMetadata().GetAtespace() + name := volume.GetMetadata().GetName() + MustCreateAtespace(t, ctx, s, atespace) + created, err := s.CreateExternalVolume(ctx, volume) + if err != nil { + t.Fatalf("creating test external volume %q/%q: %v", atespace, name, err) + } + return created +} + // RunTests runs m and terminates the shared PostgreSQL container afterwards. // Packages with no other TestMain work should use it as their whole TestMain; // the rest must call [Shutdown] themselves. diff --git a/cmd/kubectl-ate/internal/cmd/external_volume.go b/cmd/kubectl-ate/internal/cmd/external_volume.go new file mode 100644 index 0000000000..07c69347de --- /dev/null +++ b/cmd/kubectl-ate/internal/cmd/external_volume.go @@ -0,0 +1,268 @@ +// 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 cmd + +import ( + "context" + "fmt" + "strings" + + "github.com/agent-substrate/substrate/cmd/kubectl-ate/internal/printer" + "github.com/agent-substrate/substrate/internal/ateclient" + "github.com/agent-substrate/substrate/pkg/proto/ateapipb" + "github.com/spf13/cobra" + "google.golang.org/grpc" +) + +var ( + externalVolumeAtespaceFlag string + externalVolumeAllAtespacesFlag bool + createExternalVolumeAtespaceFlag string + createExternalVolumeClassFlag string + createExternalVolumeCapacityFlag string + createExternalVolumeVolumeIDFlag string + createExternalVolumeTypeFlag string + createExternalVolumeContextFlag map[string]string + createExternalVolumeDeleteTriggerFlag string + createExternalVolumeAccessModeFlag string + updateExternalVolumeAtespaceFlag string + updateExternalVolumeDeleteTriggerFlag string + deleteExternalVolumeAtespaceFlag string +) + +var getExternalVolumesCmd = &cobra.Command{ + Use: "externalvolumes [volume-name ...]", + Aliases: []string{"externalvolume", "ev"}, + Short: "List or get external volumes", + RunE: func(cmd *cobra.Command, args []string) error { + if externalVolumeAllAtespacesFlag && externalVolumeAtespaceFlag != "" { + return fmt.Errorf("--atespace and -A/--all-atespaces are mutually exclusive") + } + if len(args) > 0 && externalVolumeAtespaceFlag == "" { + return fmt.Errorf("--atespace is required when getting external volumes") + } + if len(args) == 0 && !externalVolumeAllAtespacesFlag && externalVolumeAtespaceFlag == "" { + return fmt.Errorf("specify --atespace , or -A/--all-atespaces") + } + + ctx := cmd.Context() + client, err := ateclient.NewClient(ctx, kubeconfig, k8sContext, endpoint, tokenFile, traceEnabled) + if err != nil { + return fmt.Errorf("failed to connect to ate-api-server: %w", err) + } + defer client.Close() + + if len(args) > 0 { + volumes := make([]*ateapipb.ExternalVolume, 0, len(args)) + for _, name := range args { + volume, err := client.GetExternalVolume(ctx, &ateapipb.GetExternalVolumeRequest{ + ExternalVolume: &ateapipb.ObjectRef{Atespace: externalVolumeAtespaceFlag, Name: name}, + }) + if err != nil { + return fmt.Errorf("failed to get external volume %q: %w", name, err) + } + volumes = append(volumes, volume) + } + if len(volumes) == 1 { + return printer.PrintExternalVolumeTo(cmd.OutOrStdout(), volumes[0], outputFmt) + } + return printer.PrintExternalVolumesTo(cmd.OutOrStdout(), volumes, outputFmt) + } + + var volumes []*ateapipb.ExternalVolume + pageToken := "" + for { + resp, err := client.ListExternalVolumes(ctx, &ateapipb.ListExternalVolumesRequest{ + Atespace: externalVolumeAtespaceFlag, PageSize: 1000, PageToken: pageToken, + }) + if err != nil { + return fmt.Errorf("failed to list external volumes: %w", err) + } + volumes = append(volumes, resp.GetExternalVolumes()...) + pageToken = resp.GetNextPageToken() + if pageToken == "" { + break + } + } + return printer.PrintExternalVolumesTo(cmd.OutOrStdout(), volumes, outputFmt) + }, +} + +var createExternalVolumeCmd = &cobra.Command{ + Use: "externalvolume ", + Aliases: []string{"externalvolumes", "ev"}, + Short: "Create an external volume actors can share", + Long: "Create an external volume actors can share.\n\n" + + "Name a storage class with --storage-class to provision a new volume, or\n" + + "supply --volume-id to register a volume that already exists, but not both.", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + trigger, err := parseDeleteTrigger(createExternalVolumeDeleteTriggerFlag) + if err != nil { + return err + } + mode, err := parseAccessMode(createExternalVolumeAccessModeFlag) + if err != nil { + return err + } + ctx := cmd.Context() + client, err := ateclient.NewClient(ctx, kubeconfig, k8sContext, endpoint, tokenFile, traceEnabled) + if err != nil { + return fmt.Errorf("failed to connect to ate-api-server: %w", err) + } + defer client.Close() + + volume, err := client.CreateExternalVolume(ctx, &ateapipb.CreateExternalVolumeRequest{ + ExternalVolume: &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: createExternalVolumeAtespaceFlag, Name: args[0]}, + DeleteTrigger: trigger, + AccessMode: mode, + StorageClassName: createExternalVolumeClassFlag, + Capacity: createExternalVolumeCapacityFlag, + VolumeId: createExternalVolumeVolumeIDFlag, + VolumeType: createExternalVolumeTypeFlag, + VolumeContext: createExternalVolumeContextFlag, + }, + }) + if err != nil { + return fmt.Errorf("failed to create external volume: %w", err) + } + return printer.PrintExternalVolumeTo(cmd.OutOrStdout(), volume, outputFmt) + }, +} + +var updateExternalVolumeCmd = &cobra.Command{ + Use: "externalvolume ", + Aliases: []string{"externalvolumes", "ev"}, + Short: "Change an external volume's delete trigger", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + trigger, err := parseDeleteTrigger(updateExternalVolumeDeleteTriggerFlag) + if err != nil { + return err + } + ctx := cmd.Context() + client, err := ateclient.NewClient(ctx, kubeconfig, k8sContext, endpoint, tokenFile, traceEnabled) + if err != nil { + return fmt.Errorf("failed to connect to ate-api-server: %w", err) + } + defer client.Close() + + ref := &ateapipb.ObjectRef{Atespace: updateExternalVolumeAtespaceFlag, Name: args[0]} + resp, err := updateExternalVolumeDeleteTrigger(ctx, client, ref, trigger) + if err != nil { + return err + } + return printer.PrintExternalVolumeTo(cmd.OutOrStdout(), resp, outputFmt) + }, +} + +var deleteExternalVolumeCmd = &cobra.Command{ + Use: "externalvolume ", + Aliases: []string{"externalvolumes", "ev"}, + Short: "Delete an external volume and its storage", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := cmd.Context() + client, err := ateclient.NewClient(ctx, kubeconfig, k8sContext, endpoint, tokenFile, traceEnabled) + if err != nil { + return fmt.Errorf("failed to connect to ate-api-server: %w", err) + } + defer client.Close() + + _, err = client.DeleteExternalVolume(ctx, &ateapipb.DeleteExternalVolumeRequest{ + ExternalVolume: &ateapipb.ObjectRef{Atespace: deleteExternalVolumeAtespaceFlag, Name: args[0]}, + }) + if err != nil { + return fmt.Errorf("failed to delete external volume: %w", err) + } + fmt.Fprintf(cmd.OutOrStdout(), "external volume %q deleted\n", args[0]) + return nil + }, +} + +type externalVolumeClient interface { + GetExternalVolume(ctx context.Context, in *ateapipb.GetExternalVolumeRequest, opts ...grpc.CallOption) (*ateapipb.ExternalVolume, error) + UpdateExternalVolume(ctx context.Context, in *ateapipb.UpdateExternalVolumeRequest, opts ...grpc.CallOption) (*ateapipb.ExternalVolume, error) +} + +// updateExternalVolumeDeleteTrigger reads the volume first so the update carries +// the uid and version the server requires as preconditions. +func updateExternalVolumeDeleteTrigger(ctx context.Context, client externalVolumeClient, ref *ateapipb.ObjectRef, trigger ateapipb.DeleteTrigger) (*ateapipb.ExternalVolume, error) { + volume, err := client.GetExternalVolume(ctx, &ateapipb.GetExternalVolumeRequest{ExternalVolume: ref}) + if err != nil { + return nil, fmt.Errorf("failed to get external volume %q: %w", ref.GetName(), err) + } + volume.DeleteTrigger = trigger + + resp, err := client.UpdateExternalVolume(ctx, &ateapipb.UpdateExternalVolumeRequest{ExternalVolume: volume}) + if err != nil { + return nil, fmt.Errorf("failed to update external volume: %w", err) + } + return resp, nil +} + +func parseDeleteTrigger(value string) (ateapipb.DeleteTrigger, error) { + switch strings.ToLower(value) { + case "": + return ateapipb.DeleteTrigger_DELETE_TRIGGER_UNSPECIFIED, nil + case "manual": + return ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL, nil + case "last-actor", "lastactor": + return ateapipb.DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR, nil + default: + return ateapipb.DeleteTrigger_DELETE_TRIGGER_UNSPECIFIED, fmt.Errorf("invalid delete trigger %q; must be manual or last-actor", value) + } +} + +func parseAccessMode(value string) (ateapipb.AccessMode, error) { + switch strings.ToLower(value) { + case "": + return ateapipb.AccessMode_ACCESS_MODE_UNSPECIFIED, nil + case "rwo", "readwriteonce": + return ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_ONCE, nil + case "rwx", "readwritemany": + return ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_MANY, nil + default: + return ateapipb.AccessMode_ACCESS_MODE_UNSPECIFIED, fmt.Errorf("invalid access mode %q; must be rwo or rwx", value) + } +} + +func init() { + getExternalVolumesCmd.Flags().StringVarP(&externalVolumeAtespaceFlag, "atespace", "a", "", "Atespace to list/get external volumes in") + getExternalVolumesCmd.Flags().BoolVarP(&externalVolumeAllAtespacesFlag, "all-atespaces", "A", false, "List external volumes across all atespaces") + getCmd.AddCommand(getExternalVolumesCmd) + + createExternalVolumeCmd.Flags().StringVarP(&createExternalVolumeAtespaceFlag, "atespace", "a", "", "Atespace to create the external volume in (required)") + _ = createExternalVolumeCmd.MarkFlagRequired("atespace") + createExternalVolumeCmd.Flags().StringVar(&createExternalVolumeClassFlag, "storage-class", "", "StorageClass to provision the volume from") + createExternalVolumeCmd.Flags().StringVar(&createExternalVolumeCapacityFlag, "capacity", "", "Size to provision, as a Kubernetes quantity (e.g. 10Gi); required with --storage-class") + createExternalVolumeCmd.Flags().StringVar(&createExternalVolumeVolumeIDFlag, "volume-id", "", "Volume ID of a volume that already exists, to register instead of provisioning") + createExternalVolumeCmd.Flags().StringVar(&createExternalVolumeTypeFlag, "volume-type", "", "CSI driver name; required with --volume-id unless --storage-class is set") + createExternalVolumeCmd.Flags().StringToStringVar(&createExternalVolumeContextFlag, "volume-context", nil, "Driver metadata for mounting, as key=value pairs; only valid with --volume-id") + createExternalVolumeCmd.Flags().StringVar(&createExternalVolumeDeleteTriggerFlag, "delete-trigger", "", "What removes the volume: manual or last-actor (default: last-actor when provisioned, manual when registered)") + createExternalVolumeCmd.Flags().StringVar(&createExternalVolumeAccessModeFlag, "access-mode", "", "How many resumed actors may hold the volume: rwo (default) or rwx") + createCmd.AddCommand(createExternalVolumeCmd) + + updateExternalVolumeCmd.Flags().StringVarP(&updateExternalVolumeAtespaceFlag, "atespace", "a", "", "Atespace owning the external volume (required)") + updateExternalVolumeCmd.Flags().StringVar(&updateExternalVolumeDeleteTriggerFlag, "delete-trigger", "", "What removes the volume: manual or last-actor (required)") + _ = updateExternalVolumeCmd.MarkFlagRequired("atespace") + _ = updateExternalVolumeCmd.MarkFlagRequired("delete-trigger") + updateCmd.AddCommand(updateExternalVolumeCmd) + + deleteExternalVolumeCmd.Flags().StringVarP(&deleteExternalVolumeAtespaceFlag, "atespace", "a", "", "Atespace owning the external volume (required)") + _ = deleteExternalVolumeCmd.MarkFlagRequired("atespace") + deleteCmd.AddCommand(deleteExternalVolumeCmd) +} diff --git a/cmd/kubectl-ate/internal/cmd/external_volume_test.go b/cmd/kubectl-ate/internal/cmd/external_volume_test.go new file mode 100644 index 0000000000..7f7ff77108 --- /dev/null +++ b/cmd/kubectl-ate/internal/cmd/external_volume_test.go @@ -0,0 +1,138 @@ +// 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 cmd + +import ( + "context" + "testing" + + "github.com/agent-substrate/substrate/pkg/proto/ateapipb" + "github.com/google/go-cmp/cmp" + "google.golang.org/grpc" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/testing/protocmp" +) + +type fakeExternalVolumeClient struct { + volume *ateapipb.ExternalVolume + + getCalls int + updateReq *ateapipb.UpdateExternalVolumeRequest +} + +func (f *fakeExternalVolumeClient) GetExternalVolume(_ context.Context, _ *ateapipb.GetExternalVolumeRequest, _ ...grpc.CallOption) (*ateapipb.ExternalVolume, error) { + f.getCalls++ + return proto.Clone(f.volume).(*ateapipb.ExternalVolume), nil +} + +func (f *fakeExternalVolumeClient) UpdateExternalVolume(_ context.Context, in *ateapipb.UpdateExternalVolumeRequest, _ ...grpc.CallOption) (*ateapipb.ExternalVolume, error) { + f.updateReq = in + updated := proto.Clone(in.GetExternalVolume()).(*ateapipb.ExternalVolume) + updated.Metadata.Version++ + return updated, nil +} + +func testExternalVolume() *ateapipb.ExternalVolume { + return &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{ + Atespace: "space-1", + Name: "vol-1", + Uid: "8ba9b6ee-2e1a-4c0f-9f4e-2f0a0f1c3d55", + Version: 1, + }, + DeleteTrigger: ateapipb.DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR, + AccessMode: ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_ONCE, + VolumeId: "projects/p/zones/z/disks/substrate-8ba9b6ee", + VolumeType: "pd.csi.storage.gke.io", + Status: &ateapipb.ExternalVolumeStatus{ + State: ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY, + }, + } +} + +func TestUpdateExternalVolumeDeleteTrigger(t *testing.T) { + client := &fakeExternalVolumeClient{volume: testExternalVolume()} + ref := &ateapipb.ObjectRef{Atespace: "space-1", Name: "vol-1"} + want := ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL + + resp, err := updateExternalVolumeDeleteTrigger(context.Background(), client, ref, want) + if err != nil { + t.Fatalf("updateExternalVolumeDeleteTrigger() error = %v", err) + } + + if client.getCalls != 1 { + t.Errorf("GetExternalVolume called %d times, want 1", client.getCalls) + } + + sent := client.updateReq.GetExternalVolume().GetMetadata() + if sent.GetUid() != "8ba9b6ee-2e1a-4c0f-9f4e-2f0a0f1c3d55" || sent.GetVersion() != 1 { + t.Errorf("update sent uid %q version %d, want the values just read", sent.GetUid(), sent.GetVersion()) + } + + wantResp := testExternalVolume() + wantResp.DeleteTrigger = want + wantResp.Metadata.Version = 2 + if diff := cmp.Diff(wantResp, resp, protocmp.Transform()); diff != "" { + t.Errorf("returned external volume mismatch (-want +got):\n%s", diff) + } +} + +func TestParseDeleteTrigger(t *testing.T) { + tests := []struct { + value string + want ateapipb.DeleteTrigger + wantErr bool + }{ + {value: "", want: ateapipb.DeleteTrigger_DELETE_TRIGGER_UNSPECIFIED}, + {value: "manual", want: ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL}, + {value: "Last-Actor", want: ateapipb.DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR}, + {value: "atespace", wantErr: true}, + } + for _, tc := range tests { + t.Run(tc.value, func(t *testing.T) { + got, err := parseDeleteTrigger(tc.value) + if (err != nil) != tc.wantErr { + t.Fatalf("parseDeleteTrigger(%q) error = %v, wantErr %v", tc.value, err, tc.wantErr) + } + if got != tc.want { + t.Errorf("parseDeleteTrigger(%q) = %v, want %v", tc.value, got, tc.want) + } + }) + } +} + +func TestParseAccessMode(t *testing.T) { + tests := []struct { + value string + want ateapipb.AccessMode + wantErr bool + }{ + {value: "", want: ateapipb.AccessMode_ACCESS_MODE_UNSPECIFIED}, + {value: "rwo", want: ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_ONCE}, + {value: "ReadWriteMany", want: ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_MANY}, + {value: "rox", wantErr: true}, + } + for _, tc := range tests { + t.Run(tc.value, func(t *testing.T) { + got, err := parseAccessMode(tc.value) + if (err != nil) != tc.wantErr { + t.Fatalf("parseAccessMode(%q) error = %v, wantErr %v", tc.value, err, tc.wantErr) + } + if got != tc.want { + t.Errorf("parseAccessMode(%q) = %v, want %v", tc.value, got, tc.want) + } + }) + } +} diff --git a/cmd/kubectl-ate/internal/printer/printer.go b/cmd/kubectl-ate/internal/printer/printer.go index 59c3e309fb..6d77ab7e82 100644 --- a/cmd/kubectl-ate/internal/printer/printer.go +++ b/cmd/kubectl-ate/internal/printer/printer.go @@ -385,6 +385,85 @@ func PrintTagTo(out io.Writer, tag *ateapipb.Tag, format string) error { return PrintTagsTo(out, []*ateapipb.Tag{tag}, format) } +// PrintExternalVolumesTo prints external volumes to the provided writer. +func PrintExternalVolumesTo(out io.Writer, volumes []*ateapipb.ExternalVolume, format string) error { + slices.SortFunc(volumes, func(a, b *ateapipb.ExternalVolume) int { + if c := cmp.Compare(a.GetMetadata().GetAtespace(), b.GetMetadata().GetAtespace()); c != 0 { + return c + } + return cmp.Compare(a.GetMetadata().GetName(), b.GetMetadata().GetName()) + }) + switch format { + case "json", "yaml": + return printProto(out, &ateapipb.ListExternalVolumesResponse{ExternalVolumes: volumes}, format) + case "table": + w := tabwriter.NewWriter(out, 0, 0, 3, ' ', 0) + fmt.Fprintln(w, "ATESPACE\tNAME\tSTATE\tVOLUME TYPE\tVOLUME ID\tACCESS MODE\tDELETE TRIGGER\tREFS\tAGE") + for _, volume := range volumes { + volumeType, volumeID := "", "" + if volume.GetVolumeId() != "" { + volumeType, volumeID = volume.GetVolumeType(), volume.GetVolumeId() + } + fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", + volume.GetMetadata().GetAtespace(), volume.GetMetadata().GetName(), + externalVolumeState(volume), volumeType, volumeID, + accessModeLabel(volume.GetAccessMode()), deleteTriggerLabel(volume.GetDeleteTrigger()), + externalVolumeRefs(volume), formatAge(volume.GetMetadata().GetCreateTime())) + } + return w.Flush() + default: + return fmt.Errorf("unsupported format %q", format) + } +} + +func externalVolumeState(volume *ateapipb.ExternalVolume) string { + if volume.GetStatus().GetState() != ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY { + return "Pending" + } + return "Ready" +} + +func accessModeLabel(mode ateapipb.AccessMode) string { + switch mode { + case ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_ONCE: + return "RWO" + case ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_MANY: + return "RWX" + default: + return "" + } +} + +func deleteTriggerLabel(trigger ateapipb.DeleteTrigger) string { + switch trigger { + case ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL: + return "Manual" + case ateapipb.DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR: + return "LastActor" + default: + return "" + } +} + +// externalVolumeRefs renders the reference count as active/total. +func externalVolumeRefs(volume *ateapipb.ExternalVolume) string { + active := 0 + for _, ref := range volume.GetStatus().GetRefs() { + if ref.GetActive() { + active++ + } + } + return fmt.Sprintf("%d/%d", active, len(volume.GetStatus().GetRefs())) +} + +// PrintExternalVolumeTo prints a single external volume to the provided writer. +func PrintExternalVolumeTo(out io.Writer, volume *ateapipb.ExternalVolume, format string) error { + if format == "json" || format == "yaml" { + return printProto(out, volume, format) + } + return PrintExternalVolumesTo(out, []*ateapipb.ExternalVolume{volume}, format) +} + func sortAtespaces(atespaces []*ateapipb.Atespace) { slices.SortFunc(atespaces, func(a, b *ateapipb.Atespace) int { return cmp.Compare(a.GetMetadata().GetName(), b.GetMetadata().GetName()) diff --git a/cmd/kubectl-ate/internal/printer/printer_test.go b/cmd/kubectl-ate/internal/printer/printer_test.go index 70612bdeaa..610d69e70b 100644 --- a/cmd/kubectl-ate/internal/printer/printer_test.go +++ b/cmd/kubectl-ate/internal/printer/printer_test.go @@ -708,6 +708,116 @@ func TestPrintTagTo_YAML(t *testing.T) { } } +func TestPrintExternalVolumesTo_Table(t *testing.T) { + now := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC) + pinNow(t, now) + + var buf bytes.Buffer + volumes := []*ateapipb.ExternalVolume{ + { + Metadata: &ateapipb.ResourceMetadata{ + Atespace: "team-a", + Name: "shared", + CreateTime: timestamppb.New(now.Add(-5 * time.Minute)), + }, + DeleteTrigger: ateapipb.DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR, + AccessMode: ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_ONCE, + VolumeId: "projects/p/zones/z/disks/substrate-1", + VolumeType: "pd.csi.storage.gke.io", + Status: &ateapipb.ExternalVolumeStatus{ + State: ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY, + Refs: []*ateapipb.ActorRef{ + {ActorUid: "uid-1", ActorName: "producer", Active: true}, + {ActorUid: "uid-2", ActorName: "consumer"}, + }, + }, + }, + { + Metadata: &ateapipb.ResourceMetadata{ + Atespace: "team-a", + Name: "adopted", + CreateTime: timestamppb.New(now.Add(-5 * time.Hour)), + }, + DeleteTrigger: ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL, + AccessMode: ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_ONCE, + VolumeId: "projects/p/zones/z/disks/preexisting", + VolumeType: "pd.csi.storage.gke.io", + Status: &ateapipb.ExternalVolumeStatus{ + State: ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY, + }, + }, + { + Metadata: &ateapipb.ResourceMetadata{ + Atespace: "team-a", + Name: "stranded", + CreateTime: timestamppb.New(now.Add(-30 * time.Second)), + }, + DeleteTrigger: ateapipb.DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR, + AccessMode: ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_ONCE, + Status: &ateapipb.ExternalVolumeStatus{ + State: ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_PENDING, + }, + }, + } + + if err := PrintExternalVolumesTo(&buf, volumes, "table"); err != nil { + t.Fatalf("unexpected error: %v", err) + } + + expected := `ATESPACE NAME STATE VOLUME TYPE VOLUME ID ACCESS MODE DELETE TRIGGER REFS AGE +team-a adopted Ready pd.csi.storage.gke.io projects/p/zones/z/disks/preexisting RWO Manual 0/0 5h +team-a shared Ready pd.csi.storage.gke.io projects/p/zones/z/disks/substrate-1 RWO LastActor 1/2 5m +team-a stranded Pending RWO LastActor 0/0 30s +` + if diff := cmp.Diff(expected, buf.String()); diff != "" { + t.Errorf("output mismatch (-want +got):\n%s", diff) + } +} + +func TestPrintExternalVolumesTo_Invalid(t *testing.T) { + var buf bytes.Buffer + if err := PrintExternalVolumesTo(&buf, nil, "xml"); err == nil { + t.Errorf("expected error for invalid format, got nil") + } +} + +func TestPrintExternalVolumeTo_JSON(t *testing.T) { + var buf bytes.Buffer + volume := &ateapipb.ExternalVolume{Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "shared"}} + + if err := PrintExternalVolumeTo(&buf, volume, "json"); err != nil { + t.Fatalf("unexpected error: %v", err) + } + + expected := `{ + "metadata": { + "atespace": "team-a", + "name": "shared" + } +} +` + if diff := cmp.Diff(expected, buf.String()); diff != "" { + t.Errorf("output mismatch (-want +got):\n%s", diff) + } +} + +func TestPrintExternalVolumeTo_YAML(t *testing.T) { + var buf bytes.Buffer + volume := &ateapipb.ExternalVolume{Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "shared"}} + + if err := PrintExternalVolumeTo(&buf, volume, "yaml"); err != nil { + t.Fatalf("unexpected error: %v", err) + } + + expected := `metadata: + atespace: team-a + name: shared +` + if diff := cmp.Diff(expected, buf.String()); diff != "" { + t.Errorf("output mismatch (-want +got):\n%s", diff) + } +} + func TestPrintAtespacesTo_Table(t *testing.T) { now := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC) pinNow(t, now) diff --git a/internal/resources/resourceref.go b/internal/resources/resourceref.go index a14d079d75..f609549157 100644 --- a/internal/resources/resourceref.go +++ b/internal/resources/resourceref.go @@ -107,3 +107,20 @@ func TagRefFromTag(t *ateapipb.Tag) TagRef { Name: t.GetMetadata().GetName(), } } + +// ExternalVolumeRef identifies an ExternalVolume by the (atespace, name). +type ExternalVolumeRef = ResourceRef[*ateapipb.ExternalVolume] + +// ExternalVolumeRefFromObjectRef converts an ObjectRef to an ExternalVolumeRef. +func ExternalVolumeRefFromObjectRef(ref *ateapipb.ObjectRef) ExternalVolumeRef { + return resourceRefFromObjectRef[*ateapipb.ExternalVolume](ref) +} + +// ExternalVolumeRefFromExternalVolume returns the reference addressing the +// given volume. +func ExternalVolumeRefFromExternalVolume(v *ateapipb.ExternalVolume) ExternalVolumeRef { + return ExternalVolumeRef{ + Atespace: v.GetMetadata().GetAtespace(), + Name: v.GetMetadata().GetName(), + } +} diff --git a/pkg/proto/ateapipb/ateapi.pb.go b/pkg/proto/ateapipb/ateapi.pb.go index d9de88106f..f253e89184 100644 --- a/pkg/proto/ateapipb/ateapi.pb.go +++ b/pkg/proto/ateapipb/ateapi.pb.go @@ -378,6 +378,163 @@ func (ActorState) EnumDescriptor() ([]byte, []int) { return file_ateapi_proto_rawDescGZIP(), []int{5} } +// DeleteTrigger is what removes an ExternalVolume and its storage. +// TODO: add an ATESPACE trigger that removes the volume with its atespace. +type DeleteTrigger int32 + +const ( + DeleteTrigger_DELETE_TRIGGER_UNSPECIFIED DeleteTrigger = 0 + // Only an explicit DeleteExternalVolume removes the volume. + DeleteTrigger_DELETE_TRIGGER_MANUAL DeleteTrigger = 1 + // The volume is removed when the last actor referencing it is deleted. + DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR DeleteTrigger = 2 +) + +// Enum value maps for DeleteTrigger. +var ( + DeleteTrigger_name = map[int32]string{ + 0: "DELETE_TRIGGER_UNSPECIFIED", + 1: "DELETE_TRIGGER_MANUAL", + 2: "DELETE_TRIGGER_LAST_ACTOR", + } + DeleteTrigger_value = map[string]int32{ + "DELETE_TRIGGER_UNSPECIFIED": 0, + "DELETE_TRIGGER_MANUAL": 1, + "DELETE_TRIGGER_LAST_ACTOR": 2, + } +) + +func (x DeleteTrigger) Enum() *DeleteTrigger { + p := new(DeleteTrigger) + *p = x + return p +} + +func (x DeleteTrigger) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (DeleteTrigger) Descriptor() protoreflect.EnumDescriptor { + return file_ateapi_proto_enumTypes[6].Descriptor() +} + +func (DeleteTrigger) Type() protoreflect.EnumType { + return &file_ateapi_proto_enumTypes[6] +} + +func (x DeleteTrigger) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use DeleteTrigger.Descriptor instead. +func (DeleteTrigger) EnumDescriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{6} +} + +// AccessMode is how many resumed actors may hold the volume at once. +type AccessMode int32 + +const ( + AccessMode_ACCESS_MODE_UNSPECIFIED AccessMode = 0 + // At most one resumed actor holds the volume. + AccessMode_ACCESS_MODE_READ_WRITE_ONCE AccessMode = 1 + // Any number of resumed actors hold the volume, on any node. + AccessMode_ACCESS_MODE_READ_WRITE_MANY AccessMode = 2 +) + +// Enum value maps for AccessMode. +var ( + AccessMode_name = map[int32]string{ + 0: "ACCESS_MODE_UNSPECIFIED", + 1: "ACCESS_MODE_READ_WRITE_ONCE", + 2: "ACCESS_MODE_READ_WRITE_MANY", + } + AccessMode_value = map[string]int32{ + "ACCESS_MODE_UNSPECIFIED": 0, + "ACCESS_MODE_READ_WRITE_ONCE": 1, + "ACCESS_MODE_READ_WRITE_MANY": 2, + } +) + +func (x AccessMode) Enum() *AccessMode { + p := new(AccessMode) + *p = x + return p +} + +func (x AccessMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AccessMode) Descriptor() protoreflect.EnumDescriptor { + return file_ateapi_proto_enumTypes[7].Descriptor() +} + +func (AccessMode) Type() protoreflect.EnumType { + return &file_ateapi_proto_enumTypes[7] +} + +func (x AccessMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AccessMode.Descriptor instead. +func (AccessMode) EnumDescriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{7} +} + +// ExternalVolumeState is where an ExternalVolume is in its own lifecycle. +type ExternalVolumeState int32 + +const ( + ExternalVolumeState_EXTERNAL_VOLUME_STATE_UNSPECIFIED ExternalVolumeState = 0 + // The name is reserved but no volume handle is known yet. + ExternalVolumeState_EXTERNAL_VOLUME_STATE_PENDING ExternalVolumeState = 1 + // The volume has a handle and can be referenced. + ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY ExternalVolumeState = 2 +) + +// Enum value maps for ExternalVolumeState. +var ( + ExternalVolumeState_name = map[int32]string{ + 0: "EXTERNAL_VOLUME_STATE_UNSPECIFIED", + 1: "EXTERNAL_VOLUME_STATE_PENDING", + 2: "EXTERNAL_VOLUME_STATE_READY", + } + ExternalVolumeState_value = map[string]int32{ + "EXTERNAL_VOLUME_STATE_UNSPECIFIED": 0, + "EXTERNAL_VOLUME_STATE_PENDING": 1, + "EXTERNAL_VOLUME_STATE_READY": 2, + } +) + +func (x ExternalVolumeState) Enum() *ExternalVolumeState { + p := new(ExternalVolumeState) + *p = x + return p +} + +func (x ExternalVolumeState) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ExternalVolumeState) Descriptor() protoreflect.EnumDescriptor { + return file_ateapi_proto_enumTypes[8].Descriptor() +} + +func (ExternalVolumeState) Type() protoreflect.EnumType { + return &file_ateapi_proto_enumTypes[8] +} + +func (x ExternalVolumeState) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ExternalVolumeState.Descriptor instead. +func (ExternalVolumeState) EnumDescriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{8} +} + // SandboxClass selects the sandbox runtime family. Snapshots are not portable // across classes. type SandboxClass int32 @@ -413,11 +570,11 @@ func (x SandboxClass) String() string { } func (SandboxClass) Descriptor() protoreflect.EnumDescriptor { - return file_ateapi_proto_enumTypes[6].Descriptor() + return file_ateapi_proto_enumTypes[9].Descriptor() } func (SandboxClass) Type() protoreflect.EnumType { - return &file_ateapi_proto_enumTypes[6] + return &file_ateapi_proto_enumTypes[9] } func (x SandboxClass) Number() protoreflect.EnumNumber { @@ -426,7 +583,7 @@ func (x SandboxClass) Number() protoreflect.EnumNumber { // Deprecated: Use SandboxClass.Descriptor instead. func (SandboxClass) EnumDescriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{6} + return file_ateapi_proto_rawDescGZIP(), []int{9} } // ActorMetadataField selects one identity field of the actor. @@ -466,11 +623,11 @@ func (x ActorMetadataField) String() string { } func (ActorMetadataField) Descriptor() protoreflect.EnumDescriptor { - return file_ateapi_proto_enumTypes[7].Descriptor() + return file_ateapi_proto_enumTypes[10].Descriptor() } func (ActorMetadataField) Type() protoreflect.EnumType { - return &file_ateapi_proto_enumTypes[7] + return &file_ateapi_proto_enumTypes[10] } func (x ActorMetadataField) Number() protoreflect.EnumNumber { @@ -479,7 +636,7 @@ func (x ActorMetadataField) Number() protoreflect.EnumNumber { // Deprecated: Use ActorMetadataField.Descriptor instead. func (ActorMetadataField) EnumDescriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{7} + return file_ateapi_proto_rawDescGZIP(), []int{10} } type WorkerState int32 @@ -517,11 +674,11 @@ func (x WorkerState) String() string { } func (WorkerState) Descriptor() protoreflect.EnumDescriptor { - return file_ateapi_proto_enumTypes[8].Descriptor() + return file_ateapi_proto_enumTypes[11].Descriptor() } func (WorkerState) Type() protoreflect.EnumType { - return &file_ateapi_proto_enumTypes[8] + return &file_ateapi_proto_enumTypes[11] } func (x WorkerState) Number() protoreflect.EnumNumber { @@ -530,7 +687,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_ateapi_proto_rawDescGZIP(), []int{11} } // Status is the volume's lifecycle state in the storage system. @@ -573,11 +730,11 @@ func (x ActorVolumeStatus_Status) String() string { } func (ActorVolumeStatus_Status) Descriptor() protoreflect.EnumDescriptor { - return file_ateapi_proto_enumTypes[9].Descriptor() + return file_ateapi_proto_enumTypes[12].Descriptor() } func (ActorVolumeStatus_Status) Type() protoreflect.EnumType { - return &file_ateapi_proto_enumTypes[9] + return &file_ateapi_proto_enumTypes[12] } func (x ActorVolumeStatus_Status) Number() protoreflect.EnumNumber { @@ -2535,33 +2692,99 @@ func (x *Tag) GetSourceActor() *ObjectRef { return nil } -// Atespace is the isolation boundary an Actor is created into. Global-scoped: -// metadata.atespace is always empty; the atespace's identity is metadata.name. -type Atespace struct { +// ExternalVolume is an atespace-scoped CSI volume whose lifetime is independent +// of any actor. Identity is (atespace, name); the storage-level ID is derived +// from the record's UID. +type ExternalVolume struct { state protoimpl.MessageState `protogen:"open.v1"` - // Common resource metadata: name, uid, version, timestamps. + // Common resource metadata: atespace, name, uid, version, timestamps. // // +k8s:required - // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix - Metadata *ResourceMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + // +k8s:subfield(atespace)=+k8s:required + Metadata *ResourceMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + // delete_trigger decides what removes the volume. Defaults to LAST_ACTOR when + // provisioned and MANUAL when registered. + // + // +k8s:optional + // +k8s:minimum=1 + // +k8s:maximum=2 # keep this in sync with the DeleteTrigger enum + // +k8s:mutable + DeleteTrigger DeleteTrigger `protobuf:"varint,2,opt,name=delete_trigger,json=deleteTrigger,proto3,enum=ateapi.DeleteTrigger" json:"delete_trigger,omitempty"` + // storage_class_name names the StorageClass to provision from, or documents + // the class of a registered volume. + // + // +k8s:optional + // +k8s:format=k8s-long-name + // +k8s:update=NoModify + // +k8s:update=NoUnset + StorageClassName string `protobuf:"bytes,3,opt,name=storage_class_name,json=storageClassName,proto3" json:"storage_class_name,omitempty"` + // volume_id is the storage system's volume ID. Supplied to register an + // existing volume, otherwise stamped once provisioning completes. Bounded and + // checked for control characters only. + // + // +k8s:optional + // +k8s:maxLength=256 + // +k8s:update=NoModify + // +k8s:update=NoUnset + // +k8s:customValidation # no control characters + VolumeId string `protobuf:"bytes,4,opt,name=volume_id,json=volumeId,proto3" json:"volume_id,omitempty"` + // volume_type is the CSI driver name. Required alongside volume_id when no + // StorageClass is named; otherwise taken from the class's provisioner. + // + // +k8s:optional + // +k8s:maxLength=253 + // +k8s:update=NoModify + // +k8s:update=NoUnset + // +k8s:customValidation + VolumeType string `protobuf:"bytes,5,opt,name=volume_type,json=volumeType,proto3" json:"volume_type,omitempty"` + // volume_context is driver metadata needed by the node plugin for mounting. + // Attachment metadata is per-node and deliberately not recorded here. + // + // +k8s:optional + // +k8s:maxProperties=32 + // +k8s:eachKey=+k8s:maxLength=128 + // +k8s:eachVal=+k8s:maxLength=256 + VolumeContext map[string]string `protobuf:"bytes,6,rep,name=volume_context,json=volumeContext,proto3" json:"volume_context,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // status is set by the control plane; it is ignored on write. + // + // +k8s:optional + Status *ExternalVolumeStatus `protobuf:"bytes,7,opt,name=status,proto3" json:"status,omitempty"` + // capacity to provision, as a Kubernetes resource.Quantity string (e.g. + // "10Gi"). Required when provisioning, forbidden alongside volume_id. + // + // +k8s:optional + // +k8s:maxLength=64 + // +k8s:update=NoModify + // +k8s:update=NoUnset + // +k8s:customValidation # must parse as a resource.Quantity + Capacity string `protobuf:"bytes,8,opt,name=capacity,proto3" json:"capacity,omitempty"` + // access_mode is fixed at create and defaults to READ_WRITE_ONCE. + // TODO: accept READ_WRITE_MANY once concurrent holders are supported. + // + // +k8s:optional + // +k8s:minimum=1 + // +k8s:maximum=2 # keep this in sync with the AccessMode enum + // +k8s:update=NoModify + // +k8s:update=NoUnset + AccessMode AccessMode `protobuf:"varint,9,opt,name=access_mode,json=accessMode,proto3,enum=ateapi.AccessMode" json:"access_mode,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Atespace) Reset() { - *x = Atespace{} +func (x *ExternalVolume) Reset() { + *x = ExternalVolume{} mi := &file_ateapi_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Atespace) String() string { +func (x *ExternalVolume) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Atespace) ProtoMessage() {} +func (*ExternalVolume) ProtoMessage() {} -func (x *Atespace) ProtoReflect() protoreflect.Message { +func (x *ExternalVolume) ProtoReflect() protoreflect.Message { mi := &file_ateapi_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2573,53 +2796,109 @@ func (x *Atespace) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Atespace.ProtoReflect.Descriptor instead. -func (*Atespace) Descriptor() ([]byte, []int) { +// Deprecated: Use ExternalVolume.ProtoReflect.Descriptor instead. +func (*ExternalVolume) Descriptor() ([]byte, []int) { return file_ateapi_proto_rawDescGZIP(), []int{23} } -func (x *Atespace) GetMetadata() *ResourceMetadata { +func (x *ExternalVolume) GetMetadata() *ResourceMetadata { if x != nil { return x.Metadata } return nil } -// ObjectRef references a Substrate resource by its atespace and name. -type ObjectRef struct { +func (x *ExternalVolume) GetDeleteTrigger() DeleteTrigger { + if x != nil { + return x.DeleteTrigger + } + return DeleteTrigger_DELETE_TRIGGER_UNSPECIFIED +} + +func (x *ExternalVolume) GetStorageClassName() string { + if x != nil { + return x.StorageClassName + } + return "" +} + +func (x *ExternalVolume) GetVolumeId() string { + if x != nil { + return x.VolumeId + } + return "" +} + +func (x *ExternalVolume) GetVolumeType() string { + if x != nil { + return x.VolumeType + } + return "" +} + +func (x *ExternalVolume) GetVolumeContext() map[string]string { + if x != nil { + return x.VolumeContext + } + return nil +} + +func (x *ExternalVolume) GetStatus() *ExternalVolumeStatus { + if x != nil { + return x.Status + } + return nil +} + +func (x *ExternalVolume) GetCapacity() string { + if x != nil { + return x.Capacity + } + return "" +} + +func (x *ExternalVolume) GetAccessMode() AccessMode { + if x != nil { + return x.AccessMode + } + return AccessMode_ACCESS_MODE_UNSPECIFIED +} + +// ExternalVolumeStatus is the part of an ExternalVolume the control plane owns. +type ExternalVolumeStatus struct { state protoimpl.MessageState `protogen:"open.v1"` - // The atespace of the referenced resource. This field should be empty if the - // target resource is global-scoped, but references to objects in the same - // atespace as the referrer must still populate this field. + // state is where the volume is in its lifecycle. // - // References to atespaced resources should add `+k8s:subfield(atespace)=+k8s:required` - // References to non-atespaced resources should add `+k8s:subfield(atespace)=+k8s:forbidden` // +k8s:optional - // +k8s:format=k8s-short-name - Atespace string `protobuf:"bytes,1,opt,name=atespace,proto3" json:"atespace,omitempty"` - // The name of the referenced resource. This field is required. + // +k8s:minimum=1 + // +k8s:maximum=2 # keep this in sync with the ExternalVolumeState enum + State ExternalVolumeState `protobuf:"varint,1,opt,name=state,proto3,enum=ateapi.ExternalVolumeState" json:"state,omitempty"` + // refs are the actors referencing the volume, resumed or not. + // TODO: move references to their own table before lifting the bound. // - // +k8s:required - // +k8s:format=k8s-short-name - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // +k8s:optional + // +k8s:maxItems=256 + // +k8s:listType=map + // +k8s:listMapKey=actor_uid + Refs []*ActorRef `protobuf:"bytes,2,rep,name=refs,proto3" json:"refs,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ObjectRef) Reset() { - *x = ObjectRef{} +func (x *ExternalVolumeStatus) Reset() { + *x = ExternalVolumeStatus{} mi := &file_ateapi_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ObjectRef) String() string { +func (x *ExternalVolumeStatus) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ObjectRef) ProtoMessage() {} +func (*ExternalVolumeStatus) ProtoMessage() {} -func (x *ObjectRef) ProtoReflect() protoreflect.Message { +func (x *ExternalVolumeStatus) ProtoReflect() protoreflect.Message { mi := &file_ateapi_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2631,53 +2910,240 @@ func (x *ObjectRef) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ObjectRef.ProtoReflect.Descriptor instead. -func (*ObjectRef) Descriptor() ([]byte, []int) { +// Deprecated: Use ExternalVolumeStatus.ProtoReflect.Descriptor instead. +func (*ExternalVolumeStatus) Descriptor() ([]byte, []int) { return file_ateapi_proto_rawDescGZIP(), []int{24} } -func (x *ObjectRef) GetAtespace() string { +func (x *ExternalVolumeStatus) GetState() ExternalVolumeState { if x != nil { - return x.Atespace + return x.State } - return "" + return ExternalVolumeState_EXTERNAL_VOLUME_STATE_UNSPECIFIED } -func (x *ObjectRef) GetName() string { +func (x *ExternalVolumeStatus) GetRefs() []*ActorRef { if x != nil { - return x.Name + return x.Refs } - return "" + return nil } -type ActorTemplate struct { +// ActorRef is one actor's reference to an ExternalVolume. +type ActorRef struct { state protoimpl.MessageState `protogen:"open.v1"` - // Common resource metadata: atespace, name, uid, version, timestamps. + // actor_uid identifies the actor, so a recreated namesake does not inherit it. // // +k8s:required - // +k8s:subfield(atespace)=+k8s:required - Metadata *ResourceMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` - // worker_selector restricts which worker pools actors from this template - // may use. + // +k8s:maxLength=253 + ActorUid string `protobuf:"bytes,1,opt,name=actor_uid,json=actorUid,proto3" json:"actor_uid,omitempty"` + // actor_name is the actor's name, for readers. // - // +k8s:optional - WorkerSelector *Selector `protobuf:"bytes,2,opt,name=worker_selector,json=workerSelector,proto3" json:"worker_selector,omitempty"` - // +k8s:required # at least one container - // +k8s:maxItems=10 - // +k8s:listType=map - // +k8s:listMapKey=name - Containers []*Container `protobuf:"bytes,3,rep,name=containers,proto3" json:"containers,omitempty"` - // +k8s:optional - // +k8s:maxItems=32 - // +k8s:listType=map - // +k8s:listMapKey=name - Volumes []*Volume `protobuf:"bytes,4,rep,name=volumes,proto3" json:"volumes,omitempty"` // +k8s:required - SnapshotConfig *SnapshotConfig `protobuf:"bytes,5,opt,name=snapshot_config,json=snapshotConfig,proto3" json:"snapshot_config,omitempty"` - // sandbox_config selects the sandbox runtime this version's actors run on. + // +k8s:format=k8s-short-name + ActorName string `protobuf:"bytes,2,opt,name=actor_name,json=actorName,proto3" json:"actor_name,omitempty"` + // active is true while the actor is resumed and holds the volume mounted. // - // +k8s:required - SandboxConfig *SandboxConfig `protobuf:"bytes,6,opt,name=sandbox_config,json=sandboxConfig,proto3" json:"sandbox_config,omitempty"` + // +k8s:optional + Active bool `protobuf:"varint,3,opt,name=active,proto3" json:"active,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ActorRef) Reset() { + *x = ActorRef{} + mi := &file_ateapi_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ActorRef) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActorRef) ProtoMessage() {} + +func (x *ActorRef) ProtoReflect() protoreflect.Message { + mi := &file_ateapi_proto_msgTypes[25] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ActorRef.ProtoReflect.Descriptor instead. +func (*ActorRef) Descriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{25} +} + +func (x *ActorRef) GetActorUid() string { + if x != nil { + return x.ActorUid + } + return "" +} + +func (x *ActorRef) GetActorName() string { + if x != nil { + return x.ActorName + } + return "" +} + +func (x *ActorRef) GetActive() bool { + if x != nil { + return x.Active + } + return false +} + +// Atespace is the isolation boundary an Actor is created into. Global-scoped: +// metadata.atespace is always empty; the atespace's identity is metadata.name. +type Atespace struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Common resource metadata: name, uid, version, timestamps. + // + // +k8s:required + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + Metadata *ResourceMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Atespace) Reset() { + *x = Atespace{} + mi := &file_ateapi_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Atespace) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Atespace) ProtoMessage() {} + +func (x *Atespace) ProtoReflect() protoreflect.Message { + mi := &file_ateapi_proto_msgTypes[26] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Atespace.ProtoReflect.Descriptor instead. +func (*Atespace) Descriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{26} +} + +func (x *Atespace) GetMetadata() *ResourceMetadata { + if x != nil { + return x.Metadata + } + return nil +} + +// ObjectRef references a Substrate resource by its atespace and name. +type ObjectRef struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The atespace of the referenced resource. This field should be empty if the + // target resource is global-scoped, but references to objects in the same + // atespace as the referrer must still populate this field. + // + // References to atespaced resources should add `+k8s:subfield(atespace)=+k8s:required` + // References to non-atespaced resources should add `+k8s:subfield(atespace)=+k8s:forbidden` + // +k8s:optional + // +k8s:format=k8s-short-name + Atespace string `protobuf:"bytes,1,opt,name=atespace,proto3" json:"atespace,omitempty"` + // The name of the referenced resource. This field is required. + // + // +k8s:required + // +k8s:format=k8s-short-name + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ObjectRef) Reset() { + *x = ObjectRef{} + mi := &file_ateapi_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ObjectRef) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ObjectRef) ProtoMessage() {} + +func (x *ObjectRef) ProtoReflect() protoreflect.Message { + mi := &file_ateapi_proto_msgTypes[27] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ObjectRef.ProtoReflect.Descriptor instead. +func (*ObjectRef) Descriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{27} +} + +func (x *ObjectRef) GetAtespace() string { + if x != nil { + return x.Atespace + } + return "" +} + +func (x *ObjectRef) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type ActorTemplate struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Common resource metadata: atespace, name, uid, version, timestamps. + // + // +k8s:required + // +k8s:subfield(atespace)=+k8s:required + Metadata *ResourceMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + // worker_selector restricts which worker pools actors from this template + // may use. + // + // +k8s:optional + WorkerSelector *Selector `protobuf:"bytes,2,opt,name=worker_selector,json=workerSelector,proto3" json:"worker_selector,omitempty"` + // +k8s:required # at least one container + // +k8s:maxItems=10 + // +k8s:listType=map + // +k8s:listMapKey=name + Containers []*Container `protobuf:"bytes,3,rep,name=containers,proto3" json:"containers,omitempty"` + // +k8s:optional + // +k8s:maxItems=32 + // +k8s:listType=map + // +k8s:listMapKey=name + Volumes []*Volume `protobuf:"bytes,4,rep,name=volumes,proto3" json:"volumes,omitempty"` + // +k8s:required + SnapshotConfig *SnapshotConfig `protobuf:"bytes,5,opt,name=snapshot_config,json=snapshotConfig,proto3" json:"snapshot_config,omitempty"` + // sandbox_config selects the sandbox runtime this version's actors run on. + // + // +k8s:required + SandboxConfig *SandboxConfig `protobuf:"bytes,6,opt,name=sandbox_config,json=sandboxConfig,proto3" json:"sandbox_config,omitempty"` // Resource usage configuration. // // +k8s:optional @@ -2690,7 +3156,7 @@ type ActorTemplate struct { func (x *ActorTemplate) Reset() { *x = ActorTemplate{} - mi := &file_ateapi_proto_msgTypes[25] + mi := &file_ateapi_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2702,7 +3168,7 @@ func (x *ActorTemplate) String() string { func (*ActorTemplate) ProtoMessage() {} func (x *ActorTemplate) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[25] + mi := &file_ateapi_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2715,7 +3181,7 @@ func (x *ActorTemplate) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorTemplate.ProtoReflect.Descriptor instead. func (*ActorTemplate) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{25} + return file_ateapi_proto_rawDescGZIP(), []int{28} } func (x *ActorTemplate) GetMetadata() *ResourceMetadata { @@ -2791,7 +3257,7 @@ type Resources struct { func (x *Resources) Reset() { *x = Resources{} - mi := &file_ateapi_proto_msgTypes[26] + mi := &file_ateapi_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2803,7 +3269,7 @@ func (x *Resources) String() string { func (*Resources) ProtoMessage() {} func (x *Resources) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[26] + mi := &file_ateapi_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2816,7 +3282,7 @@ func (x *Resources) ProtoReflect() protoreflect.Message { // Deprecated: Use Resources.ProtoReflect.Descriptor instead. func (*Resources) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{26} + return file_ateapi_proto_rawDescGZIP(), []int{29} } func (x *Resources) GetLimits() []*Limits { @@ -2844,7 +3310,7 @@ type Limits struct { func (x *Limits) Reset() { *x = Limits{} - mi := &file_ateapi_proto_msgTypes[27] + mi := &file_ateapi_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2856,7 +3322,7 @@ func (x *Limits) String() string { func (*Limits) ProtoMessage() {} func (x *Limits) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[27] + mi := &file_ateapi_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2869,7 +3335,7 @@ func (x *Limits) ProtoReflect() protoreflect.Message { // Deprecated: Use Limits.ProtoReflect.Descriptor instead. func (*Limits) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{27} + return file_ateapi_proto_rawDescGZIP(), []int{30} } func (x *Limits) GetName() string { @@ -2910,7 +3376,7 @@ type GoldenSnapshotStatus struct { func (x *GoldenSnapshotStatus) Reset() { *x = GoldenSnapshotStatus{} - mi := &file_ateapi_proto_msgTypes[28] + mi := &file_ateapi_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2922,7 +3388,7 @@ func (x *GoldenSnapshotStatus) String() string { func (*GoldenSnapshotStatus) ProtoMessage() {} func (x *GoldenSnapshotStatus) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[28] + mi := &file_ateapi_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2935,7 +3401,7 @@ func (x *GoldenSnapshotStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use GoldenSnapshotStatus.ProtoReflect.Descriptor instead. func (*GoldenSnapshotStatus) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{28} + return file_ateapi_proto_rawDescGZIP(), []int{31} } func (x *GoldenSnapshotStatus) GetGoldenTag() *ObjectRef { @@ -2969,7 +3435,7 @@ type ActorTemplateStatus struct { func (x *ActorTemplateStatus) Reset() { *x = ActorTemplateStatus{} - mi := &file_ateapi_proto_msgTypes[29] + mi := &file_ateapi_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2981,7 +3447,7 @@ func (x *ActorTemplateStatus) String() string { func (*ActorTemplateStatus) ProtoMessage() {} func (x *ActorTemplateStatus) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[29] + mi := &file_ateapi_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2994,7 +3460,7 @@ func (x *ActorTemplateStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorTemplateStatus.ProtoReflect.Descriptor instead. func (*ActorTemplateStatus) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{29} + return file_ateapi_proto_rawDescGZIP(), []int{32} } func (x *ActorTemplateStatus) GetGoldenSnapshotStatus() *GoldenSnapshotStatus { @@ -3025,7 +3491,7 @@ type SandboxConfig struct { func (x *SandboxConfig) Reset() { *x = SandboxConfig{} - mi := &file_ateapi_proto_msgTypes[30] + mi := &file_ateapi_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3037,7 +3503,7 @@ func (x *SandboxConfig) String() string { func (*SandboxConfig) ProtoMessage() {} func (x *SandboxConfig) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[30] + mi := &file_ateapi_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3050,7 +3516,7 @@ func (x *SandboxConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxConfig.ProtoReflect.Descriptor instead. func (*SandboxConfig) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{30} + return file_ateapi_proto_rawDescGZIP(), []int{33} } func (x *SandboxConfig) GetSandboxClass() SandboxClass { @@ -3098,7 +3564,7 @@ type SnapshotConfig struct { func (x *SnapshotConfig) Reset() { *x = SnapshotConfig{} - mi := &file_ateapi_proto_msgTypes[31] + mi := &file_ateapi_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3110,7 +3576,7 @@ func (x *SnapshotConfig) String() string { func (*SnapshotConfig) ProtoMessage() {} func (x *SnapshotConfig) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[31] + mi := &file_ateapi_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3123,7 +3589,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_ateapi_proto_rawDescGZIP(), []int{34} } func (x *SnapshotConfig) GetStorageLocation() string { @@ -3210,7 +3676,7 @@ type Container struct { func (x *Container) Reset() { *x = Container{} - mi := &file_ateapi_proto_msgTypes[32] + mi := &file_ateapi_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3222,7 +3688,7 @@ func (x *Container) String() string { func (*Container) ProtoMessage() {} func (x *Container) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[32] + mi := &file_ateapi_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3235,7 +3701,7 @@ func (x *Container) ProtoReflect() protoreflect.Message { // Deprecated: Use Container.ProtoReflect.Descriptor instead. func (*Container) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{32} + return file_ateapi_proto_rawDescGZIP(), []int{35} } func (x *Container) GetName() string { @@ -3315,7 +3781,7 @@ type SecurityContext struct { func (x *SecurityContext) Reset() { *x = SecurityContext{} - mi := &file_ateapi_proto_msgTypes[33] + mi := &file_ateapi_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3327,7 +3793,7 @@ func (x *SecurityContext) String() string { func (*SecurityContext) ProtoMessage() {} func (x *SecurityContext) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[33] + mi := &file_ateapi_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3340,7 +3806,7 @@ func (x *SecurityContext) ProtoReflect() protoreflect.Message { // Deprecated: Use SecurityContext.ProtoReflect.Descriptor instead. func (*SecurityContext) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{33} + return file_ateapi_proto_rawDescGZIP(), []int{36} } func (x *SecurityContext) GetCapabilities() *Capabilities { @@ -3378,7 +3844,7 @@ type Capabilities struct { func (x *Capabilities) Reset() { *x = Capabilities{} - mi := &file_ateapi_proto_msgTypes[34] + mi := &file_ateapi_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3390,7 +3856,7 @@ func (x *Capabilities) String() string { func (*Capabilities) ProtoMessage() {} func (x *Capabilities) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[34] + mi := &file_ateapi_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3403,7 +3869,7 @@ func (x *Capabilities) ProtoReflect() protoreflect.Message { // Deprecated: Use Capabilities.ProtoReflect.Descriptor instead. func (*Capabilities) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{34} + return file_ateapi_proto_rawDescGZIP(), []int{37} } func (x *Capabilities) GetAdd() []string { @@ -3441,7 +3907,7 @@ type EnvVar struct { func (x *EnvVar) Reset() { *x = EnvVar{} - mi := &file_ateapi_proto_msgTypes[35] + mi := &file_ateapi_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3453,7 +3919,7 @@ func (x *EnvVar) String() string { func (*EnvVar) ProtoMessage() {} func (x *EnvVar) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[35] + mi := &file_ateapi_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3466,7 +3932,7 @@ func (x *EnvVar) ProtoReflect() protoreflect.Message { // Deprecated: Use EnvVar.ProtoReflect.Descriptor instead. func (*EnvVar) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{35} + return file_ateapi_proto_rawDescGZIP(), []int{38} } func (x *EnvVar) GetName() string { @@ -3506,7 +3972,7 @@ type ContainerWakeupProbe struct { func (x *ContainerWakeupProbe) Reset() { *x = ContainerWakeupProbe{} - mi := &file_ateapi_proto_msgTypes[36] + mi := &file_ateapi_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3518,7 +3984,7 @@ func (x *ContainerWakeupProbe) String() string { func (*ContainerWakeupProbe) ProtoMessage() {} func (x *ContainerWakeupProbe) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[36] + mi := &file_ateapi_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3531,7 +3997,7 @@ func (x *ContainerWakeupProbe) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerWakeupProbe.ProtoReflect.Descriptor instead. func (*ContainerWakeupProbe) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{36} + return file_ateapi_proto_rawDescGZIP(), []int{39} } func (x *ContainerWakeupProbe) GetHttpGet() *HTTPGetAction { @@ -3571,7 +4037,7 @@ type HTTPGetAction struct { func (x *HTTPGetAction) Reset() { *x = HTTPGetAction{} - mi := &file_ateapi_proto_msgTypes[37] + mi := &file_ateapi_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3583,7 +4049,7 @@ func (x *HTTPGetAction) String() string { func (*HTTPGetAction) ProtoMessage() {} func (x *HTTPGetAction) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[37] + mi := &file_ateapi_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3596,7 +4062,7 @@ func (x *HTTPGetAction) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPGetAction.ProtoReflect.Descriptor instead. func (*HTTPGetAction) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{37} + return file_ateapi_proto_rawDescGZIP(), []int{40} } func (x *HTTPGetAction) GetPath() string { @@ -3643,7 +4109,7 @@ type Volume struct { func (x *Volume) Reset() { *x = Volume{} - mi := &file_ateapi_proto_msgTypes[38] + mi := &file_ateapi_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3655,7 +4121,7 @@ func (x *Volume) String() string { func (*Volume) ProtoMessage() {} func (x *Volume) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[38] + mi := &file_ateapi_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3668,7 +4134,7 @@ func (x *Volume) ProtoReflect() protoreflect.Message { // Deprecated: Use Volume.ProtoReflect.Descriptor instead. func (*Volume) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{38} + return file_ateapi_proto_rawDescGZIP(), []int{41} } func (x *Volume) GetName() string { @@ -3724,7 +4190,7 @@ type ImageVolumeSource struct { func (x *ImageVolumeSource) Reset() { *x = ImageVolumeSource{} - mi := &file_ateapi_proto_msgTypes[39] + mi := &file_ateapi_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3736,7 +4202,7 @@ func (x *ImageVolumeSource) String() string { func (*ImageVolumeSource) ProtoMessage() {} func (x *ImageVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[39] + mi := &file_ateapi_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3749,7 +4215,7 @@ func (x *ImageVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageVolumeSource.ProtoReflect.Descriptor instead. func (*ImageVolumeSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{39} + return file_ateapi_proto_rawDescGZIP(), []int{42} } func (x *ImageVolumeSource) GetReference() string { @@ -3769,7 +4235,7 @@ type DurableDirVolumeSource struct { func (x *DurableDirVolumeSource) Reset() { *x = DurableDirVolumeSource{} - mi := &file_ateapi_proto_msgTypes[40] + mi := &file_ateapi_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3781,7 +4247,7 @@ func (x *DurableDirVolumeSource) String() string { func (*DurableDirVolumeSource) ProtoMessage() {} func (x *DurableDirVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[40] + mi := &file_ateapi_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3794,7 +4260,7 @@ func (x *DurableDirVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use DurableDirVolumeSource.ProtoReflect.Descriptor instead. func (*DurableDirVolumeSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{40} + return file_ateapi_proto_rawDescGZIP(), []int{43} } // ExternalVolumeTemplate provisions an external volume per actor; the volume @@ -3820,7 +4286,7 @@ type ExternalVolumeTemplate struct { func (x *ExternalVolumeTemplate) Reset() { *x = ExternalVolumeTemplate{} - mi := &file_ateapi_proto_msgTypes[41] + mi := &file_ateapi_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3832,7 +4298,7 @@ func (x *ExternalVolumeTemplate) String() string { func (*ExternalVolumeTemplate) ProtoMessage() {} func (x *ExternalVolumeTemplate) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[41] + mi := &file_ateapi_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3845,7 +4311,7 @@ func (x *ExternalVolumeTemplate) ProtoReflect() protoreflect.Message { // Deprecated: Use ExternalVolumeTemplate.ProtoReflect.Descriptor instead. func (*ExternalVolumeTemplate) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{41} + return file_ateapi_proto_rawDescGZIP(), []int{44} } func (x *ExternalVolumeTemplate) GetCapacity() string { @@ -3882,7 +4348,7 @@ type SystemInfoVolumeSource struct { func (x *SystemInfoVolumeSource) Reset() { *x = SystemInfoVolumeSource{} - mi := &file_ateapi_proto_msgTypes[42] + mi := &file_ateapi_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3894,7 +4360,7 @@ func (x *SystemInfoVolumeSource) String() string { func (*SystemInfoVolumeSource) ProtoMessage() {} func (x *SystemInfoVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[42] + mi := &file_ateapi_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3907,7 +4373,7 @@ func (x *SystemInfoVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use SystemInfoVolumeSource.ProtoReflect.Descriptor instead. func (*SystemInfoVolumeSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{42} + return file_ateapi_proto_rawDescGZIP(), []int{45} } func (x *SystemInfoVolumeSource) GetDataSources() []*SystemInfoDataSource { @@ -3933,7 +4399,7 @@ type SystemInfoDataSource struct { func (x *SystemInfoDataSource) Reset() { *x = SystemInfoDataSource{} - mi := &file_ateapi_proto_msgTypes[43] + mi := &file_ateapi_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3945,7 +4411,7 @@ func (x *SystemInfoDataSource) String() string { func (*SystemInfoDataSource) ProtoMessage() {} func (x *SystemInfoDataSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[43] + mi := &file_ateapi_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3958,7 +4424,7 @@ func (x *SystemInfoDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use SystemInfoDataSource.ProtoReflect.Descriptor instead. func (*SystemInfoDataSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{43} + return file_ateapi_proto_rawDescGZIP(), []int{46} } func (x *SystemInfoDataSource) GetActorMetadata() *ActorMetadataDataSource { @@ -3995,7 +4461,7 @@ type ActorMetadataDataSource struct { func (x *ActorMetadataDataSource) Reset() { *x = ActorMetadataDataSource{} - mi := &file_ateapi_proto_msgTypes[44] + mi := &file_ateapi_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4007,7 +4473,7 @@ func (x *ActorMetadataDataSource) String() string { func (*ActorMetadataDataSource) ProtoMessage() {} func (x *ActorMetadataDataSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[44] + mi := &file_ateapi_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4020,7 +4486,7 @@ func (x *ActorMetadataDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorMetadataDataSource.ProtoReflect.Descriptor instead. func (*ActorMetadataDataSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{44} + return file_ateapi_proto_rawDescGZIP(), []int{47} } func (x *ActorMetadataDataSource) GetItems() []*ActorMetadataItem { @@ -4052,7 +4518,7 @@ type ActorMetadataItem struct { func (x *ActorMetadataItem) Reset() { *x = ActorMetadataItem{} - mi := &file_ateapi_proto_msgTypes[45] + mi := &file_ateapi_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4064,7 +4530,7 @@ func (x *ActorMetadataItem) String() string { func (*ActorMetadataItem) ProtoMessage() {} func (x *ActorMetadataItem) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[45] + mi := &file_ateapi_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4077,7 +4543,7 @@ func (x *ActorMetadataItem) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorMetadataItem.ProtoReflect.Descriptor instead. func (*ActorMetadataItem) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{45} + return file_ateapi_proto_rawDescGZIP(), []int{48} } func (x *ActorMetadataItem) GetField() ActorMetadataField { @@ -4129,7 +4595,7 @@ type TrustBundleDataSource struct { func (x *TrustBundleDataSource) Reset() { *x = TrustBundleDataSource{} - mi := &file_ateapi_proto_msgTypes[46] + mi := &file_ateapi_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4141,7 +4607,7 @@ func (x *TrustBundleDataSource) String() string { func (*TrustBundleDataSource) ProtoMessage() {} func (x *TrustBundleDataSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[46] + mi := &file_ateapi_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4154,7 +4620,7 @@ func (x *TrustBundleDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use TrustBundleDataSource.ProtoReflect.Descriptor instead. func (*TrustBundleDataSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{46} + return file_ateapi_proto_rawDescGZIP(), []int{49} } func (x *TrustBundleDataSource) GetNames() []string { @@ -4193,7 +4659,7 @@ type VolumeMount struct { func (x *VolumeMount) Reset() { *x = VolumeMount{} - mi := &file_ateapi_proto_msgTypes[47] + mi := &file_ateapi_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4205,7 +4671,7 @@ func (x *VolumeMount) String() string { func (*VolumeMount) ProtoMessage() {} func (x *VolumeMount) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[47] + mi := &file_ateapi_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4218,7 +4684,7 @@ func (x *VolumeMount) ProtoReflect() protoreflect.Message { // Deprecated: Use VolumeMount.ProtoReflect.Descriptor instead. func (*VolumeMount) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{47} + return file_ateapi_proto_rawDescGZIP(), []int{50} } func (x *VolumeMount) GetName() string { @@ -4247,7 +4713,7 @@ type CreateAtespaceRequest struct { func (x *CreateAtespaceRequest) Reset() { *x = CreateAtespaceRequest{} - mi := &file_ateapi_proto_msgTypes[48] + mi := &file_ateapi_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4259,7 +4725,7 @@ func (x *CreateAtespaceRequest) String() string { func (*CreateAtespaceRequest) ProtoMessage() {} func (x *CreateAtespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[48] + mi := &file_ateapi_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4272,7 +4738,7 @@ func (x *CreateAtespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateAtespaceRequest.ProtoReflect.Descriptor instead. func (*CreateAtespaceRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{48} + return file_ateapi_proto_rawDescGZIP(), []int{51} } func (x *CreateAtespaceRequest) GetAtespace() *Atespace { @@ -4293,7 +4759,7 @@ type GetAtespaceRequest struct { func (x *GetAtespaceRequest) Reset() { *x = GetAtespaceRequest{} - mi := &file_ateapi_proto_msgTypes[49] + mi := &file_ateapi_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4305,7 +4771,7 @@ func (x *GetAtespaceRequest) String() string { func (*GetAtespaceRequest) ProtoMessage() {} func (x *GetAtespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[49] + mi := &file_ateapi_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4318,7 +4784,7 @@ func (x *GetAtespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAtespaceRequest.ProtoReflect.Descriptor instead. func (*GetAtespaceRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{49} + return file_ateapi_proto_rawDescGZIP(), []int{52} } func (x *GetAtespaceRequest) GetAtespace() *ObjectRef { @@ -4349,7 +4815,7 @@ type ListAtespacesRequest struct { func (x *ListAtespacesRequest) Reset() { *x = ListAtespacesRequest{} - mi := &file_ateapi_proto_msgTypes[50] + mi := &file_ateapi_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4361,7 +4827,7 @@ func (x *ListAtespacesRequest) String() string { func (*ListAtespacesRequest) ProtoMessage() {} func (x *ListAtespacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[50] + mi := &file_ateapi_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4374,7 +4840,7 @@ func (x *ListAtespacesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAtespacesRequest.ProtoReflect.Descriptor instead. func (*ListAtespacesRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{50} + return file_ateapi_proto_rawDescGZIP(), []int{53} } func (x *ListAtespacesRequest) GetPageSize() int32 { @@ -4403,7 +4869,7 @@ type ListAtespacesResponse struct { func (x *ListAtespacesResponse) Reset() { *x = ListAtespacesResponse{} - mi := &file_ateapi_proto_msgTypes[51] + mi := &file_ateapi_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4415,7 +4881,7 @@ func (x *ListAtespacesResponse) String() string { func (*ListAtespacesResponse) ProtoMessage() {} func (x *ListAtespacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[51] + mi := &file_ateapi_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4428,7 +4894,7 @@ func (x *ListAtespacesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAtespacesResponse.ProtoReflect.Descriptor instead. func (*ListAtespacesResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{51} + return file_ateapi_proto_rawDescGZIP(), []int{54} } func (x *ListAtespacesResponse) GetAtespaces() []*Atespace { @@ -4460,7 +4926,7 @@ type DeleteAtespaceRequest struct { func (x *DeleteAtespaceRequest) Reset() { *x = DeleteAtespaceRequest{} - mi := &file_ateapi_proto_msgTypes[52] + mi := &file_ateapi_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4472,7 +4938,7 @@ func (x *DeleteAtespaceRequest) String() string { func (*DeleteAtespaceRequest) ProtoMessage() {} func (x *DeleteAtespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[52] + mi := &file_ateapi_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4485,7 +4951,7 @@ func (x *DeleteAtespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteAtespaceRequest.ProtoReflect.Descriptor instead. func (*DeleteAtespaceRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{52} + return file_ateapi_proto_rawDescGZIP(), []int{55} } func (x *DeleteAtespaceRequest) GetAtespace() *ObjectRef { @@ -4516,7 +4982,7 @@ type CreateActorTemplateRequest struct { func (x *CreateActorTemplateRequest) Reset() { *x = CreateActorTemplateRequest{} - mi := &file_ateapi_proto_msgTypes[53] + mi := &file_ateapi_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4528,7 +4994,7 @@ func (x *CreateActorTemplateRequest) String() string { func (*CreateActorTemplateRequest) ProtoMessage() {} func (x *CreateActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[53] + mi := &file_ateapi_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4541,7 +5007,7 @@ func (x *CreateActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorTemplateRequest.ProtoReflect.Descriptor instead. func (*CreateActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{53} + return file_ateapi_proto_rawDescGZIP(), []int{56} } func (x *CreateActorTemplateRequest) GetActorTemplate() *ActorTemplate { @@ -4562,7 +5028,7 @@ type GetActorTemplateRequest struct { func (x *GetActorTemplateRequest) Reset() { *x = GetActorTemplateRequest{} - mi := &file_ateapi_proto_msgTypes[54] + mi := &file_ateapi_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4574,7 +5040,7 @@ func (x *GetActorTemplateRequest) String() string { func (*GetActorTemplateRequest) ProtoMessage() {} func (x *GetActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[54] + mi := &file_ateapi_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4587,7 +5053,7 @@ func (x *GetActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorTemplateRequest.ProtoReflect.Descriptor instead. func (*GetActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{54} + return file_ateapi_proto_rawDescGZIP(), []int{57} } func (x *GetActorTemplateRequest) GetActorTemplate() *ObjectRef { @@ -4624,7 +5090,7 @@ type ListActorTemplatesRequest struct { func (x *ListActorTemplatesRequest) Reset() { *x = ListActorTemplatesRequest{} - mi := &file_ateapi_proto_msgTypes[55] + mi := &file_ateapi_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4636,7 +5102,7 @@ func (x *ListActorTemplatesRequest) String() string { func (*ListActorTemplatesRequest) ProtoMessage() {} func (x *ListActorTemplatesRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[55] + mi := &file_ateapi_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4649,7 +5115,7 @@ func (x *ListActorTemplatesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorTemplatesRequest.ProtoReflect.Descriptor instead. func (*ListActorTemplatesRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{55} + return file_ateapi_proto_rawDescGZIP(), []int{58} } func (x *ListActorTemplatesRequest) GetAtespace() string { @@ -4686,7 +5152,7 @@ type ListActorTemplatesResponse struct { func (x *ListActorTemplatesResponse) Reset() { *x = ListActorTemplatesResponse{} - mi := &file_ateapi_proto_msgTypes[56] + mi := &file_ateapi_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4698,7 +5164,7 @@ func (x *ListActorTemplatesResponse) String() string { func (*ListActorTemplatesResponse) ProtoMessage() {} func (x *ListActorTemplatesResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[56] + mi := &file_ateapi_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4711,7 +5177,7 @@ func (x *ListActorTemplatesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorTemplatesResponse.ProtoReflect.Descriptor instead. func (*ListActorTemplatesResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{56} + return file_ateapi_proto_rawDescGZIP(), []int{59} } func (x *ListActorTemplatesResponse) GetActorTemplates() []*ActorTemplate { @@ -4743,7 +5209,7 @@ type DeleteActorTemplateRequest struct { func (x *DeleteActorTemplateRequest) Reset() { *x = DeleteActorTemplateRequest{} - mi := &file_ateapi_proto_msgTypes[57] + mi := &file_ateapi_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4755,7 +5221,7 @@ func (x *DeleteActorTemplateRequest) String() string { func (*DeleteActorTemplateRequest) ProtoMessage() {} func (x *DeleteActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[57] + mi := &file_ateapi_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4768,7 +5234,7 @@ func (x *DeleteActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorTemplateRequest.ProtoReflect.Descriptor instead. func (*DeleteActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{57} + return file_ateapi_proto_rawDescGZIP(), []int{60} } func (x *DeleteActorTemplateRequest) GetActorTemplate() *ObjectRef { @@ -4796,7 +5262,7 @@ type GetActorRequest struct { func (x *GetActorRequest) Reset() { *x = GetActorRequest{} - mi := &file_ateapi_proto_msgTypes[58] + mi := &file_ateapi_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4808,7 +5274,7 @@ func (x *GetActorRequest) String() string { func (*GetActorRequest) ProtoMessage() {} func (x *GetActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[58] + mi := &file_ateapi_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4821,7 +5287,7 @@ func (x *GetActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorRequest.ProtoReflect.Descriptor instead. func (*GetActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{58} + return file_ateapi_proto_rawDescGZIP(), []int{61} } func (x *GetActorRequest) GetActor() *ObjectRef { @@ -4844,7 +5310,7 @@ type CreateActorRequest struct { func (x *CreateActorRequest) Reset() { *x = CreateActorRequest{} - mi := &file_ateapi_proto_msgTypes[59] + mi := &file_ateapi_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4856,7 +5322,7 @@ func (x *CreateActorRequest) String() string { func (*CreateActorRequest) ProtoMessage() {} func (x *CreateActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[59] + mi := &file_ateapi_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4869,7 +5335,7 @@ func (x *CreateActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorRequest.ProtoReflect.Descriptor instead. func (*CreateActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{59} + return file_ateapi_proto_rawDescGZIP(), []int{62} } func (x *CreateActorRequest) GetActor() *Actor { @@ -4900,7 +5366,7 @@ type UpdateActorRequest struct { func (x *UpdateActorRequest) Reset() { *x = UpdateActorRequest{} - mi := &file_ateapi_proto_msgTypes[60] + mi := &file_ateapi_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4912,7 +5378,7 @@ func (x *UpdateActorRequest) String() string { func (*UpdateActorRequest) ProtoMessage() {} func (x *UpdateActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[60] + mi := &file_ateapi_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4925,7 +5391,7 @@ func (x *UpdateActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateActorRequest.ProtoReflect.Descriptor instead. func (*UpdateActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{60} + return file_ateapi_proto_rawDescGZIP(), []int{63} } func (x *UpdateActorRequest) GetActor() *Actor { @@ -4946,7 +5412,7 @@ type SuspendActorRequest struct { func (x *SuspendActorRequest) Reset() { *x = SuspendActorRequest{} - mi := &file_ateapi_proto_msgTypes[61] + mi := &file_ateapi_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4958,7 +5424,7 @@ func (x *SuspendActorRequest) String() string { func (*SuspendActorRequest) ProtoMessage() {} func (x *SuspendActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[61] + mi := &file_ateapi_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4971,7 +5437,7 @@ func (x *SuspendActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SuspendActorRequest.ProtoReflect.Descriptor instead. func (*SuspendActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{61} + return file_ateapi_proto_rawDescGZIP(), []int{64} } func (x *SuspendActorRequest) GetActor() *ObjectRef { @@ -4990,7 +5456,7 @@ type SuspendActorResponse struct { func (x *SuspendActorResponse) Reset() { *x = SuspendActorResponse{} - mi := &file_ateapi_proto_msgTypes[62] + mi := &file_ateapi_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5002,7 +5468,7 @@ func (x *SuspendActorResponse) String() string { func (*SuspendActorResponse) ProtoMessage() {} func (x *SuspendActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[62] + mi := &file_ateapi_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5015,7 +5481,7 @@ func (x *SuspendActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SuspendActorResponse.ProtoReflect.Descriptor instead. func (*SuspendActorResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{62} + return file_ateapi_proto_rawDescGZIP(), []int{65} } func (x *SuspendActorResponse) GetActor() *Actor { @@ -5036,7 +5502,7 @@ type PauseActorRequest struct { func (x *PauseActorRequest) Reset() { *x = PauseActorRequest{} - mi := &file_ateapi_proto_msgTypes[63] + mi := &file_ateapi_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5048,7 +5514,7 @@ func (x *PauseActorRequest) String() string { func (*PauseActorRequest) ProtoMessage() {} func (x *PauseActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[63] + mi := &file_ateapi_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5061,7 +5527,7 @@ func (x *PauseActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PauseActorRequest.ProtoReflect.Descriptor instead. func (*PauseActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{63} + return file_ateapi_proto_rawDescGZIP(), []int{66} } func (x *PauseActorRequest) GetActor() *ObjectRef { @@ -5080,7 +5546,7 @@ type PauseActorResponse struct { func (x *PauseActorResponse) Reset() { *x = PauseActorResponse{} - mi := &file_ateapi_proto_msgTypes[64] + mi := &file_ateapi_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5092,7 +5558,7 @@ func (x *PauseActorResponse) String() string { func (*PauseActorResponse) ProtoMessage() {} func (x *PauseActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[64] + mi := &file_ateapi_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5105,7 +5571,7 @@ func (x *PauseActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PauseActorResponse.ProtoReflect.Descriptor instead. func (*PauseActorResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{64} + return file_ateapi_proto_rawDescGZIP(), []int{67} } func (x *PauseActorResponse) GetActor() *Actor { @@ -5126,7 +5592,7 @@ type ResumeActorRequest struct { func (x *ResumeActorRequest) Reset() { *x = ResumeActorRequest{} - mi := &file_ateapi_proto_msgTypes[65] + mi := &file_ateapi_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5138,7 +5604,7 @@ func (x *ResumeActorRequest) String() string { func (*ResumeActorRequest) ProtoMessage() {} func (x *ResumeActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[65] + mi := &file_ateapi_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5151,7 +5617,7 @@ func (x *ResumeActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResumeActorRequest.ProtoReflect.Descriptor instead. func (*ResumeActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{65} + return file_ateapi_proto_rawDescGZIP(), []int{68} } func (x *ResumeActorRequest) GetActor() *ObjectRef { @@ -5173,7 +5639,7 @@ type ResumeActorResponse struct { func (x *ResumeActorResponse) Reset() { *x = ResumeActorResponse{} - mi := &file_ateapi_proto_msgTypes[66] + mi := &file_ateapi_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5185,7 +5651,7 @@ func (x *ResumeActorResponse) String() string { func (*ResumeActorResponse) ProtoMessage() {} func (x *ResumeActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[66] + mi := &file_ateapi_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5198,7 +5664,7 @@ func (x *ResumeActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResumeActorResponse.ProtoReflect.Descriptor instead. func (*ResumeActorResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{66} + return file_ateapi_proto_rawDescGZIP(), []int{69} } func (x *ResumeActorResponse) GetActor() *Actor { @@ -5228,7 +5694,7 @@ type RevertActorRequest struct { func (x *RevertActorRequest) Reset() { *x = RevertActorRequest{} - mi := &file_ateapi_proto_msgTypes[67] + mi := &file_ateapi_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5240,7 +5706,7 @@ func (x *RevertActorRequest) String() string { func (*RevertActorRequest) ProtoMessage() {} func (x *RevertActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[67] + mi := &file_ateapi_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5253,7 +5719,7 @@ func (x *RevertActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RevertActorRequest.ProtoReflect.Descriptor instead. func (*RevertActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{67} + return file_ateapi_proto_rawDescGZIP(), []int{70} } func (x *RevertActorRequest) GetActor() *ObjectRef { @@ -5275,7 +5741,7 @@ type RevertActorResponse struct { func (x *RevertActorResponse) Reset() { *x = RevertActorResponse{} - mi := &file_ateapi_proto_msgTypes[68] + mi := &file_ateapi_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5287,7 +5753,7 @@ func (x *RevertActorResponse) String() string { func (*RevertActorResponse) ProtoMessage() {} func (x *RevertActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[68] + mi := &file_ateapi_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5300,7 +5766,7 @@ func (x *RevertActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RevertActorResponse.ProtoReflect.Descriptor instead. func (*RevertActorResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{68} + return file_ateapi_proto_rawDescGZIP(), []int{71} } func (x *RevertActorResponse) GetActor() *Actor { @@ -5329,7 +5795,7 @@ type DeleteActorRequest struct { func (x *DeleteActorRequest) Reset() { *x = DeleteActorRequest{} - mi := &file_ateapi_proto_msgTypes[69] + mi := &file_ateapi_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5341,7 +5807,7 @@ func (x *DeleteActorRequest) String() string { func (*DeleteActorRequest) ProtoMessage() {} func (x *DeleteActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[69] + mi := &file_ateapi_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5354,7 +5820,7 @@ func (x *DeleteActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorRequest.ProtoReflect.Descriptor instead. func (*DeleteActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{69} + return file_ateapi_proto_rawDescGZIP(), []int{72} } func (x *DeleteActorRequest) GetActor() *ObjectRef { @@ -5392,7 +5858,7 @@ type GetActorEgressPolicyRequest struct { func (x *GetActorEgressPolicyRequest) Reset() { *x = GetActorEgressPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[70] + mi := &file_ateapi_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5404,7 +5870,7 @@ func (x *GetActorEgressPolicyRequest) String() string { func (*GetActorEgressPolicyRequest) ProtoMessage() {} func (x *GetActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[70] + mi := &file_ateapi_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5417,7 +5883,7 @@ func (x *GetActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*GetActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{70} + return file_ateapi_proto_rawDescGZIP(), []int{73} } func (x *GetActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5448,7 +5914,7 @@ type CreateActorEgressPolicyRequest struct { func (x *CreateActorEgressPolicyRequest) Reset() { *x = CreateActorEgressPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[71] + mi := &file_ateapi_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5460,7 +5926,7 @@ func (x *CreateActorEgressPolicyRequest) String() string { func (*CreateActorEgressPolicyRequest) ProtoMessage() {} func (x *CreateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[71] + mi := &file_ateapi_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5473,7 +5939,7 @@ func (x *CreateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{71} + return file_ateapi_proto_rawDescGZIP(), []int{74} } func (x *CreateActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5511,7 +5977,7 @@ type UpdateActorEgressPolicyRequest struct { func (x *UpdateActorEgressPolicyRequest) Reset() { *x = UpdateActorEgressPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[72] + mi := &file_ateapi_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5523,7 +5989,7 @@ func (x *UpdateActorEgressPolicyRequest) String() string { func (*UpdateActorEgressPolicyRequest) ProtoMessage() {} func (x *UpdateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[72] + mi := &file_ateapi_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5536,7 +6002,7 @@ func (x *UpdateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{72} + return file_ateapi_proto_rawDescGZIP(), []int{75} } func (x *UpdateActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5571,7 +6037,7 @@ type DeleteActorEgressPolicyRequest struct { func (x *DeleteActorEgressPolicyRequest) Reset() { *x = DeleteActorEgressPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[73] + mi := &file_ateapi_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5583,7 +6049,7 @@ func (x *DeleteActorEgressPolicyRequest) String() string { func (*DeleteActorEgressPolicyRequest) ProtoMessage() {} func (x *DeleteActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[73] + mi := &file_ateapi_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5596,7 +6062,7 @@ func (x *DeleteActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*DeleteActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{73} + return file_ateapi_proto_rawDescGZIP(), []int{76} } func (x *DeleteActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5624,7 +6090,7 @@ type GetTagRequest struct { func (x *GetTagRequest) Reset() { *x = GetTagRequest{} - mi := &file_ateapi_proto_msgTypes[74] + mi := &file_ateapi_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5636,7 +6102,7 @@ func (x *GetTagRequest) String() string { func (*GetTagRequest) ProtoMessage() {} func (x *GetTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[74] + mi := &file_ateapi_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5649,7 +6115,7 @@ func (x *GetTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTagRequest.ProtoReflect.Descriptor instead. func (*GetTagRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{74} + return file_ateapi_proto_rawDescGZIP(), []int{77} } func (x *GetTagRequest) GetTag() *ObjectRef { @@ -5688,7 +6154,7 @@ type MintActorJWTRequest struct { func (x *MintActorJWTRequest) Reset() { *x = MintActorJWTRequest{} - mi := &file_ateapi_proto_msgTypes[75] + mi := &file_ateapi_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5700,7 +6166,7 @@ func (x *MintActorJWTRequest) String() string { func (*MintActorJWTRequest) ProtoMessage() {} func (x *MintActorJWTRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[75] + mi := &file_ateapi_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5713,7 +6179,7 @@ func (x *MintActorJWTRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorJWTRequest.ProtoReflect.Descriptor instead. func (*MintActorJWTRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{75} + return file_ateapi_proto_rawDescGZIP(), []int{78} } func (x *MintActorJWTRequest) GetActor() *ObjectRef { @@ -5763,7 +6229,7 @@ type MintActorJWTResponse struct { func (x *MintActorJWTResponse) Reset() { *x = MintActorJWTResponse{} - mi := &file_ateapi_proto_msgTypes[76] + mi := &file_ateapi_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5775,7 +6241,7 @@ func (x *MintActorJWTResponse) String() string { func (*MintActorJWTResponse) ProtoMessage() {} func (x *MintActorJWTResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[76] + mi := &file_ateapi_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5788,7 +6254,7 @@ func (x *MintActorJWTResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorJWTResponse.ProtoReflect.Descriptor instead. func (*MintActorJWTResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{76} + return file_ateapi_proto_rawDescGZIP(), []int{79} } func (x *MintActorJWTResponse) GetActorJwt() string { @@ -5833,7 +6299,7 @@ type MintActorCertificateRequest struct { func (x *MintActorCertificateRequest) Reset() { *x = MintActorCertificateRequest{} - mi := &file_ateapi_proto_msgTypes[77] + mi := &file_ateapi_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5845,7 +6311,7 @@ func (x *MintActorCertificateRequest) String() string { func (*MintActorCertificateRequest) ProtoMessage() {} func (x *MintActorCertificateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[77] + mi := &file_ateapi_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5858,7 +6324,7 @@ func (x *MintActorCertificateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorCertificateRequest.ProtoReflect.Descriptor instead. func (*MintActorCertificateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{77} + return file_ateapi_proto_rawDescGZIP(), []int{80} } func (x *MintActorCertificateRequest) GetActor() *ObjectRef { @@ -5895,7 +6361,7 @@ type MintActorCertificateResponse struct { func (x *MintActorCertificateResponse) Reset() { *x = MintActorCertificateResponse{} - mi := &file_ateapi_proto_msgTypes[78] + mi := &file_ateapi_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5907,7 +6373,7 @@ func (x *MintActorCertificateResponse) String() string { func (*MintActorCertificateResponse) ProtoMessage() {} func (x *MintActorCertificateResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[78] + mi := &file_ateapi_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5920,7 +6386,7 @@ func (x *MintActorCertificateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorCertificateResponse.ProtoReflect.Descriptor instead. func (*MintActorCertificateResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{78} + return file_ateapi_proto_rawDescGZIP(), []int{81} } func (x *MintActorCertificateResponse) GetActorCertificates() [][]byte { @@ -5956,7 +6422,7 @@ type ListTagsRequest struct { func (x *ListTagsRequest) Reset() { *x = ListTagsRequest{} - mi := &file_ateapi_proto_msgTypes[79] + mi := &file_ateapi_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5968,7 +6434,7 @@ func (x *ListTagsRequest) String() string { func (*ListTagsRequest) ProtoMessage() {} func (x *ListTagsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[79] + mi := &file_ateapi_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5981,7 +6447,7 @@ func (x *ListTagsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTagsRequest.ProtoReflect.Descriptor instead. func (*ListTagsRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{79} + return file_ateapi_proto_rawDescGZIP(), []int{82} } func (x *ListTagsRequest) GetAtespace() string { @@ -6015,7 +6481,7 @@ type ListTagsResponse struct { func (x *ListTagsResponse) Reset() { *x = ListTagsResponse{} - mi := &file_ateapi_proto_msgTypes[80] + mi := &file_ateapi_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6027,7 +6493,7 @@ func (x *ListTagsResponse) String() string { func (*ListTagsResponse) ProtoMessage() {} func (x *ListTagsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[80] + mi := &file_ateapi_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6040,7 +6506,7 @@ func (x *ListTagsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTagsResponse.ProtoReflect.Descriptor instead. func (*ListTagsResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{80} + return file_ateapi_proto_rawDescGZIP(), []int{83} } func (x *ListTagsResponse) GetTags() []*Tag { @@ -6073,31 +6539,364 @@ func (x *ListTagsResponse) GetNextPageToken() string { // +k8s:customValidation # metadata.atespace must match source_actor.atespace type CreateTagRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - // The tag to create. metadata.atespace, metadata.name, scope and source_actor - // are honored; metadata.atespace must match source_actor's, and status is - // ignored on write. - // - // +k8s:required - Tag *Tag `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + // The tag to create. metadata.atespace, metadata.name, scope and source_actor + // are honored; metadata.atespace must match source_actor's, and status is + // ignored on write. + // + // +k8s:required + Tag *Tag `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateTagRequest) Reset() { + *x = CreateTagRequest{} + mi := &file_ateapi_proto_msgTypes[84] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateTagRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateTagRequest) ProtoMessage() {} + +func (x *CreateTagRequest) ProtoReflect() protoreflect.Message { + mi := &file_ateapi_proto_msgTypes[84] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateTagRequest.ProtoReflect.Descriptor instead. +func (*CreateTagRequest) Descriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{84} +} + +func (x *CreateTagRequest) GetTag() *Tag { + if x != nil { + return x.Tag + } + return nil +} + +// Request to update mutable fields on an existing Tag. +// The tag keeps its address: the snapshot it points at cannot be changed. +type UpdateTagRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The tag to update. + // tag.metadata.atespace and tag.metadata.name identify which resource to + // update. + // tag.metadata.version and tag.metadata.uid are required preconditions + // + // +k8s:required + // +k8s:opaqueType # updates are handled in 2 steps, do not descend + // +k8s:subfield(metadata)=+k8s:required + // +k8s:customValidation # TODO: when we get nested subfields, require metadata.atespace + Tag *Tag `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateTagRequest) Reset() { + *x = UpdateTagRequest{} + mi := &file_ateapi_proto_msgTypes[85] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateTagRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateTagRequest) ProtoMessage() {} + +func (x *UpdateTagRequest) ProtoReflect() protoreflect.Message { + mi := &file_ateapi_proto_msgTypes[85] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateTagRequest.ProtoReflect.Descriptor instead. +func (*UpdateTagRequest) Descriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{85} +} + +func (x *UpdateTagRequest) GetTag() *Tag { + if x != nil { + return x.Tag + } + return nil +} + +type DeleteTagRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // +k8s:required + // +k8s:subfield(atespace)=+k8s:required + Tag *ObjectRef `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + // Optional per-delete preconditions. + // + // +k8s:optional + Options *DeleteOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteTagRequest) Reset() { + *x = DeleteTagRequest{} + mi := &file_ateapi_proto_msgTypes[86] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteTagRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteTagRequest) ProtoMessage() {} + +func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { + mi := &file_ateapi_proto_msgTypes[86] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteTagRequest.ProtoReflect.Descriptor instead. +func (*DeleteTagRequest) Descriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{86} +} + +func (x *DeleteTagRequest) GetTag() *ObjectRef { + if x != nil { + return x.Tag + } + return nil +} + +func (x *DeleteTagRequest) GetOptions() *DeleteOptions { + if x != nil { + return x.Options + } + return nil +} + +// Request to create an ExternalVolume. +// +// +k8s:customValidation # exactly one of storage_class_name and volume_id +type CreateExternalVolumeRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The volume to create. Name a storage class to provision a new volume, or + // supply a volume ID to register one that already exists. status is ignored. + // + // +k8s:required + ExternalVolume *ExternalVolume `protobuf:"bytes,1,opt,name=external_volume,json=externalVolume,proto3" json:"external_volume,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateExternalVolumeRequest) Reset() { + *x = CreateExternalVolumeRequest{} + mi := &file_ateapi_proto_msgTypes[87] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateExternalVolumeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateExternalVolumeRequest) ProtoMessage() {} + +func (x *CreateExternalVolumeRequest) ProtoReflect() protoreflect.Message { + mi := &file_ateapi_proto_msgTypes[87] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateExternalVolumeRequest.ProtoReflect.Descriptor instead. +func (*CreateExternalVolumeRequest) Descriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{87} +} + +func (x *CreateExternalVolumeRequest) GetExternalVolume() *ExternalVolume { + if x != nil { + return x.ExternalVolume + } + return nil +} + +// GetExternalVolumeRequest identifies one ExternalVolume. +type GetExternalVolumeRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The volume to get. + // + // +k8s:required + // +k8s:subfield(atespace)=+k8s:required + ExternalVolume *ObjectRef `protobuf:"bytes,1,opt,name=external_volume,json=externalVolume,proto3" json:"external_volume,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetExternalVolumeRequest) Reset() { + *x = GetExternalVolumeRequest{} + mi := &file_ateapi_proto_msgTypes[88] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetExternalVolumeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExternalVolumeRequest) ProtoMessage() {} + +func (x *GetExternalVolumeRequest) ProtoReflect() protoreflect.Message { + mi := &file_ateapi_proto_msgTypes[88] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExternalVolumeRequest.ProtoReflect.Descriptor instead. +func (*GetExternalVolumeRequest) Descriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{88} +} + +func (x *GetExternalVolumeRequest) GetExternalVolume() *ObjectRef { + if x != nil { + return x.ExternalVolume + } + return nil +} + +// ListExternalVolumesRequest selects a page of ExternalVolumes. +type ListExternalVolumesRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The atespace to list from. Empty lists across all atespaces. + // + // +k8s:optional + // +k8s:format=k8s-short-name + Atespace string `protobuf:"bytes,1,opt,name=atespace,proto3" json:"atespace,omitempty"` + // Requested page size; values above 1000 are coerced to 1000. + // + // +k8s:optional + // +k8s:minimum=1 + PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // Pagination token from a previous ListExternalVolumes response. + // + // +k8s:optional + // +k8s:maxLength=256 + PageToken string `protobuf:"bytes,3,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListExternalVolumesRequest) Reset() { + *x = ListExternalVolumesRequest{} + mi := &file_ateapi_proto_msgTypes[89] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListExternalVolumesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListExternalVolumesRequest) ProtoMessage() {} + +func (x *ListExternalVolumesRequest) ProtoReflect() protoreflect.Message { + mi := &file_ateapi_proto_msgTypes[89] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListExternalVolumesRequest.ProtoReflect.Descriptor instead. +func (*ListExternalVolumesRequest) Descriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{89} +} + +func (x *ListExternalVolumesRequest) GetAtespace() string { + if x != nil { + return x.Atespace + } + return "" +} + +func (x *ListExternalVolumesRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListExternalVolumesRequest) GetPageToken() string { + if x != nil { + return x.PageToken + } + return "" +} + +// ListExternalVolumesResponse is one page of ExternalVolumes. +type ListExternalVolumesResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The volumes in this page. + ExternalVolumes []*ExternalVolume `protobuf:"bytes,1,rep,name=external_volumes,json=externalVolumes,proto3" json:"external_volumes,omitempty"` + // Pagination token for the next page. Empty on the last page. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *CreateTagRequest) Reset() { - *x = CreateTagRequest{} - mi := &file_ateapi_proto_msgTypes[81] +func (x *ListExternalVolumesResponse) Reset() { + *x = ListExternalVolumesResponse{} + mi := &file_ateapi_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *CreateTagRequest) String() string { +func (x *ListExternalVolumesResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CreateTagRequest) ProtoMessage() {} +func (*ListExternalVolumesResponse) ProtoMessage() {} -func (x *CreateTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[81] +func (x *ListExternalVolumesResponse) ProtoReflect() protoreflect.Message { + mi := &file_ateapi_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6108,51 +6907,55 @@ func (x *CreateTagRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CreateTagRequest.ProtoReflect.Descriptor instead. -func (*CreateTagRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{81} +// Deprecated: Use ListExternalVolumesResponse.ProtoReflect.Descriptor instead. +func (*ListExternalVolumesResponse) Descriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{90} } -func (x *CreateTagRequest) GetTag() *Tag { +func (x *ListExternalVolumesResponse) GetExternalVolumes() []*ExternalVolume { if x != nil { - return x.Tag + return x.ExternalVolumes } return nil } -// Request to update mutable fields on an existing Tag. -// The tag keeps its address: the snapshot it points at cannot be changed. -type UpdateTagRequest struct { +func (x *ListExternalVolumesResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +// Request to update the mutable fields of an ExternalVolume. +type UpdateExternalVolumeRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - // The tag to update. - // tag.metadata.atespace and tag.metadata.name identify which resource to - // update. - // tag.metadata.version and tag.metadata.uid are required preconditions + // The volume to update. metadata.atespace and metadata.name identify it; + // metadata.version and metadata.uid are required preconditions. // // +k8s:required // +k8s:opaqueType # updates are handled in 2 steps, do not descend // +k8s:subfield(metadata)=+k8s:required // +k8s:customValidation # TODO: when we get nested subfields, require metadata.atespace - Tag *Tag `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + ExternalVolume *ExternalVolume `protobuf:"bytes,1,opt,name=external_volume,json=externalVolume,proto3" json:"external_volume,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *UpdateTagRequest) Reset() { - *x = UpdateTagRequest{} - mi := &file_ateapi_proto_msgTypes[82] +func (x *UpdateExternalVolumeRequest) Reset() { + *x = UpdateExternalVolumeRequest{} + mi := &file_ateapi_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *UpdateTagRequest) String() string { +func (x *UpdateExternalVolumeRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*UpdateTagRequest) ProtoMessage() {} +func (*UpdateExternalVolumeRequest) ProtoMessage() {} -func (x *UpdateTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[82] +func (x *UpdateExternalVolumeRequest) ProtoReflect() protoreflect.Message { + mi := &file_ateapi_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6163,23 +6966,26 @@ func (x *UpdateTagRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use UpdateTagRequest.ProtoReflect.Descriptor instead. -func (*UpdateTagRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{82} +// Deprecated: Use UpdateExternalVolumeRequest.ProtoReflect.Descriptor instead. +func (*UpdateExternalVolumeRequest) Descriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{91} } -func (x *UpdateTagRequest) GetTag() *Tag { +func (x *UpdateExternalVolumeRequest) GetExternalVolume() *ExternalVolume { if x != nil { - return x.Tag + return x.ExternalVolume } return nil } -type DeleteTagRequest struct { +// DeleteExternalVolumeRequest identifies one ExternalVolume to delete. +type DeleteExternalVolumeRequest struct { state protoimpl.MessageState `protogen:"open.v1"` + // The volume to delete. + // // +k8s:required // +k8s:subfield(atespace)=+k8s:required - Tag *ObjectRef `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + ExternalVolume *ObjectRef `protobuf:"bytes,1,opt,name=external_volume,json=externalVolume,proto3" json:"external_volume,omitempty"` // Optional per-delete preconditions. // // +k8s:optional @@ -6188,21 +6994,21 @@ type DeleteTagRequest struct { sizeCache protoimpl.SizeCache } -func (x *DeleteTagRequest) Reset() { - *x = DeleteTagRequest{} - mi := &file_ateapi_proto_msgTypes[83] +func (x *DeleteExternalVolumeRequest) Reset() { + *x = DeleteExternalVolumeRequest{} + mi := &file_ateapi_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *DeleteTagRequest) String() string { +func (x *DeleteExternalVolumeRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*DeleteTagRequest) ProtoMessage() {} +func (*DeleteExternalVolumeRequest) ProtoMessage() {} -func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[83] +func (x *DeleteExternalVolumeRequest) ProtoReflect() protoreflect.Message { + mi := &file_ateapi_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6213,19 +7019,19 @@ func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use DeleteTagRequest.ProtoReflect.Descriptor instead. -func (*DeleteTagRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{83} +// Deprecated: Use DeleteExternalVolumeRequest.ProtoReflect.Descriptor instead. +func (*DeleteExternalVolumeRequest) Descriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{92} } -func (x *DeleteTagRequest) GetTag() *ObjectRef { +func (x *DeleteExternalVolumeRequest) GetExternalVolume() *ObjectRef { if x != nil { - return x.Tag + return x.ExternalVolume } return nil } -func (x *DeleteTagRequest) GetOptions() *DeleteOptions { +func (x *DeleteExternalVolumeRequest) GetOptions() *DeleteOptions { if x != nil { return x.Options } @@ -6254,7 +7060,7 @@ type DeleteOptions struct { func (x *DeleteOptions) Reset() { *x = DeleteOptions{} - mi := &file_ateapi_proto_msgTypes[84] + mi := &file_ateapi_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6266,7 +7072,7 @@ func (x *DeleteOptions) String() string { func (*DeleteOptions) ProtoMessage() {} func (x *DeleteOptions) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[84] + mi := &file_ateapi_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6279,7 +7085,7 @@ func (x *DeleteOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteOptions.ProtoReflect.Descriptor instead. func (*DeleteOptions) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{84} + return file_ateapi_proto_rawDescGZIP(), []int{93} } func (x *DeleteOptions) GetVersion() int64 { @@ -6323,7 +7129,7 @@ type ListWorkerActorAssignmentsRequest struct { func (x *ListWorkerActorAssignmentsRequest) Reset() { *x = ListWorkerActorAssignmentsRequest{} - mi := &file_ateapi_proto_msgTypes[85] + mi := &file_ateapi_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6335,7 +7141,7 @@ func (x *ListWorkerActorAssignmentsRequest) String() string { func (*ListWorkerActorAssignmentsRequest) ProtoMessage() {} func (x *ListWorkerActorAssignmentsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[85] + mi := &file_ateapi_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6348,7 +7154,7 @@ func (x *ListWorkerActorAssignmentsRequest) ProtoReflect() protoreflect.Message // Deprecated: Use ListWorkerActorAssignmentsRequest.ProtoReflect.Descriptor instead. func (*ListWorkerActorAssignmentsRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{85} + return file_ateapi_proto_rawDescGZIP(), []int{94} } func (x *ListWorkerActorAssignmentsRequest) GetWorker() *ObjectRef { @@ -6385,7 +7191,7 @@ type ListWorkerActorAssignmentsResponse struct { func (x *ListWorkerActorAssignmentsResponse) Reset() { *x = ListWorkerActorAssignmentsResponse{} - mi := &file_ateapi_proto_msgTypes[86] + mi := &file_ateapi_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6397,7 +7203,7 @@ func (x *ListWorkerActorAssignmentsResponse) String() string { func (*ListWorkerActorAssignmentsResponse) ProtoMessage() {} func (x *ListWorkerActorAssignmentsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[86] + mi := &file_ateapi_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6410,7 +7216,7 @@ func (x *ListWorkerActorAssignmentsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ListWorkerActorAssignmentsResponse.ProtoReflect.Descriptor instead. func (*ListWorkerActorAssignmentsResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{86} + return file_ateapi_proto_rawDescGZIP(), []int{95} } func (x *ListWorkerActorAssignmentsResponse) GetActorAssignments() []*ActorAssignment { @@ -6448,7 +7254,7 @@ type ListWorkersRequest struct { func (x *ListWorkersRequest) Reset() { *x = ListWorkersRequest{} - mi := &file_ateapi_proto_msgTypes[87] + mi := &file_ateapi_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6460,7 +7266,7 @@ func (x *ListWorkersRequest) String() string { func (*ListWorkersRequest) ProtoMessage() {} func (x *ListWorkersRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[87] + mi := &file_ateapi_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6473,7 +7279,7 @@ func (x *ListWorkersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkersRequest.ProtoReflect.Descriptor instead. func (*ListWorkersRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{87} + return file_ateapi_proto_rawDescGZIP(), []int{96} } func (x *ListWorkersRequest) GetPageSize() int32 { @@ -6502,7 +7308,7 @@ type ListWorkersResponse struct { func (x *ListWorkersResponse) Reset() { *x = ListWorkersResponse{} - mi := &file_ateapi_proto_msgTypes[88] + mi := &file_ateapi_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6514,7 +7320,7 @@ func (x *ListWorkersResponse) String() string { func (*ListWorkersResponse) ProtoMessage() {} func (x *ListWorkersResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[88] + mi := &file_ateapi_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6527,7 +7333,7 @@ func (x *ListWorkersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkersResponse.ProtoReflect.Descriptor instead. func (*ListWorkersResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{88} + return file_ateapi_proto_rawDescGZIP(), []int{97} } func (x *ListWorkersResponse) GetWorkers() []*Worker { @@ -6557,7 +7363,7 @@ type GetWorkerRequest struct { func (x *GetWorkerRequest) Reset() { *x = GetWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[89] + mi := &file_ateapi_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6569,7 +7375,7 @@ func (x *GetWorkerRequest) String() string { func (*GetWorkerRequest) ProtoMessage() {} func (x *GetWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[89] + mi := &file_ateapi_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6582,7 +7388,7 @@ func (x *GetWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkerRequest.ProtoReflect.Descriptor instead. func (*GetWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{89} + return file_ateapi_proto_rawDescGZIP(), []int{98} } func (x *GetWorkerRequest) GetWorker() *ObjectRef { @@ -6604,7 +7410,7 @@ type CreateWorkerRequest struct { func (x *CreateWorkerRequest) Reset() { *x = CreateWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[90] + mi := &file_ateapi_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6616,7 +7422,7 @@ func (x *CreateWorkerRequest) String() string { func (*CreateWorkerRequest) ProtoMessage() {} func (x *CreateWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[90] + mi := &file_ateapi_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6629,7 +7435,7 @@ func (x *CreateWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkerRequest.ProtoReflect.Descriptor instead. func (*CreateWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{90} + return file_ateapi_proto_rawDescGZIP(), []int{99} } func (x *CreateWorkerRequest) GetWorker() *Worker { @@ -6664,7 +7470,7 @@ type UpdateWorkerRequest struct { func (x *UpdateWorkerRequest) Reset() { *x = UpdateWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[91] + mi := &file_ateapi_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6676,7 +7482,7 @@ func (x *UpdateWorkerRequest) String() string { func (*UpdateWorkerRequest) ProtoMessage() {} func (x *UpdateWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[91] + mi := &file_ateapi_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6689,7 +7495,7 @@ func (x *UpdateWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateWorkerRequest.ProtoReflect.Descriptor instead. func (*UpdateWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{91} + return file_ateapi_proto_rawDescGZIP(), []int{100} } func (x *UpdateWorkerRequest) GetWorker() *Worker { @@ -6716,7 +7522,7 @@ type DeleteWorkerRequest struct { func (x *DeleteWorkerRequest) Reset() { *x = DeleteWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[92] + mi := &file_ateapi_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6728,7 +7534,7 @@ func (x *DeleteWorkerRequest) String() string { func (*DeleteWorkerRequest) ProtoMessage() {} func (x *DeleteWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[92] + mi := &file_ateapi_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6741,7 +7547,7 @@ func (x *DeleteWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkerRequest.ProtoReflect.Descriptor instead. func (*DeleteWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{92} + return file_ateapi_proto_rawDescGZIP(), []int{101} } func (x *DeleteWorkerRequest) GetWorker() *ObjectRef { @@ -6771,7 +7577,7 @@ type DrainWorkerRequest struct { func (x *DrainWorkerRequest) Reset() { *x = DrainWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[93] + mi := &file_ateapi_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6783,7 +7589,7 @@ func (x *DrainWorkerRequest) String() string { func (*DrainWorkerRequest) ProtoMessage() {} func (x *DrainWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[93] + mi := &file_ateapi_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6796,7 +7602,7 @@ func (x *DrainWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DrainWorkerRequest.ProtoReflect.Descriptor instead. func (*DrainWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{93} + return file_ateapi_proto_rawDescGZIP(), []int{102} } func (x *DrainWorkerRequest) GetWorker() *ObjectRef { @@ -6834,7 +7640,7 @@ type ListActorsRequest struct { func (x *ListActorsRequest) Reset() { *x = ListActorsRequest{} - mi := &file_ateapi_proto_msgTypes[94] + mi := &file_ateapi_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6846,7 +7652,7 @@ func (x *ListActorsRequest) String() string { func (*ListActorsRequest) ProtoMessage() {} func (x *ListActorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[94] + mi := &file_ateapi_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6859,7 +7665,7 @@ func (x *ListActorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorsRequest.ProtoReflect.Descriptor instead. func (*ListActorsRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{94} + return file_ateapi_proto_rawDescGZIP(), []int{103} } func (x *ListActorsRequest) GetAtespace() string { @@ -6895,7 +7701,7 @@ type ListActorsResponse struct { func (x *ListActorsResponse) Reset() { *x = ListActorsResponse{} - mi := &file_ateapi_proto_msgTypes[95] + mi := &file_ateapi_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6907,7 +7713,7 @@ func (x *ListActorsResponse) String() string { func (*ListActorsResponse) ProtoMessage() {} func (x *ListActorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[95] + mi := &file_ateapi_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6920,7 +7726,7 @@ func (x *ListActorsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorsResponse.ProtoReflect.Descriptor instead. func (*ListActorsResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{95} + return file_ateapi_proto_rawDescGZIP(), []int{104} } func (x *ListActorsResponse) GetActors() []*Actor { @@ -7027,7 +7833,7 @@ type Worker struct { func (x *Worker) Reset() { *x = Worker{} - mi := &file_ateapi_proto_msgTypes[96] + mi := &file_ateapi_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7039,7 +7845,7 @@ func (x *Worker) String() string { func (*Worker) ProtoMessage() {} func (x *Worker) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[96] + mi := &file_ateapi_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7052,7 +7858,7 @@ func (x *Worker) ProtoReflect() protoreflect.Message { // Deprecated: Use Worker.ProtoReflect.Descriptor instead. func (*Worker) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{96} + return file_ateapi_proto_rawDescGZIP(), []int{105} } func (x *Worker) GetMetadata() *ResourceMetadata { @@ -7172,7 +7978,7 @@ type WorkerStatus struct { func (x *WorkerStatus) Reset() { *x = WorkerStatus{} - mi := &file_ateapi_proto_msgTypes[97] + mi := &file_ateapi_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7184,7 +7990,7 @@ func (x *WorkerStatus) String() string { func (*WorkerStatus) ProtoMessage() {} func (x *WorkerStatus) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[97] + mi := &file_ateapi_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7197,7 +8003,7 @@ func (x *WorkerStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerStatus.ProtoReflect.Descriptor instead. func (*WorkerStatus) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{97} + return file_ateapi_proto_rawDescGZIP(), []int{106} } func (x *WorkerStatus) GetState() WorkerState { @@ -7253,7 +8059,7 @@ type HardwareIdentity struct { func (x *HardwareIdentity) Reset() { *x = HardwareIdentity{} - mi := &file_ateapi_proto_msgTypes[98] + mi := &file_ateapi_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7265,7 +8071,7 @@ func (x *HardwareIdentity) String() string { func (*HardwareIdentity) ProtoMessage() {} func (x *HardwareIdentity) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[98] + mi := &file_ateapi_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7278,7 +8084,7 @@ func (x *HardwareIdentity) ProtoReflect() protoreflect.Message { // Deprecated: Use HardwareIdentity.ProtoReflect.Descriptor instead. func (*HardwareIdentity) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{98} + return file_ateapi_proto_rawDescGZIP(), []int{107} } func (x *HardwareIdentity) GetAttributes() map[string]string { @@ -7310,7 +8116,7 @@ type WorkerResources struct { func (x *WorkerResources) Reset() { *x = WorkerResources{} - mi := &file_ateapi_proto_msgTypes[99] + mi := &file_ateapi_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7322,7 +8128,7 @@ func (x *WorkerResources) String() string { func (*WorkerResources) ProtoMessage() {} func (x *WorkerResources) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[99] + mi := &file_ateapi_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7335,7 +8141,7 @@ func (x *WorkerResources) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerResources.ProtoReflect.Descriptor instead. func (*WorkerResources) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{99} + return file_ateapi_proto_rawDescGZIP(), []int{108} } func (x *WorkerResources) GetResources() *Resources { @@ -7388,7 +8194,7 @@ type ActorAssignment struct { func (x *ActorAssignment) Reset() { *x = ActorAssignment{} - mi := &file_ateapi_proto_msgTypes[100] + mi := &file_ateapi_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7400,7 +8206,7 @@ func (x *ActorAssignment) String() string { func (*ActorAssignment) ProtoMessage() {} func (x *ActorAssignment) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[100] + mi := &file_ateapi_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7413,7 +8219,7 @@ func (x *ActorAssignment) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorAssignment.ProtoReflect.Descriptor instead. func (*ActorAssignment) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{100} + return file_ateapi_proto_rawDescGZIP(), []int{109} } func (x *ActorAssignment) GetMetadata() *ResourceMetadata { @@ -7476,7 +8282,7 @@ type RegisterWorkerRequest struct { func (x *RegisterWorkerRequest) Reset() { *x = RegisterWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[101] + mi := &file_ateapi_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7488,7 +8294,7 @@ func (x *RegisterWorkerRequest) String() string { func (*RegisterWorkerRequest) ProtoMessage() {} func (x *RegisterWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[101] + mi := &file_ateapi_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7501,7 +8307,7 @@ func (x *RegisterWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterWorkerRequest.ProtoReflect.Descriptor instead. func (*RegisterWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{101} + return file_ateapi_proto_rawDescGZIP(), []int{110} } func (x *RegisterWorkerRequest) GetWorker() *ObjectRef { @@ -7535,7 +8341,7 @@ type RegisterWorkerResponse struct { func (x *RegisterWorkerResponse) Reset() { *x = RegisterWorkerResponse{} - mi := &file_ateapi_proto_msgTypes[102] + mi := &file_ateapi_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7547,7 +8353,7 @@ func (x *RegisterWorkerResponse) String() string { func (*RegisterWorkerResponse) ProtoMessage() {} func (x *RegisterWorkerResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[102] + mi := &file_ateapi_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7560,7 +8366,7 @@ func (x *RegisterWorkerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterWorkerResponse.ProtoReflect.Descriptor instead. func (*RegisterWorkerResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{102} + return file_ateapi_proto_rawDescGZIP(), []int{111} } func (x *RegisterWorkerResponse) GetWorker() *Worker { @@ -7599,7 +8405,7 @@ type MintAteomActorCertificateRequest struct { func (x *MintAteomActorCertificateRequest) Reset() { *x = MintAteomActorCertificateRequest{} - mi := &file_ateapi_proto_msgTypes[103] + mi := &file_ateapi_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7611,7 +8417,7 @@ func (x *MintAteomActorCertificateRequest) String() string { func (*MintAteomActorCertificateRequest) ProtoMessage() {} func (x *MintAteomActorCertificateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[103] + mi := &file_ateapi_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7624,7 +8430,7 @@ func (x *MintAteomActorCertificateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintAteomActorCertificateRequest.ProtoReflect.Descriptor instead. func (*MintAteomActorCertificateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{103} + return file_ateapi_proto_rawDescGZIP(), []int{112} } func (x *MintAteomActorCertificateRequest) GetActor() *ObjectRef { @@ -7661,7 +8467,7 @@ type MintAteomActorCertificateResponse struct { func (x *MintAteomActorCertificateResponse) Reset() { *x = MintAteomActorCertificateResponse{} - mi := &file_ateapi_proto_msgTypes[104] + mi := &file_ateapi_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7673,7 +8479,7 @@ func (x *MintAteomActorCertificateResponse) String() string { func (*MintAteomActorCertificateResponse) ProtoMessage() {} func (x *MintAteomActorCertificateResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[104] + mi := &file_ateapi_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7686,7 +8492,7 @@ func (x *MintAteomActorCertificateResponse) ProtoReflect() protoreflect.Message // Deprecated: Use MintAteomActorCertificateResponse.ProtoReflect.Descriptor instead. func (*MintAteomActorCertificateResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{104} + return file_ateapi_proto_rawDescGZIP(), []int{113} } func (x *MintAteomActorCertificateResponse) GetActorCertificates() [][]byte { @@ -7724,7 +8530,7 @@ type RequestActorSuspendRequest struct { func (x *RequestActorSuspendRequest) Reset() { *x = RequestActorSuspendRequest{} - mi := &file_ateapi_proto_msgTypes[105] + mi := &file_ateapi_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7736,7 +8542,7 @@ func (x *RequestActorSuspendRequest) String() string { func (*RequestActorSuspendRequest) ProtoMessage() {} func (x *RequestActorSuspendRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[105] + mi := &file_ateapi_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7749,7 +8555,7 @@ func (x *RequestActorSuspendRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestActorSuspendRequest.ProtoReflect.Descriptor instead. func (*RequestActorSuspendRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{105} + return file_ateapi_proto_rawDescGZIP(), []int{114} } func (x *RequestActorSuspendRequest) GetWorker() *ObjectRef { @@ -7783,7 +8589,7 @@ type RequestActorSuspendResponse struct { func (x *RequestActorSuspendResponse) Reset() { *x = RequestActorSuspendResponse{} - mi := &file_ateapi_proto_msgTypes[106] + mi := &file_ateapi_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7795,7 +8601,7 @@ func (x *RequestActorSuspendResponse) String() string { func (*RequestActorSuspendResponse) ProtoMessage() {} func (x *RequestActorSuspendResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[106] + mi := &file_ateapi_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7808,7 +8614,7 @@ func (x *RequestActorSuspendResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestActorSuspendResponse.ProtoReflect.Descriptor instead. func (*RequestActorSuspendResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{106} + return file_ateapi_proto_rawDescGZIP(), []int{115} } func (x *RequestActorSuspendResponse) GetActor() *Actor { @@ -7843,7 +8649,7 @@ type AccessPolicy struct { func (x *AccessPolicy) Reset() { *x = AccessPolicy{} - mi := &file_ateapi_proto_msgTypes[107] + mi := &file_ateapi_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7855,7 +8661,7 @@ func (x *AccessPolicy) String() string { func (*AccessPolicy) ProtoMessage() {} func (x *AccessPolicy) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[107] + mi := &file_ateapi_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7868,7 +8674,7 @@ func (x *AccessPolicy) ProtoReflect() protoreflect.Message { // Deprecated: Use AccessPolicy.ProtoReflect.Descriptor instead. func (*AccessPolicy) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{107} + return file_ateapi_proto_rawDescGZIP(), []int{116} } func (x *AccessPolicy) GetMetadata() *ResourceMetadata { @@ -7910,7 +8716,7 @@ type Binding struct { func (x *Binding) Reset() { *x = Binding{} - mi := &file_ateapi_proto_msgTypes[108] + mi := &file_ateapi_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7922,7 +8728,7 @@ func (x *Binding) String() string { func (*Binding) ProtoMessage() {} func (x *Binding) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[108] + mi := &file_ateapi_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7935,7 +8741,7 @@ func (x *Binding) ProtoReflect() protoreflect.Message { // Deprecated: Use Binding.ProtoReflect.Descriptor instead. func (*Binding) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{108} + return file_ateapi_proto_rawDescGZIP(), []int{117} } func (x *Binding) GetRole() string { @@ -7961,7 +8767,7 @@ type GetGlobalAccessPolicyRequest struct { func (x *GetGlobalAccessPolicyRequest) Reset() { *x = GetGlobalAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[109] + mi := &file_ateapi_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7973,7 +8779,7 @@ func (x *GetGlobalAccessPolicyRequest) String() string { func (*GetGlobalAccessPolicyRequest) ProtoMessage() {} func (x *GetGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[109] + mi := &file_ateapi_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7986,7 +8792,7 @@ func (x *GetGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*GetGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{109} + return file_ateapi_proto_rawDescGZIP(), []int{118} } // CreateGlobalAccessPolicyRequest creates the deployment-wide global access policy singleton. @@ -8003,7 +8809,7 @@ type CreateGlobalAccessPolicyRequest struct { func (x *CreateGlobalAccessPolicyRequest) Reset() { *x = CreateGlobalAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[110] + mi := &file_ateapi_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8015,7 +8821,7 @@ func (x *CreateGlobalAccessPolicyRequest) String() string { func (*CreateGlobalAccessPolicyRequest) ProtoMessage() {} func (x *CreateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[110] + mi := &file_ateapi_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8028,7 +8834,7 @@ func (x *CreateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{110} + return file_ateapi_proto_rawDescGZIP(), []int{119} } func (x *CreateGlobalAccessPolicyRequest) GetAccessPolicy() *AccessPolicy { @@ -8052,7 +8858,7 @@ type UpdateGlobalAccessPolicyRequest struct { func (x *UpdateGlobalAccessPolicyRequest) Reset() { *x = UpdateGlobalAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[111] + mi := &file_ateapi_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8064,7 +8870,7 @@ func (x *UpdateGlobalAccessPolicyRequest) String() string { func (*UpdateGlobalAccessPolicyRequest) ProtoMessage() {} func (x *UpdateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[111] + mi := &file_ateapi_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8077,7 +8883,7 @@ func (x *UpdateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{111} + return file_ateapi_proto_rawDescGZIP(), []int{120} } func (x *UpdateGlobalAccessPolicyRequest) GetAccessPolicy() *AccessPolicy { @@ -8101,7 +8907,7 @@ type GetAtespaceAccessPolicyRequest struct { func (x *GetAtespaceAccessPolicyRequest) Reset() { *x = GetAtespaceAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[112] + mi := &file_ateapi_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8113,7 +8919,7 @@ func (x *GetAtespaceAccessPolicyRequest) String() string { func (*GetAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *GetAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[112] + mi := &file_ateapi_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8126,7 +8932,7 @@ func (x *GetAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*GetAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{112} + return file_ateapi_proto_rawDescGZIP(), []int{121} } func (x *GetAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -8155,7 +8961,7 @@ type CreateAtespaceAccessPolicyRequest struct { func (x *CreateAtespaceAccessPolicyRequest) Reset() { *x = CreateAtespaceAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[113] + mi := &file_ateapi_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8167,7 +8973,7 @@ func (x *CreateAtespaceAccessPolicyRequest) String() string { func (*CreateAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *CreateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[113] + mi := &file_ateapi_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8180,7 +8986,7 @@ func (x *CreateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use CreateAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{113} + return file_ateapi_proto_rawDescGZIP(), []int{122} } func (x *CreateAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -8216,7 +9022,7 @@ type UpdateAtespaceAccessPolicyRequest struct { func (x *UpdateAtespaceAccessPolicyRequest) Reset() { *x = UpdateAtespaceAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[114] + mi := &file_ateapi_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8228,7 +9034,7 @@ func (x *UpdateAtespaceAccessPolicyRequest) String() string { func (*UpdateAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *UpdateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[114] + mi := &file_ateapi_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8241,7 +9047,7 @@ func (x *UpdateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use UpdateAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{114} + return file_ateapi_proto_rawDescGZIP(), []int{123} } func (x *UpdateAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -8276,7 +9082,7 @@ type DeleteAtespaceAccessPolicyRequest struct { func (x *DeleteAtespaceAccessPolicyRequest) Reset() { *x = DeleteAtespaceAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[115] + mi := &file_ateapi_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8288,7 +9094,7 @@ func (x *DeleteAtespaceAccessPolicyRequest) String() string { func (*DeleteAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *DeleteAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[115] + mi := &file_ateapi_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8301,7 +9107,7 @@ func (x *DeleteAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use DeleteAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*DeleteAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{115} + return file_ateapi_proto_rawDescGZIP(), []int{124} } func (x *DeleteAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -8444,7 +9250,30 @@ const file_ateapi_proto_rawDesc = "" + "\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\"@\n" + + "\fsource_actor\x18\x04 \x01(\v2\x11.ateapi.ObjectRefR\vsourceActor\"\x8b\x04\n" + + "\x0eExternalVolume\x124\n" + + "\bmetadata\x18\x01 \x01(\v2\x18.ateapi.ResourceMetadataR\bmetadata\x12<\n" + + "\x0edelete_trigger\x18\x02 \x01(\x0e2\x15.ateapi.DeleteTriggerR\rdeleteTrigger\x12,\n" + + "\x12storage_class_name\x18\x03 \x01(\tR\x10storageClassName\x12\x1b\n" + + "\tvolume_id\x18\x04 \x01(\tR\bvolumeId\x12\x1f\n" + + "\vvolume_type\x18\x05 \x01(\tR\n" + + "volumeType\x12P\n" + + "\x0evolume_context\x18\x06 \x03(\v2).ateapi.ExternalVolume.VolumeContextEntryR\rvolumeContext\x124\n" + + "\x06status\x18\a \x01(\v2\x1c.ateapi.ExternalVolumeStatusR\x06status\x12\x1a\n" + + "\bcapacity\x18\b \x01(\tR\bcapacity\x123\n" + + "\vaccess_mode\x18\t \x01(\x0e2\x12.ateapi.AccessModeR\n" + + "accessMode\x1a@\n" + + "\x12VolumeContextEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"o\n" + + "\x14ExternalVolumeStatus\x121\n" + + "\x05state\x18\x01 \x01(\x0e2\x1b.ateapi.ExternalVolumeStateR\x05state\x12$\n" + + "\x04refs\x18\x02 \x03(\v2\x10.ateapi.ActorRefR\x04refs\"^\n" + + "\bActorRef\x12\x1b\n" + + "\tactor_uid\x18\x01 \x01(\tR\bactorUid\x12\x1d\n" + + "\n" + + "actor_name\x18\x02 \x01(\tR\tactorName\x12\x16\n" + + "\x06active\x18\x03 \x01(\bR\x06active\"@\n" + "\bAtespace\x124\n" + "\bmetadata\x18\x01 \x01(\v2\x18.ateapi.ResourceMetadataR\bmetadata\";\n" + "\tObjectRef\x12\x1a\n" + @@ -8632,6 +9461,23 @@ const file_ateapi_proto_rawDesc = "" + "\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" + + "\x1bCreateExternalVolumeRequest\x12?\n" + + "\x0fexternal_volume\x18\x01 \x01(\v2\x16.ateapi.ExternalVolumeR\x0eexternalVolume\"V\n" + + "\x18GetExternalVolumeRequest\x12:\n" + + "\x0fexternal_volume\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x0eexternalVolume\"t\n" + + "\x1aListExternalVolumesRequest\x12\x1a\n" + + "\batespace\x18\x01 \x01(\tR\batespace\x12\x1b\n" + + "\tpage_size\x18\x02 \x01(\x05R\bpageSize\x12\x1d\n" + + "\n" + + "page_token\x18\x03 \x01(\tR\tpageToken\"\x88\x01\n" + + "\x1bListExternalVolumesResponse\x12A\n" + + "\x10external_volumes\x18\x01 \x03(\v2\x16.ateapi.ExternalVolumeR\x0fexternalVolumes\x12&\n" + + "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"^\n" + + "\x1bUpdateExternalVolumeRequest\x12?\n" + + "\x0fexternal_volume\x18\x01 \x01(\v2\x16.ateapi.ExternalVolumeR\x0eexternalVolume\"\x8a\x01\n" + + "\x1bDeleteExternalVolumeRequest\x12:\n" + + "\x0fexternal_volume\x18\x01 \x01(\v2\x11.ateapi.ObjectRefR\x0eexternalVolume\x12/\n" + "\aoptions\x18\x02 \x01(\v2\x15.ateapi.DeleteOptionsR\aoptions\";\n" + "\rDeleteOptions\x12\x18\n" + "\aversion\x18\x01 \x01(\x03R\aversion\x12\x10\n" + @@ -8781,7 +9627,20 @@ const file_ateapi_proto_rawDesc = "" + "\x12ACTOR_STATE_PAUSED\x10\x06\x12\x17\n" + "\x13ACTOR_STATE_CRASHED\x10\a\x12\x18\n" + "\x14ACTOR_STATE_DELETING\x10\b\x12\x19\n" + - "\x15ACTOR_STATE_REVERTING\x10\t*b\n" + + "\x15ACTOR_STATE_REVERTING\x10\t*i\n" + + "\rDeleteTrigger\x12\x1e\n" + + "\x1aDELETE_TRIGGER_UNSPECIFIED\x10\x00\x12\x19\n" + + "\x15DELETE_TRIGGER_MANUAL\x10\x01\x12\x1d\n" + + "\x19DELETE_TRIGGER_LAST_ACTOR\x10\x02*k\n" + + "\n" + + "AccessMode\x12\x1b\n" + + "\x17ACCESS_MODE_UNSPECIFIED\x10\x00\x12\x1f\n" + + "\x1bACCESS_MODE_READ_WRITE_ONCE\x10\x01\x12\x1f\n" + + "\x1bACCESS_MODE_READ_WRITE_MANY\x10\x02*\x80\x01\n" + + "\x13ExternalVolumeState\x12%\n" + + "!EXTERNAL_VOLUME_STATE_UNSPECIFIED\x10\x00\x12!\n" + + "\x1dEXTERNAL_VOLUME_STATE_PENDING\x10\x01\x12\x1f\n" + + "\x1bEXTERNAL_VOLUME_STATE_READY\x10\x02*b\n" + "\fSandboxClass\x12\x1d\n" + "\x19SANDBOX_CLASS_UNSPECIFIED\x10\x00\x12\x18\n" + "\x14SANDBOX_CLASS_GVISOR\x10\x01\x12\x19\n" + @@ -8794,7 +9653,7 @@ const file_ateapi_proto_rawDesc = "" + "\vWorkerState\x12\x1c\n" + "\x18WORKER_STATE_UNSPECIFIED\x10\x00\x12\x17\n" + "\x13WORKER_STATE_ACTIVE\x10\x01\x12\x19\n" + - "\x15WORKER_STATE_DRAINING\x10\x022\xfe\x18\n" + + "\x15WORKER_STATE_DRAINING\x10\x022\xb6\x1c\n" + "\aControl\x124\n" + "\bGetActor\x12\x17.ateapi.GetActorRequest\x1a\r.ateapi.Actor\"\x00\x12:\n" + "\vCreateActor\x12\x1a.ateapi.CreateActorRequest\x1a\r.ateapi.Actor\"\x00\x12:\n" + @@ -8815,7 +9674,12 @@ const file_ateapi_proto_rawDesc = "" + "\x06GetTag\x12\x15.ateapi.GetTagRequest\x1a\v.ateapi.Tag\"\x00\x12?\n" + "\bListTags\x12\x17.ateapi.ListTagsRequest\x1a\x18.ateapi.ListTagsResponse\"\x00\x124\n" + "\tUpdateTag\x12\x18.ateapi.UpdateTagRequest\x1a\v.ateapi.Tag\"\x00\x124\n" + - "\tDeleteTag\x12\x18.ateapi.DeleteTagRequest\x1a\v.ateapi.Tag\"\x00\x12H\n" + + "\tDeleteTag\x12\x18.ateapi.DeleteTagRequest\x1a\v.ateapi.Tag\"\x00\x12U\n" + + "\x14CreateExternalVolume\x12#.ateapi.CreateExternalVolumeRequest\x1a\x16.ateapi.ExternalVolume\"\x00\x12O\n" + + "\x11GetExternalVolume\x12 .ateapi.GetExternalVolumeRequest\x1a\x16.ateapi.ExternalVolume\"\x00\x12`\n" + + "\x13ListExternalVolumes\x12\".ateapi.ListExternalVolumesRequest\x1a#.ateapi.ListExternalVolumesResponse\"\x00\x12U\n" + + "\x14UpdateExternalVolume\x12#.ateapi.UpdateExternalVolumeRequest\x1a\x16.ateapi.ExternalVolume\"\x00\x12U\n" + + "\x14DeleteExternalVolume\x12#.ateapi.DeleteExternalVolumeRequest\x1a\x16.ateapi.ExternalVolume\"\x00\x12H\n" + "\vListWorkers\x12\x1a.ateapi.ListWorkersRequest\x1a\x1b.ateapi.ListWorkersResponse\"\x00\x127\n" + "\tGetWorker\x12\x18.ateapi.GetWorkerRequest\x1a\x0e.ateapi.Worker\"\x00\x12=\n" + "\fCreateWorker\x12\x1b.ateapi.CreateWorkerRequest\x1a\x0e.ateapi.Worker\"\x00\x12=\n" + @@ -8857,8 +9721,8 @@ func file_ateapi_proto_rawDescGZIP() []byte { return file_ateapi_proto_rawDescData } -var file_ateapi_proto_enumTypes = make([]protoimpl.EnumInfo, 10) -var file_ateapi_proto_msgTypes = make([]protoimpl.MessageInfo, 120) +var file_ateapi_proto_enumTypes = make([]protoimpl.EnumInfo, 13) +var file_ateapi_proto_msgTypes = make([]protoimpl.MessageInfo, 130) var file_ateapi_proto_goTypes = []any{ (SnapshotOwner)(0), // 0: ateapi.SnapshotOwner (SnapshotDurability)(0), // 1: ateapi.SnapshotDurability @@ -8866,381 +9730,417 @@ var file_ateapi_proto_goTypes = []any{ (SnapshotFidelity)(0), // 3: ateapi.SnapshotFidelity (TagScope)(0), // 4: ateapi.TagScope (ActorState)(0), // 5: ateapi.ActorState - (SandboxClass)(0), // 6: ateapi.SandboxClass - (ActorMetadataField)(0), // 7: ateapi.ActorMetadataField - (WorkerState)(0), // 8: ateapi.WorkerState - (ActorVolumeStatus_Status)(0), // 9: ateapi.ActorVolumeStatus.Status - (*ObjectSnapshot)(nil), // 10: ateapi.ObjectSnapshot - (*LocalSnapshot)(nil), // 11: ateapi.LocalSnapshot - (*SnapshotStorage)(nil), // 12: ateapi.SnapshotStorage - (*Snapshot)(nil), // 13: ateapi.Snapshot - (*Selector)(nil), // 14: ateapi.Selector - (*ResourceMetadata)(nil), // 15: ateapi.ResourceMetadata - (*ActorVolumeStatus)(nil), // 16: ateapi.ActorVolumeStatus - (*Actor)(nil), // 17: ateapi.Actor - (*EgressPolicy)(nil), // 18: ateapi.EgressPolicy - (*EgressRule)(nil), // 19: ateapi.EgressRule - (*HTTPRule)(nil), // 20: ateapi.HTTPRule - (*HTTPSRule)(nil), // 21: ateapi.HTTPSRule - (*TLSPassthroughRule)(nil), // 22: ateapi.TLSPassthroughRule - (*Ports)(nil), // 23: ateapi.Ports - (*AllPorts)(nil), // 24: ateapi.AllPorts - (*HttpRuleEffects)(nil), // 25: ateapi.HttpRuleEffects - (*CredentialHeader)(nil), // 26: ateapi.CredentialHeader - (*ActorJWTSource)(nil), // 27: ateapi.ActorJWTSource - (*ActorStatus)(nil), // 28: ateapi.ActorStatus - (*ActorCrash)(nil), // 29: ateapi.ActorCrash - (*WorkerAssignment)(nil), // 30: ateapi.WorkerAssignment - (*TagStatus)(nil), // 31: ateapi.TagStatus - (*Tag)(nil), // 32: ateapi.Tag - (*Atespace)(nil), // 33: ateapi.Atespace - (*ObjectRef)(nil), // 34: ateapi.ObjectRef - (*ActorTemplate)(nil), // 35: ateapi.ActorTemplate - (*Resources)(nil), // 36: ateapi.Resources - (*Limits)(nil), // 37: ateapi.Limits - (*GoldenSnapshotStatus)(nil), // 38: ateapi.GoldenSnapshotStatus - (*ActorTemplateStatus)(nil), // 39: ateapi.ActorTemplateStatus - (*SandboxConfig)(nil), // 40: ateapi.SandboxConfig - (*SnapshotConfig)(nil), // 41: ateapi.SnapshotConfig - (*Container)(nil), // 42: ateapi.Container - (*SecurityContext)(nil), // 43: ateapi.SecurityContext - (*Capabilities)(nil), // 44: ateapi.Capabilities - (*EnvVar)(nil), // 45: ateapi.EnvVar - (*ContainerWakeupProbe)(nil), // 46: ateapi.ContainerWakeupProbe - (*HTTPGetAction)(nil), // 47: ateapi.HTTPGetAction - (*Volume)(nil), // 48: ateapi.Volume - (*ImageVolumeSource)(nil), // 49: ateapi.ImageVolumeSource - (*DurableDirVolumeSource)(nil), // 50: ateapi.DurableDirVolumeSource - (*ExternalVolumeTemplate)(nil), // 51: ateapi.ExternalVolumeTemplate - (*SystemInfoVolumeSource)(nil), // 52: ateapi.SystemInfoVolumeSource - (*SystemInfoDataSource)(nil), // 53: ateapi.SystemInfoDataSource - (*ActorMetadataDataSource)(nil), // 54: ateapi.ActorMetadataDataSource - (*ActorMetadataItem)(nil), // 55: ateapi.ActorMetadataItem - (*TrustBundleDataSource)(nil), // 56: ateapi.TrustBundleDataSource - (*VolumeMount)(nil), // 57: ateapi.VolumeMount - (*CreateAtespaceRequest)(nil), // 58: ateapi.CreateAtespaceRequest - (*GetAtespaceRequest)(nil), // 59: ateapi.GetAtespaceRequest - (*ListAtespacesRequest)(nil), // 60: ateapi.ListAtespacesRequest - (*ListAtespacesResponse)(nil), // 61: ateapi.ListAtespacesResponse - (*DeleteAtespaceRequest)(nil), // 62: ateapi.DeleteAtespaceRequest - (*CreateActorTemplateRequest)(nil), // 63: ateapi.CreateActorTemplateRequest - (*GetActorTemplateRequest)(nil), // 64: ateapi.GetActorTemplateRequest - (*ListActorTemplatesRequest)(nil), // 65: ateapi.ListActorTemplatesRequest - (*ListActorTemplatesResponse)(nil), // 66: ateapi.ListActorTemplatesResponse - (*DeleteActorTemplateRequest)(nil), // 67: ateapi.DeleteActorTemplateRequest - (*GetActorRequest)(nil), // 68: ateapi.GetActorRequest - (*CreateActorRequest)(nil), // 69: ateapi.CreateActorRequest - (*UpdateActorRequest)(nil), // 70: ateapi.UpdateActorRequest - (*SuspendActorRequest)(nil), // 71: ateapi.SuspendActorRequest - (*SuspendActorResponse)(nil), // 72: ateapi.SuspendActorResponse - (*PauseActorRequest)(nil), // 73: ateapi.PauseActorRequest - (*PauseActorResponse)(nil), // 74: ateapi.PauseActorResponse - (*ResumeActorRequest)(nil), // 75: ateapi.ResumeActorRequest - (*ResumeActorResponse)(nil), // 76: ateapi.ResumeActorResponse - (*RevertActorRequest)(nil), // 77: ateapi.RevertActorRequest - (*RevertActorResponse)(nil), // 78: ateapi.RevertActorResponse - (*DeleteActorRequest)(nil), // 79: ateapi.DeleteActorRequest - (*GetActorEgressPolicyRequest)(nil), // 80: ateapi.GetActorEgressPolicyRequest - (*CreateActorEgressPolicyRequest)(nil), // 81: ateapi.CreateActorEgressPolicyRequest - (*UpdateActorEgressPolicyRequest)(nil), // 82: ateapi.UpdateActorEgressPolicyRequest - (*DeleteActorEgressPolicyRequest)(nil), // 83: ateapi.DeleteActorEgressPolicyRequest - (*GetTagRequest)(nil), // 84: ateapi.GetTagRequest - (*MintActorJWTRequest)(nil), // 85: ateapi.MintActorJWTRequest - (*MintActorJWTResponse)(nil), // 86: ateapi.MintActorJWTResponse - (*MintActorCertificateRequest)(nil), // 87: ateapi.MintActorCertificateRequest - (*MintActorCertificateResponse)(nil), // 88: ateapi.MintActorCertificateResponse - (*ListTagsRequest)(nil), // 89: ateapi.ListTagsRequest - (*ListTagsResponse)(nil), // 90: ateapi.ListTagsResponse - (*CreateTagRequest)(nil), // 91: ateapi.CreateTagRequest - (*UpdateTagRequest)(nil), // 92: ateapi.UpdateTagRequest - (*DeleteTagRequest)(nil), // 93: ateapi.DeleteTagRequest - (*DeleteOptions)(nil), // 94: ateapi.DeleteOptions - (*ListWorkerActorAssignmentsRequest)(nil), // 95: ateapi.ListWorkerActorAssignmentsRequest - (*ListWorkerActorAssignmentsResponse)(nil), // 96: ateapi.ListWorkerActorAssignmentsResponse - (*ListWorkersRequest)(nil), // 97: ateapi.ListWorkersRequest - (*ListWorkersResponse)(nil), // 98: ateapi.ListWorkersResponse - (*GetWorkerRequest)(nil), // 99: ateapi.GetWorkerRequest - (*CreateWorkerRequest)(nil), // 100: ateapi.CreateWorkerRequest - (*UpdateWorkerRequest)(nil), // 101: ateapi.UpdateWorkerRequest - (*DeleteWorkerRequest)(nil), // 102: ateapi.DeleteWorkerRequest - (*DrainWorkerRequest)(nil), // 103: ateapi.DrainWorkerRequest - (*ListActorsRequest)(nil), // 104: ateapi.ListActorsRequest - (*ListActorsResponse)(nil), // 105: ateapi.ListActorsResponse - (*Worker)(nil), // 106: ateapi.Worker - (*WorkerStatus)(nil), // 107: ateapi.WorkerStatus - (*HardwareIdentity)(nil), // 108: ateapi.HardwareIdentity - (*WorkerResources)(nil), // 109: ateapi.WorkerResources - (*ActorAssignment)(nil), // 110: ateapi.ActorAssignment - (*RegisterWorkerRequest)(nil), // 111: ateapi.RegisterWorkerRequest - (*RegisterWorkerResponse)(nil), // 112: ateapi.RegisterWorkerResponse - (*MintAteomActorCertificateRequest)(nil), // 113: ateapi.MintAteomActorCertificateRequest - (*MintAteomActorCertificateResponse)(nil), // 114: ateapi.MintAteomActorCertificateResponse - (*RequestActorSuspendRequest)(nil), // 115: ateapi.RequestActorSuspendRequest - (*RequestActorSuspendResponse)(nil), // 116: ateapi.RequestActorSuspendResponse - (*AccessPolicy)(nil), // 117: ateapi.AccessPolicy - (*Binding)(nil), // 118: ateapi.Binding - (*GetGlobalAccessPolicyRequest)(nil), // 119: ateapi.GetGlobalAccessPolicyRequest - (*CreateGlobalAccessPolicyRequest)(nil), // 120: ateapi.CreateGlobalAccessPolicyRequest - (*UpdateGlobalAccessPolicyRequest)(nil), // 121: ateapi.UpdateGlobalAccessPolicyRequest - (*GetAtespaceAccessPolicyRequest)(nil), // 122: ateapi.GetAtespaceAccessPolicyRequest - (*CreateAtespaceAccessPolicyRequest)(nil), // 123: ateapi.CreateAtespaceAccessPolicyRequest - (*UpdateAtespaceAccessPolicyRequest)(nil), // 124: ateapi.UpdateAtespaceAccessPolicyRequest - (*DeleteAtespaceAccessPolicyRequest)(nil), // 125: ateapi.DeleteAtespaceAccessPolicyRequest - nil, // 126: ateapi.Selector.MatchLabelsEntry - nil, // 127: ateapi.ActorVolumeStatus.VolumeContextEntry - nil, // 128: ateapi.Worker.LabelsEntry - nil, // 129: ateapi.HardwareIdentity.AttributesEntry - (*timestamppb.Timestamp)(nil), // 130: google.protobuf.Timestamp + (DeleteTrigger)(0), // 6: ateapi.DeleteTrigger + (AccessMode)(0), // 7: ateapi.AccessMode + (ExternalVolumeState)(0), // 8: ateapi.ExternalVolumeState + (SandboxClass)(0), // 9: ateapi.SandboxClass + (ActorMetadataField)(0), // 10: ateapi.ActorMetadataField + (WorkerState)(0), // 11: ateapi.WorkerState + (ActorVolumeStatus_Status)(0), // 12: ateapi.ActorVolumeStatus.Status + (*ObjectSnapshot)(nil), // 13: ateapi.ObjectSnapshot + (*LocalSnapshot)(nil), // 14: ateapi.LocalSnapshot + (*SnapshotStorage)(nil), // 15: ateapi.SnapshotStorage + (*Snapshot)(nil), // 16: ateapi.Snapshot + (*Selector)(nil), // 17: ateapi.Selector + (*ResourceMetadata)(nil), // 18: ateapi.ResourceMetadata + (*ActorVolumeStatus)(nil), // 19: ateapi.ActorVolumeStatus + (*Actor)(nil), // 20: ateapi.Actor + (*EgressPolicy)(nil), // 21: ateapi.EgressPolicy + (*EgressRule)(nil), // 22: ateapi.EgressRule + (*HTTPRule)(nil), // 23: ateapi.HTTPRule + (*HTTPSRule)(nil), // 24: ateapi.HTTPSRule + (*TLSPassthroughRule)(nil), // 25: ateapi.TLSPassthroughRule + (*Ports)(nil), // 26: ateapi.Ports + (*AllPorts)(nil), // 27: ateapi.AllPorts + (*HttpRuleEffects)(nil), // 28: ateapi.HttpRuleEffects + (*CredentialHeader)(nil), // 29: ateapi.CredentialHeader + (*ActorJWTSource)(nil), // 30: ateapi.ActorJWTSource + (*ActorStatus)(nil), // 31: ateapi.ActorStatus + (*ActorCrash)(nil), // 32: ateapi.ActorCrash + (*WorkerAssignment)(nil), // 33: ateapi.WorkerAssignment + (*TagStatus)(nil), // 34: ateapi.TagStatus + (*Tag)(nil), // 35: ateapi.Tag + (*ExternalVolume)(nil), // 36: ateapi.ExternalVolume + (*ExternalVolumeStatus)(nil), // 37: ateapi.ExternalVolumeStatus + (*ActorRef)(nil), // 38: ateapi.ActorRef + (*Atespace)(nil), // 39: ateapi.Atespace + (*ObjectRef)(nil), // 40: ateapi.ObjectRef + (*ActorTemplate)(nil), // 41: ateapi.ActorTemplate + (*Resources)(nil), // 42: ateapi.Resources + (*Limits)(nil), // 43: ateapi.Limits + (*GoldenSnapshotStatus)(nil), // 44: ateapi.GoldenSnapshotStatus + (*ActorTemplateStatus)(nil), // 45: ateapi.ActorTemplateStatus + (*SandboxConfig)(nil), // 46: ateapi.SandboxConfig + (*SnapshotConfig)(nil), // 47: ateapi.SnapshotConfig + (*Container)(nil), // 48: ateapi.Container + (*SecurityContext)(nil), // 49: ateapi.SecurityContext + (*Capabilities)(nil), // 50: ateapi.Capabilities + (*EnvVar)(nil), // 51: ateapi.EnvVar + (*ContainerWakeupProbe)(nil), // 52: ateapi.ContainerWakeupProbe + (*HTTPGetAction)(nil), // 53: ateapi.HTTPGetAction + (*Volume)(nil), // 54: ateapi.Volume + (*ImageVolumeSource)(nil), // 55: ateapi.ImageVolumeSource + (*DurableDirVolumeSource)(nil), // 56: ateapi.DurableDirVolumeSource + (*ExternalVolumeTemplate)(nil), // 57: ateapi.ExternalVolumeTemplate + (*SystemInfoVolumeSource)(nil), // 58: ateapi.SystemInfoVolumeSource + (*SystemInfoDataSource)(nil), // 59: ateapi.SystemInfoDataSource + (*ActorMetadataDataSource)(nil), // 60: ateapi.ActorMetadataDataSource + (*ActorMetadataItem)(nil), // 61: ateapi.ActorMetadataItem + (*TrustBundleDataSource)(nil), // 62: ateapi.TrustBundleDataSource + (*VolumeMount)(nil), // 63: ateapi.VolumeMount + (*CreateAtespaceRequest)(nil), // 64: ateapi.CreateAtespaceRequest + (*GetAtespaceRequest)(nil), // 65: ateapi.GetAtespaceRequest + (*ListAtespacesRequest)(nil), // 66: ateapi.ListAtespacesRequest + (*ListAtespacesResponse)(nil), // 67: ateapi.ListAtespacesResponse + (*DeleteAtespaceRequest)(nil), // 68: ateapi.DeleteAtespaceRequest + (*CreateActorTemplateRequest)(nil), // 69: ateapi.CreateActorTemplateRequest + (*GetActorTemplateRequest)(nil), // 70: ateapi.GetActorTemplateRequest + (*ListActorTemplatesRequest)(nil), // 71: ateapi.ListActorTemplatesRequest + (*ListActorTemplatesResponse)(nil), // 72: ateapi.ListActorTemplatesResponse + (*DeleteActorTemplateRequest)(nil), // 73: ateapi.DeleteActorTemplateRequest + (*GetActorRequest)(nil), // 74: ateapi.GetActorRequest + (*CreateActorRequest)(nil), // 75: ateapi.CreateActorRequest + (*UpdateActorRequest)(nil), // 76: ateapi.UpdateActorRequest + (*SuspendActorRequest)(nil), // 77: ateapi.SuspendActorRequest + (*SuspendActorResponse)(nil), // 78: ateapi.SuspendActorResponse + (*PauseActorRequest)(nil), // 79: ateapi.PauseActorRequest + (*PauseActorResponse)(nil), // 80: ateapi.PauseActorResponse + (*ResumeActorRequest)(nil), // 81: ateapi.ResumeActorRequest + (*ResumeActorResponse)(nil), // 82: ateapi.ResumeActorResponse + (*RevertActorRequest)(nil), // 83: ateapi.RevertActorRequest + (*RevertActorResponse)(nil), // 84: ateapi.RevertActorResponse + (*DeleteActorRequest)(nil), // 85: ateapi.DeleteActorRequest + (*GetActorEgressPolicyRequest)(nil), // 86: ateapi.GetActorEgressPolicyRequest + (*CreateActorEgressPolicyRequest)(nil), // 87: ateapi.CreateActorEgressPolicyRequest + (*UpdateActorEgressPolicyRequest)(nil), // 88: ateapi.UpdateActorEgressPolicyRequest + (*DeleteActorEgressPolicyRequest)(nil), // 89: ateapi.DeleteActorEgressPolicyRequest + (*GetTagRequest)(nil), // 90: ateapi.GetTagRequest + (*MintActorJWTRequest)(nil), // 91: ateapi.MintActorJWTRequest + (*MintActorJWTResponse)(nil), // 92: ateapi.MintActorJWTResponse + (*MintActorCertificateRequest)(nil), // 93: ateapi.MintActorCertificateRequest + (*MintActorCertificateResponse)(nil), // 94: ateapi.MintActorCertificateResponse + (*ListTagsRequest)(nil), // 95: ateapi.ListTagsRequest + (*ListTagsResponse)(nil), // 96: ateapi.ListTagsResponse + (*CreateTagRequest)(nil), // 97: ateapi.CreateTagRequest + (*UpdateTagRequest)(nil), // 98: ateapi.UpdateTagRequest + (*DeleteTagRequest)(nil), // 99: ateapi.DeleteTagRequest + (*CreateExternalVolumeRequest)(nil), // 100: ateapi.CreateExternalVolumeRequest + (*GetExternalVolumeRequest)(nil), // 101: ateapi.GetExternalVolumeRequest + (*ListExternalVolumesRequest)(nil), // 102: ateapi.ListExternalVolumesRequest + (*ListExternalVolumesResponse)(nil), // 103: ateapi.ListExternalVolumesResponse + (*UpdateExternalVolumeRequest)(nil), // 104: ateapi.UpdateExternalVolumeRequest + (*DeleteExternalVolumeRequest)(nil), // 105: ateapi.DeleteExternalVolumeRequest + (*DeleteOptions)(nil), // 106: ateapi.DeleteOptions + (*ListWorkerActorAssignmentsRequest)(nil), // 107: ateapi.ListWorkerActorAssignmentsRequest + (*ListWorkerActorAssignmentsResponse)(nil), // 108: ateapi.ListWorkerActorAssignmentsResponse + (*ListWorkersRequest)(nil), // 109: ateapi.ListWorkersRequest + (*ListWorkersResponse)(nil), // 110: ateapi.ListWorkersResponse + (*GetWorkerRequest)(nil), // 111: ateapi.GetWorkerRequest + (*CreateWorkerRequest)(nil), // 112: ateapi.CreateWorkerRequest + (*UpdateWorkerRequest)(nil), // 113: ateapi.UpdateWorkerRequest + (*DeleteWorkerRequest)(nil), // 114: ateapi.DeleteWorkerRequest + (*DrainWorkerRequest)(nil), // 115: ateapi.DrainWorkerRequest + (*ListActorsRequest)(nil), // 116: ateapi.ListActorsRequest + (*ListActorsResponse)(nil), // 117: ateapi.ListActorsResponse + (*Worker)(nil), // 118: ateapi.Worker + (*WorkerStatus)(nil), // 119: ateapi.WorkerStatus + (*HardwareIdentity)(nil), // 120: ateapi.HardwareIdentity + (*WorkerResources)(nil), // 121: ateapi.WorkerResources + (*ActorAssignment)(nil), // 122: ateapi.ActorAssignment + (*RegisterWorkerRequest)(nil), // 123: ateapi.RegisterWorkerRequest + (*RegisterWorkerResponse)(nil), // 124: ateapi.RegisterWorkerResponse + (*MintAteomActorCertificateRequest)(nil), // 125: ateapi.MintAteomActorCertificateRequest + (*MintAteomActorCertificateResponse)(nil), // 126: ateapi.MintAteomActorCertificateResponse + (*RequestActorSuspendRequest)(nil), // 127: ateapi.RequestActorSuspendRequest + (*RequestActorSuspendResponse)(nil), // 128: ateapi.RequestActorSuspendResponse + (*AccessPolicy)(nil), // 129: ateapi.AccessPolicy + (*Binding)(nil), // 130: ateapi.Binding + (*GetGlobalAccessPolicyRequest)(nil), // 131: ateapi.GetGlobalAccessPolicyRequest + (*CreateGlobalAccessPolicyRequest)(nil), // 132: ateapi.CreateGlobalAccessPolicyRequest + (*UpdateGlobalAccessPolicyRequest)(nil), // 133: ateapi.UpdateGlobalAccessPolicyRequest + (*GetAtespaceAccessPolicyRequest)(nil), // 134: ateapi.GetAtespaceAccessPolicyRequest + (*CreateAtespaceAccessPolicyRequest)(nil), // 135: ateapi.CreateAtespaceAccessPolicyRequest + (*UpdateAtespaceAccessPolicyRequest)(nil), // 136: ateapi.UpdateAtespaceAccessPolicyRequest + (*DeleteAtespaceAccessPolicyRequest)(nil), // 137: ateapi.DeleteAtespaceAccessPolicyRequest + nil, // 138: ateapi.Selector.MatchLabelsEntry + nil, // 139: ateapi.ActorVolumeStatus.VolumeContextEntry + nil, // 140: ateapi.ExternalVolume.VolumeContextEntry + nil, // 141: ateapi.Worker.LabelsEntry + nil, // 142: ateapi.HardwareIdentity.AttributesEntry + (*timestamppb.Timestamp)(nil), // 143: google.protobuf.Timestamp } var file_ateapi_proto_depIdxs = []int32{ 1, // 0: ateapi.SnapshotStorage.durability:type_name -> ateapi.SnapshotDurability 2, // 1: ateapi.SnapshotStorage.status:type_name -> ateapi.SnapshotStorageStatus 3, // 2: ateapi.SnapshotStorage.fidelity:type_name -> ateapi.SnapshotFidelity - 11, // 3: ateapi.SnapshotStorage.local:type_name -> ateapi.LocalSnapshot - 10, // 4: ateapi.SnapshotStorage.object:type_name -> ateapi.ObjectSnapshot + 14, // 3: ateapi.SnapshotStorage.local:type_name -> ateapi.LocalSnapshot + 13, // 4: ateapi.SnapshotStorage.object:type_name -> ateapi.ObjectSnapshot 0, // 5: ateapi.Snapshot.owner:type_name -> ateapi.SnapshotOwner - 12, // 6: ateapi.Snapshot.storage:type_name -> ateapi.SnapshotStorage - 126, // 7: ateapi.Selector.match_labels:type_name -> ateapi.Selector.MatchLabelsEntry - 130, // 8: ateapi.ResourceMetadata.create_time:type_name -> google.protobuf.Timestamp - 130, // 9: ateapi.ResourceMetadata.update_time:type_name -> google.protobuf.Timestamp - 9, // 10: ateapi.ActorVolumeStatus.status:type_name -> ateapi.ActorVolumeStatus.Status - 127, // 11: ateapi.ActorVolumeStatus.volume_context:type_name -> ateapi.ActorVolumeStatus.VolumeContextEntry - 15, // 12: ateapi.Actor.metadata:type_name -> ateapi.ResourceMetadata - 34, // 13: ateapi.Actor.actor_template:type_name -> ateapi.ObjectRef - 14, // 14: ateapi.Actor.worker_selector:type_name -> ateapi.Selector - 34, // 15: ateapi.Actor.source_tag:type_name -> ateapi.ObjectRef - 28, // 16: ateapi.Actor.status:type_name -> ateapi.ActorStatus - 15, // 17: ateapi.EgressPolicy.metadata:type_name -> ateapi.ResourceMetadata - 19, // 18: ateapi.EgressPolicy.rules:type_name -> ateapi.EgressRule - 20, // 19: ateapi.EgressRule.http:type_name -> ateapi.HTTPRule - 21, // 20: ateapi.EgressRule.https:type_name -> ateapi.HTTPSRule - 22, // 21: ateapi.EgressRule.tls_passthrough:type_name -> ateapi.TLSPassthroughRule - 23, // 22: ateapi.HTTPRule.ports:type_name -> ateapi.Ports - 25, // 23: ateapi.HTTPRule.effects:type_name -> ateapi.HttpRuleEffects - 23, // 24: ateapi.HTTPSRule.ports:type_name -> ateapi.Ports - 25, // 25: ateapi.HTTPSRule.effects:type_name -> ateapi.HttpRuleEffects - 23, // 26: ateapi.TLSPassthroughRule.ports:type_name -> ateapi.Ports - 24, // 27: ateapi.Ports.all:type_name -> ateapi.AllPorts - 26, // 28: ateapi.HttpRuleEffects.replace_headers:type_name -> ateapi.CredentialHeader - 27, // 29: ateapi.CredentialHeader.actor_jwt:type_name -> ateapi.ActorJWTSource + 15, // 6: ateapi.Snapshot.storage:type_name -> ateapi.SnapshotStorage + 138, // 7: ateapi.Selector.match_labels:type_name -> ateapi.Selector.MatchLabelsEntry + 143, // 8: ateapi.ResourceMetadata.create_time:type_name -> google.protobuf.Timestamp + 143, // 9: ateapi.ResourceMetadata.update_time:type_name -> google.protobuf.Timestamp + 12, // 10: ateapi.ActorVolumeStatus.status:type_name -> ateapi.ActorVolumeStatus.Status + 139, // 11: ateapi.ActorVolumeStatus.volume_context:type_name -> ateapi.ActorVolumeStatus.VolumeContextEntry + 18, // 12: ateapi.Actor.metadata:type_name -> ateapi.ResourceMetadata + 40, // 13: ateapi.Actor.actor_template:type_name -> ateapi.ObjectRef + 17, // 14: ateapi.Actor.worker_selector:type_name -> ateapi.Selector + 40, // 15: ateapi.Actor.source_tag:type_name -> ateapi.ObjectRef + 31, // 16: ateapi.Actor.status:type_name -> ateapi.ActorStatus + 18, // 17: ateapi.EgressPolicy.metadata:type_name -> ateapi.ResourceMetadata + 22, // 18: ateapi.EgressPolicy.rules:type_name -> ateapi.EgressRule + 23, // 19: ateapi.EgressRule.http:type_name -> ateapi.HTTPRule + 24, // 20: ateapi.EgressRule.https:type_name -> ateapi.HTTPSRule + 25, // 21: ateapi.EgressRule.tls_passthrough:type_name -> ateapi.TLSPassthroughRule + 26, // 22: ateapi.HTTPRule.ports:type_name -> ateapi.Ports + 28, // 23: ateapi.HTTPRule.effects:type_name -> ateapi.HttpRuleEffects + 26, // 24: ateapi.HTTPSRule.ports:type_name -> ateapi.Ports + 28, // 25: ateapi.HTTPSRule.effects:type_name -> ateapi.HttpRuleEffects + 26, // 26: ateapi.TLSPassthroughRule.ports:type_name -> ateapi.Ports + 27, // 27: ateapi.Ports.all:type_name -> ateapi.AllPorts + 29, // 28: ateapi.HttpRuleEffects.replace_headers:type_name -> ateapi.CredentialHeader + 30, // 29: ateapi.CredentialHeader.actor_jwt:type_name -> ateapi.ActorJWTSource 5, // 30: ateapi.ActorStatus.state:type_name -> ateapi.ActorState - 30, // 31: ateapi.ActorStatus.worker_assignment:type_name -> ateapi.WorkerAssignment - 16, // 32: ateapi.ActorStatus.external_volumes:type_name -> ateapi.ActorVolumeStatus - 29, // 33: ateapi.ActorStatus.crash:type_name -> ateapi.ActorCrash - 13, // 34: ateapi.ActorStatus.snapshots:type_name -> ateapi.Snapshot - 130, // 35: ateapi.ActorCrash.crash_time:type_name -> google.protobuf.Timestamp - 34, // 36: ateapi.WorkerAssignment.worker:type_name -> ateapi.ObjectRef - 13, // 37: ateapi.TagStatus.snapshot:type_name -> ateapi.Snapshot - 15, // 38: ateapi.Tag.metadata:type_name -> ateapi.ResourceMetadata - 31, // 39: ateapi.Tag.status:type_name -> ateapi.TagStatus + 33, // 31: ateapi.ActorStatus.worker_assignment:type_name -> ateapi.WorkerAssignment + 19, // 32: ateapi.ActorStatus.external_volumes:type_name -> ateapi.ActorVolumeStatus + 32, // 33: ateapi.ActorStatus.crash:type_name -> ateapi.ActorCrash + 16, // 34: ateapi.ActorStatus.snapshots:type_name -> ateapi.Snapshot + 143, // 35: ateapi.ActorCrash.crash_time:type_name -> google.protobuf.Timestamp + 40, // 36: ateapi.WorkerAssignment.worker:type_name -> ateapi.ObjectRef + 16, // 37: ateapi.TagStatus.snapshot:type_name -> ateapi.Snapshot + 18, // 38: ateapi.Tag.metadata:type_name -> ateapi.ResourceMetadata + 34, // 39: ateapi.Tag.status:type_name -> ateapi.TagStatus 4, // 40: ateapi.Tag.scope:type_name -> ateapi.TagScope - 34, // 41: ateapi.Tag.source_actor:type_name -> ateapi.ObjectRef - 15, // 42: ateapi.Atespace.metadata:type_name -> ateapi.ResourceMetadata - 15, // 43: ateapi.ActorTemplate.metadata:type_name -> ateapi.ResourceMetadata - 14, // 44: ateapi.ActorTemplate.worker_selector:type_name -> ateapi.Selector - 42, // 45: ateapi.ActorTemplate.containers:type_name -> ateapi.Container - 48, // 46: ateapi.ActorTemplate.volumes:type_name -> ateapi.Volume - 41, // 47: ateapi.ActorTemplate.snapshot_config:type_name -> ateapi.SnapshotConfig - 40, // 48: ateapi.ActorTemplate.sandbox_config:type_name -> ateapi.SandboxConfig - 36, // 49: ateapi.ActorTemplate.resources:type_name -> ateapi.Resources - 39, // 50: ateapi.ActorTemplate.status:type_name -> ateapi.ActorTemplateStatus - 37, // 51: ateapi.Resources.limits:type_name -> ateapi.Limits - 34, // 52: ateapi.GoldenSnapshotStatus.golden_tag:type_name -> ateapi.ObjectRef - 130, // 53: ateapi.GoldenSnapshotStatus.take_golden_snapshot_at:type_name -> google.protobuf.Timestamp - 38, // 54: ateapi.ActorTemplateStatus.golden_snapshot_status:type_name -> ateapi.GoldenSnapshotStatus - 6, // 55: ateapi.SandboxConfig.sandbox_class:type_name -> ateapi.SandboxClass - 3, // 56: ateapi.SnapshotConfig.preferred_fidelity:type_name -> ateapi.SnapshotFidelity - 45, // 57: ateapi.Container.env:type_name -> ateapi.EnvVar - 46, // 58: ateapi.Container.wakeup_probe:type_name -> ateapi.ContainerWakeupProbe - 57, // 59: ateapi.Container.volume_mounts:type_name -> ateapi.VolumeMount - 43, // 60: ateapi.Container.security_context:type_name -> ateapi.SecurityContext - 36, // 61: ateapi.Container.resources:type_name -> ateapi.Resources - 44, // 62: ateapi.SecurityContext.capabilities:type_name -> ateapi.Capabilities - 47, // 63: ateapi.ContainerWakeupProbe.http_get:type_name -> ateapi.HTTPGetAction - 50, // 64: ateapi.Volume.durable_dir:type_name -> ateapi.DurableDirVolumeSource - 51, // 65: ateapi.Volume.external_volume_template:type_name -> ateapi.ExternalVolumeTemplate - 52, // 66: ateapi.Volume.system_info:type_name -> ateapi.SystemInfoVolumeSource - 49, // 67: ateapi.Volume.image:type_name -> ateapi.ImageVolumeSource - 53, // 68: ateapi.SystemInfoVolumeSource.data_sources:type_name -> ateapi.SystemInfoDataSource - 54, // 69: ateapi.SystemInfoDataSource.actor_metadata:type_name -> ateapi.ActorMetadataDataSource - 56, // 70: ateapi.SystemInfoDataSource.trust_bundle:type_name -> ateapi.TrustBundleDataSource - 55, // 71: ateapi.ActorMetadataDataSource.items:type_name -> ateapi.ActorMetadataItem - 7, // 72: ateapi.ActorMetadataItem.field:type_name -> ateapi.ActorMetadataField - 33, // 73: ateapi.CreateAtespaceRequest.atespace:type_name -> ateapi.Atespace - 34, // 74: ateapi.GetAtespaceRequest.atespace:type_name -> ateapi.ObjectRef - 33, // 75: ateapi.ListAtespacesResponse.atespaces:type_name -> ateapi.Atespace - 34, // 76: ateapi.DeleteAtespaceRequest.atespace:type_name -> ateapi.ObjectRef - 94, // 77: ateapi.DeleteAtespaceRequest.options:type_name -> ateapi.DeleteOptions - 35, // 78: ateapi.CreateActorTemplateRequest.actor_template:type_name -> ateapi.ActorTemplate - 34, // 79: ateapi.GetActorTemplateRequest.actor_template:type_name -> ateapi.ObjectRef - 35, // 80: ateapi.ListActorTemplatesResponse.actor_templates:type_name -> ateapi.ActorTemplate - 34, // 81: ateapi.DeleteActorTemplateRequest.actor_template:type_name -> ateapi.ObjectRef - 94, // 82: ateapi.DeleteActorTemplateRequest.options:type_name -> ateapi.DeleteOptions - 34, // 83: ateapi.GetActorRequest.actor:type_name -> ateapi.ObjectRef - 17, // 84: ateapi.CreateActorRequest.actor:type_name -> ateapi.Actor - 17, // 85: ateapi.UpdateActorRequest.actor:type_name -> ateapi.Actor - 34, // 86: ateapi.SuspendActorRequest.actor:type_name -> ateapi.ObjectRef - 17, // 87: ateapi.SuspendActorResponse.actor:type_name -> ateapi.Actor - 34, // 88: ateapi.PauseActorRequest.actor:type_name -> ateapi.ObjectRef - 17, // 89: ateapi.PauseActorResponse.actor:type_name -> ateapi.Actor - 34, // 90: ateapi.ResumeActorRequest.actor:type_name -> ateapi.ObjectRef - 17, // 91: ateapi.ResumeActorResponse.actor:type_name -> ateapi.Actor - 34, // 92: ateapi.RevertActorRequest.actor:type_name -> ateapi.ObjectRef - 17, // 93: ateapi.RevertActorResponse.actor:type_name -> ateapi.Actor - 34, // 94: ateapi.DeleteActorRequest.actor:type_name -> ateapi.ObjectRef - 94, // 95: ateapi.DeleteActorRequest.options:type_name -> ateapi.DeleteOptions - 34, // 96: ateapi.GetActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef - 34, // 97: ateapi.CreateActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef - 18, // 98: ateapi.CreateActorEgressPolicyRequest.egress_policy:type_name -> ateapi.EgressPolicy - 34, // 99: ateapi.UpdateActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef - 18, // 100: ateapi.UpdateActorEgressPolicyRequest.egress_policy:type_name -> ateapi.EgressPolicy - 34, // 101: ateapi.DeleteActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef - 94, // 102: ateapi.DeleteActorEgressPolicyRequest.options:type_name -> ateapi.DeleteOptions - 34, // 103: ateapi.GetTagRequest.tag:type_name -> ateapi.ObjectRef - 34, // 104: ateapi.MintActorJWTRequest.actor:type_name -> ateapi.ObjectRef - 130, // 105: ateapi.MintActorJWTResponse.expires_at:type_name -> google.protobuf.Timestamp - 34, // 106: ateapi.MintActorCertificateRequest.actor:type_name -> ateapi.ObjectRef - 32, // 107: ateapi.ListTagsResponse.tags:type_name -> ateapi.Tag - 32, // 108: ateapi.CreateTagRequest.tag:type_name -> ateapi.Tag - 32, // 109: ateapi.UpdateTagRequest.tag:type_name -> ateapi.Tag - 34, // 110: ateapi.DeleteTagRequest.tag:type_name -> ateapi.ObjectRef - 94, // 111: ateapi.DeleteTagRequest.options:type_name -> ateapi.DeleteOptions - 34, // 112: ateapi.ListWorkerActorAssignmentsRequest.worker:type_name -> ateapi.ObjectRef - 110, // 113: ateapi.ListWorkerActorAssignmentsResponse.actor_assignments:type_name -> ateapi.ActorAssignment - 106, // 114: ateapi.ListWorkersResponse.workers:type_name -> ateapi.Worker - 34, // 115: ateapi.GetWorkerRequest.worker:type_name -> ateapi.ObjectRef - 106, // 116: ateapi.CreateWorkerRequest.worker:type_name -> ateapi.Worker - 106, // 117: ateapi.UpdateWorkerRequest.worker:type_name -> ateapi.Worker - 34, // 118: ateapi.DeleteWorkerRequest.worker:type_name -> ateapi.ObjectRef - 94, // 119: ateapi.DeleteWorkerRequest.options:type_name -> ateapi.DeleteOptions - 34, // 120: ateapi.DrainWorkerRequest.worker:type_name -> ateapi.ObjectRef - 17, // 121: ateapi.ListActorsResponse.actors:type_name -> ateapi.Actor - 15, // 122: ateapi.Worker.metadata:type_name -> ateapi.ResourceMetadata - 128, // 123: ateapi.Worker.labels:type_name -> ateapi.Worker.LabelsEntry - 107, // 124: ateapi.Worker.status:type_name -> ateapi.WorkerStatus - 8, // 125: ateapi.WorkerStatus.state:type_name -> ateapi.WorkerState - 109, // 126: ateapi.WorkerStatus.capacity:type_name -> ateapi.WorkerResources - 109, // 127: ateapi.WorkerStatus.allocated:type_name -> ateapi.WorkerResources - 108, // 128: ateapi.WorkerStatus.hardware:type_name -> ateapi.HardwareIdentity - 129, // 129: ateapi.HardwareIdentity.attributes:type_name -> ateapi.HardwareIdentity.AttributesEntry - 36, // 130: ateapi.WorkerResources.resources:type_name -> ateapi.Resources - 15, // 131: ateapi.ActorAssignment.metadata:type_name -> ateapi.ResourceMetadata - 34, // 132: ateapi.ActorAssignment.actor:type_name -> ateapi.ObjectRef - 36, // 133: ateapi.ActorAssignment.resources:type_name -> ateapi.Resources - 34, // 134: ateapi.RegisterWorkerRequest.worker:type_name -> ateapi.ObjectRef - 109, // 135: ateapi.RegisterWorkerRequest.capacity:type_name -> ateapi.WorkerResources - 108, // 136: ateapi.RegisterWorkerRequest.hardware:type_name -> ateapi.HardwareIdentity - 106, // 137: ateapi.RegisterWorkerResponse.worker:type_name -> ateapi.Worker - 34, // 138: ateapi.MintAteomActorCertificateRequest.actor:type_name -> ateapi.ObjectRef - 34, // 139: ateapi.RequestActorSuspendRequest.worker:type_name -> ateapi.ObjectRef - 34, // 140: ateapi.RequestActorSuspendRequest.actor:type_name -> ateapi.ObjectRef - 17, // 141: ateapi.RequestActorSuspendResponse.actor:type_name -> ateapi.Actor - 15, // 142: ateapi.AccessPolicy.metadata:type_name -> ateapi.ResourceMetadata - 118, // 143: ateapi.AccessPolicy.bindings:type_name -> ateapi.Binding - 117, // 144: ateapi.CreateGlobalAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy - 117, // 145: ateapi.UpdateGlobalAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy - 34, // 146: ateapi.GetAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef - 34, // 147: ateapi.CreateAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef - 117, // 148: ateapi.CreateAtespaceAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy - 34, // 149: ateapi.UpdateAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef - 117, // 150: ateapi.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy - 34, // 151: ateapi.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef - 94, // 152: ateapi.DeleteAtespaceAccessPolicyRequest.options:type_name -> ateapi.DeleteOptions - 68, // 153: ateapi.Control.GetActor:input_type -> ateapi.GetActorRequest - 69, // 154: ateapi.Control.CreateActor:input_type -> ateapi.CreateActorRequest - 70, // 155: ateapi.Control.UpdateActor:input_type -> ateapi.UpdateActorRequest - 71, // 156: ateapi.Control.SuspendActor:input_type -> ateapi.SuspendActorRequest - 73, // 157: ateapi.Control.PauseActor:input_type -> ateapi.PauseActorRequest - 75, // 158: ateapi.Control.ResumeActor:input_type -> ateapi.ResumeActorRequest - 77, // 159: ateapi.Control.RevertActor:input_type -> ateapi.RevertActorRequest - 79, // 160: ateapi.Control.DeleteActor:input_type -> ateapi.DeleteActorRequest - 80, // 161: ateapi.Control.GetActorEgressPolicy:input_type -> ateapi.GetActorEgressPolicyRequest - 81, // 162: ateapi.Control.CreateActorEgressPolicy:input_type -> ateapi.CreateActorEgressPolicyRequest - 82, // 163: ateapi.Control.UpdateActorEgressPolicy:input_type -> ateapi.UpdateActorEgressPolicyRequest - 83, // 164: ateapi.Control.DeleteActorEgressPolicy:input_type -> ateapi.DeleteActorEgressPolicyRequest - 85, // 165: ateapi.Control.MintActorJWT:input_type -> ateapi.MintActorJWTRequest - 87, // 166: ateapi.Control.MintActorCertificate:input_type -> ateapi.MintActorCertificateRequest - 91, // 167: ateapi.Control.CreateTag:input_type -> ateapi.CreateTagRequest - 84, // 168: ateapi.Control.GetTag:input_type -> ateapi.GetTagRequest - 89, // 169: ateapi.Control.ListTags:input_type -> ateapi.ListTagsRequest - 92, // 170: ateapi.Control.UpdateTag:input_type -> ateapi.UpdateTagRequest - 93, // 171: ateapi.Control.DeleteTag:input_type -> ateapi.DeleteTagRequest - 97, // 172: ateapi.Control.ListWorkers:input_type -> ateapi.ListWorkersRequest - 99, // 173: ateapi.Control.GetWorker:input_type -> ateapi.GetWorkerRequest - 100, // 174: ateapi.Control.CreateWorker:input_type -> ateapi.CreateWorkerRequest - 101, // 175: ateapi.Control.UpdateWorker:input_type -> ateapi.UpdateWorkerRequest - 102, // 176: ateapi.Control.DeleteWorker:input_type -> ateapi.DeleteWorkerRequest - 103, // 177: ateapi.Control.DrainWorker:input_type -> ateapi.DrainWorkerRequest - 95, // 178: ateapi.Control.ListWorkerActorAssignments:input_type -> ateapi.ListWorkerActorAssignmentsRequest - 104, // 179: ateapi.Control.ListActors:input_type -> ateapi.ListActorsRequest - 58, // 180: ateapi.Control.CreateAtespace:input_type -> ateapi.CreateAtespaceRequest - 59, // 181: ateapi.Control.GetAtespace:input_type -> ateapi.GetAtespaceRequest - 60, // 182: ateapi.Control.ListAtespaces:input_type -> ateapi.ListAtespacesRequest - 62, // 183: ateapi.Control.DeleteAtespace:input_type -> ateapi.DeleteAtespaceRequest - 63, // 184: ateapi.Control.CreateActorTemplate:input_type -> ateapi.CreateActorTemplateRequest - 64, // 185: ateapi.Control.GetActorTemplate:input_type -> ateapi.GetActorTemplateRequest - 65, // 186: ateapi.Control.ListActorTemplates:input_type -> ateapi.ListActorTemplatesRequest - 67, // 187: ateapi.Control.DeleteActorTemplate:input_type -> ateapi.DeleteActorTemplateRequest - 119, // 188: ateapi.Control.GetGlobalAccessPolicy:input_type -> ateapi.GetGlobalAccessPolicyRequest - 120, // 189: ateapi.Control.CreateGlobalAccessPolicy:input_type -> ateapi.CreateGlobalAccessPolicyRequest - 121, // 190: ateapi.Control.UpdateGlobalAccessPolicy:input_type -> ateapi.UpdateGlobalAccessPolicyRequest - 122, // 191: ateapi.Control.GetAtespaceAccessPolicy:input_type -> ateapi.GetAtespaceAccessPolicyRequest - 123, // 192: ateapi.Control.CreateAtespaceAccessPolicy:input_type -> ateapi.CreateAtespaceAccessPolicyRequest - 124, // 193: ateapi.Control.UpdateAtespaceAccessPolicy:input_type -> ateapi.UpdateAtespaceAccessPolicyRequest - 125, // 194: ateapi.Control.DeleteAtespaceAccessPolicy:input_type -> ateapi.DeleteAtespaceAccessPolicyRequest - 111, // 195: ateapi.WorkerService.RegisterWorker:input_type -> ateapi.RegisterWorkerRequest - 113, // 196: ateapi.WorkerService.MintAteomActorCertificate:input_type -> ateapi.MintAteomActorCertificateRequest - 115, // 197: ateapi.WorkerService.RequestActorSuspend:input_type -> ateapi.RequestActorSuspendRequest - 17, // 198: ateapi.Control.GetActor:output_type -> ateapi.Actor - 17, // 199: ateapi.Control.CreateActor:output_type -> ateapi.Actor - 17, // 200: ateapi.Control.UpdateActor:output_type -> ateapi.Actor - 72, // 201: ateapi.Control.SuspendActor:output_type -> ateapi.SuspendActorResponse - 74, // 202: ateapi.Control.PauseActor:output_type -> ateapi.PauseActorResponse - 76, // 203: ateapi.Control.ResumeActor:output_type -> ateapi.ResumeActorResponse - 78, // 204: ateapi.Control.RevertActor:output_type -> ateapi.RevertActorResponse - 17, // 205: ateapi.Control.DeleteActor:output_type -> ateapi.Actor - 18, // 206: ateapi.Control.GetActorEgressPolicy:output_type -> ateapi.EgressPolicy - 18, // 207: ateapi.Control.CreateActorEgressPolicy:output_type -> ateapi.EgressPolicy - 18, // 208: ateapi.Control.UpdateActorEgressPolicy:output_type -> ateapi.EgressPolicy - 18, // 209: ateapi.Control.DeleteActorEgressPolicy:output_type -> ateapi.EgressPolicy - 86, // 210: ateapi.Control.MintActorJWT:output_type -> ateapi.MintActorJWTResponse - 88, // 211: ateapi.Control.MintActorCertificate:output_type -> ateapi.MintActorCertificateResponse - 32, // 212: ateapi.Control.CreateTag:output_type -> ateapi.Tag - 32, // 213: ateapi.Control.GetTag:output_type -> ateapi.Tag - 90, // 214: ateapi.Control.ListTags:output_type -> ateapi.ListTagsResponse - 32, // 215: ateapi.Control.UpdateTag:output_type -> ateapi.Tag - 32, // 216: ateapi.Control.DeleteTag:output_type -> ateapi.Tag - 98, // 217: ateapi.Control.ListWorkers:output_type -> ateapi.ListWorkersResponse - 106, // 218: ateapi.Control.GetWorker:output_type -> ateapi.Worker - 106, // 219: ateapi.Control.CreateWorker:output_type -> ateapi.Worker - 106, // 220: ateapi.Control.UpdateWorker:output_type -> ateapi.Worker - 106, // 221: ateapi.Control.DeleteWorker:output_type -> ateapi.Worker - 106, // 222: ateapi.Control.DrainWorker:output_type -> ateapi.Worker - 96, // 223: ateapi.Control.ListWorkerActorAssignments:output_type -> ateapi.ListWorkerActorAssignmentsResponse - 105, // 224: ateapi.Control.ListActors:output_type -> ateapi.ListActorsResponse - 33, // 225: ateapi.Control.CreateAtespace:output_type -> ateapi.Atespace - 33, // 226: ateapi.Control.GetAtespace:output_type -> ateapi.Atespace - 61, // 227: ateapi.Control.ListAtespaces:output_type -> ateapi.ListAtespacesResponse - 33, // 228: ateapi.Control.DeleteAtespace:output_type -> ateapi.Atespace - 35, // 229: ateapi.Control.CreateActorTemplate:output_type -> ateapi.ActorTemplate - 35, // 230: ateapi.Control.GetActorTemplate:output_type -> ateapi.ActorTemplate - 66, // 231: ateapi.Control.ListActorTemplates:output_type -> ateapi.ListActorTemplatesResponse - 35, // 232: ateapi.Control.DeleteActorTemplate:output_type -> ateapi.ActorTemplate - 117, // 233: ateapi.Control.GetGlobalAccessPolicy:output_type -> ateapi.AccessPolicy - 117, // 234: ateapi.Control.CreateGlobalAccessPolicy:output_type -> ateapi.AccessPolicy - 117, // 235: ateapi.Control.UpdateGlobalAccessPolicy:output_type -> ateapi.AccessPolicy - 117, // 236: ateapi.Control.GetAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy - 117, // 237: ateapi.Control.CreateAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy - 117, // 238: ateapi.Control.UpdateAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy - 117, // 239: ateapi.Control.DeleteAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy - 112, // 240: ateapi.WorkerService.RegisterWorker:output_type -> ateapi.RegisterWorkerResponse - 114, // 241: ateapi.WorkerService.MintAteomActorCertificate:output_type -> ateapi.MintAteomActorCertificateResponse - 116, // 242: ateapi.WorkerService.RequestActorSuspend:output_type -> ateapi.RequestActorSuspendResponse - 198, // [198:243] is the sub-list for method output_type - 153, // [153:198] is the sub-list for method input_type - 153, // [153:153] is the sub-list for extension type_name - 153, // [153:153] is the sub-list for extension extendee - 0, // [0:153] is the sub-list for field type_name + 40, // 41: ateapi.Tag.source_actor:type_name -> ateapi.ObjectRef + 18, // 42: ateapi.ExternalVolume.metadata:type_name -> ateapi.ResourceMetadata + 6, // 43: ateapi.ExternalVolume.delete_trigger:type_name -> ateapi.DeleteTrigger + 140, // 44: ateapi.ExternalVolume.volume_context:type_name -> ateapi.ExternalVolume.VolumeContextEntry + 37, // 45: ateapi.ExternalVolume.status:type_name -> ateapi.ExternalVolumeStatus + 7, // 46: ateapi.ExternalVolume.access_mode:type_name -> ateapi.AccessMode + 8, // 47: ateapi.ExternalVolumeStatus.state:type_name -> ateapi.ExternalVolumeState + 38, // 48: ateapi.ExternalVolumeStatus.refs:type_name -> ateapi.ActorRef + 18, // 49: ateapi.Atespace.metadata:type_name -> ateapi.ResourceMetadata + 18, // 50: ateapi.ActorTemplate.metadata:type_name -> ateapi.ResourceMetadata + 17, // 51: ateapi.ActorTemplate.worker_selector:type_name -> ateapi.Selector + 48, // 52: ateapi.ActorTemplate.containers:type_name -> ateapi.Container + 54, // 53: ateapi.ActorTemplate.volumes:type_name -> ateapi.Volume + 47, // 54: ateapi.ActorTemplate.snapshot_config:type_name -> ateapi.SnapshotConfig + 46, // 55: ateapi.ActorTemplate.sandbox_config:type_name -> ateapi.SandboxConfig + 42, // 56: ateapi.ActorTemplate.resources:type_name -> ateapi.Resources + 45, // 57: ateapi.ActorTemplate.status:type_name -> ateapi.ActorTemplateStatus + 43, // 58: ateapi.Resources.limits:type_name -> ateapi.Limits + 40, // 59: ateapi.GoldenSnapshotStatus.golden_tag:type_name -> ateapi.ObjectRef + 143, // 60: ateapi.GoldenSnapshotStatus.take_golden_snapshot_at:type_name -> google.protobuf.Timestamp + 44, // 61: ateapi.ActorTemplateStatus.golden_snapshot_status:type_name -> ateapi.GoldenSnapshotStatus + 9, // 62: ateapi.SandboxConfig.sandbox_class:type_name -> ateapi.SandboxClass + 3, // 63: ateapi.SnapshotConfig.preferred_fidelity:type_name -> ateapi.SnapshotFidelity + 51, // 64: ateapi.Container.env:type_name -> ateapi.EnvVar + 52, // 65: ateapi.Container.wakeup_probe:type_name -> ateapi.ContainerWakeupProbe + 63, // 66: ateapi.Container.volume_mounts:type_name -> ateapi.VolumeMount + 49, // 67: ateapi.Container.security_context:type_name -> ateapi.SecurityContext + 42, // 68: ateapi.Container.resources:type_name -> ateapi.Resources + 50, // 69: ateapi.SecurityContext.capabilities:type_name -> ateapi.Capabilities + 53, // 70: ateapi.ContainerWakeupProbe.http_get:type_name -> ateapi.HTTPGetAction + 56, // 71: ateapi.Volume.durable_dir:type_name -> ateapi.DurableDirVolumeSource + 57, // 72: ateapi.Volume.external_volume_template:type_name -> ateapi.ExternalVolumeTemplate + 58, // 73: ateapi.Volume.system_info:type_name -> ateapi.SystemInfoVolumeSource + 55, // 74: ateapi.Volume.image:type_name -> ateapi.ImageVolumeSource + 59, // 75: ateapi.SystemInfoVolumeSource.data_sources:type_name -> ateapi.SystemInfoDataSource + 60, // 76: ateapi.SystemInfoDataSource.actor_metadata:type_name -> ateapi.ActorMetadataDataSource + 62, // 77: ateapi.SystemInfoDataSource.trust_bundle:type_name -> ateapi.TrustBundleDataSource + 61, // 78: ateapi.ActorMetadataDataSource.items:type_name -> ateapi.ActorMetadataItem + 10, // 79: ateapi.ActorMetadataItem.field:type_name -> ateapi.ActorMetadataField + 39, // 80: ateapi.CreateAtespaceRequest.atespace:type_name -> ateapi.Atespace + 40, // 81: ateapi.GetAtespaceRequest.atespace:type_name -> ateapi.ObjectRef + 39, // 82: ateapi.ListAtespacesResponse.atespaces:type_name -> ateapi.Atespace + 40, // 83: ateapi.DeleteAtespaceRequest.atespace:type_name -> ateapi.ObjectRef + 106, // 84: ateapi.DeleteAtespaceRequest.options:type_name -> ateapi.DeleteOptions + 41, // 85: ateapi.CreateActorTemplateRequest.actor_template:type_name -> ateapi.ActorTemplate + 40, // 86: ateapi.GetActorTemplateRequest.actor_template:type_name -> ateapi.ObjectRef + 41, // 87: ateapi.ListActorTemplatesResponse.actor_templates:type_name -> ateapi.ActorTemplate + 40, // 88: ateapi.DeleteActorTemplateRequest.actor_template:type_name -> ateapi.ObjectRef + 106, // 89: ateapi.DeleteActorTemplateRequest.options:type_name -> ateapi.DeleteOptions + 40, // 90: ateapi.GetActorRequest.actor:type_name -> ateapi.ObjectRef + 20, // 91: ateapi.CreateActorRequest.actor:type_name -> ateapi.Actor + 20, // 92: ateapi.UpdateActorRequest.actor:type_name -> ateapi.Actor + 40, // 93: ateapi.SuspendActorRequest.actor:type_name -> ateapi.ObjectRef + 20, // 94: ateapi.SuspendActorResponse.actor:type_name -> ateapi.Actor + 40, // 95: ateapi.PauseActorRequest.actor:type_name -> ateapi.ObjectRef + 20, // 96: ateapi.PauseActorResponse.actor:type_name -> ateapi.Actor + 40, // 97: ateapi.ResumeActorRequest.actor:type_name -> ateapi.ObjectRef + 20, // 98: ateapi.ResumeActorResponse.actor:type_name -> ateapi.Actor + 40, // 99: ateapi.RevertActorRequest.actor:type_name -> ateapi.ObjectRef + 20, // 100: ateapi.RevertActorResponse.actor:type_name -> ateapi.Actor + 40, // 101: ateapi.DeleteActorRequest.actor:type_name -> ateapi.ObjectRef + 106, // 102: ateapi.DeleteActorRequest.options:type_name -> ateapi.DeleteOptions + 40, // 103: ateapi.GetActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef + 40, // 104: ateapi.CreateActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef + 21, // 105: ateapi.CreateActorEgressPolicyRequest.egress_policy:type_name -> ateapi.EgressPolicy + 40, // 106: ateapi.UpdateActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef + 21, // 107: ateapi.UpdateActorEgressPolicyRequest.egress_policy:type_name -> ateapi.EgressPolicy + 40, // 108: ateapi.DeleteActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef + 106, // 109: ateapi.DeleteActorEgressPolicyRequest.options:type_name -> ateapi.DeleteOptions + 40, // 110: ateapi.GetTagRequest.tag:type_name -> ateapi.ObjectRef + 40, // 111: ateapi.MintActorJWTRequest.actor:type_name -> ateapi.ObjectRef + 143, // 112: ateapi.MintActorJWTResponse.expires_at:type_name -> google.protobuf.Timestamp + 40, // 113: ateapi.MintActorCertificateRequest.actor:type_name -> ateapi.ObjectRef + 35, // 114: ateapi.ListTagsResponse.tags:type_name -> ateapi.Tag + 35, // 115: ateapi.CreateTagRequest.tag:type_name -> ateapi.Tag + 35, // 116: ateapi.UpdateTagRequest.tag:type_name -> ateapi.Tag + 40, // 117: ateapi.DeleteTagRequest.tag:type_name -> ateapi.ObjectRef + 106, // 118: ateapi.DeleteTagRequest.options:type_name -> ateapi.DeleteOptions + 36, // 119: ateapi.CreateExternalVolumeRequest.external_volume:type_name -> ateapi.ExternalVolume + 40, // 120: ateapi.GetExternalVolumeRequest.external_volume:type_name -> ateapi.ObjectRef + 36, // 121: ateapi.ListExternalVolumesResponse.external_volumes:type_name -> ateapi.ExternalVolume + 36, // 122: ateapi.UpdateExternalVolumeRequest.external_volume:type_name -> ateapi.ExternalVolume + 40, // 123: ateapi.DeleteExternalVolumeRequest.external_volume:type_name -> ateapi.ObjectRef + 106, // 124: ateapi.DeleteExternalVolumeRequest.options:type_name -> ateapi.DeleteOptions + 40, // 125: ateapi.ListWorkerActorAssignmentsRequest.worker:type_name -> ateapi.ObjectRef + 122, // 126: ateapi.ListWorkerActorAssignmentsResponse.actor_assignments:type_name -> ateapi.ActorAssignment + 118, // 127: ateapi.ListWorkersResponse.workers:type_name -> ateapi.Worker + 40, // 128: ateapi.GetWorkerRequest.worker:type_name -> ateapi.ObjectRef + 118, // 129: ateapi.CreateWorkerRequest.worker:type_name -> ateapi.Worker + 118, // 130: ateapi.UpdateWorkerRequest.worker:type_name -> ateapi.Worker + 40, // 131: ateapi.DeleteWorkerRequest.worker:type_name -> ateapi.ObjectRef + 106, // 132: ateapi.DeleteWorkerRequest.options:type_name -> ateapi.DeleteOptions + 40, // 133: ateapi.DrainWorkerRequest.worker:type_name -> ateapi.ObjectRef + 20, // 134: ateapi.ListActorsResponse.actors:type_name -> ateapi.Actor + 18, // 135: ateapi.Worker.metadata:type_name -> ateapi.ResourceMetadata + 141, // 136: ateapi.Worker.labels:type_name -> ateapi.Worker.LabelsEntry + 119, // 137: ateapi.Worker.status:type_name -> ateapi.WorkerStatus + 11, // 138: ateapi.WorkerStatus.state:type_name -> ateapi.WorkerState + 121, // 139: ateapi.WorkerStatus.capacity:type_name -> ateapi.WorkerResources + 121, // 140: ateapi.WorkerStatus.allocated:type_name -> ateapi.WorkerResources + 120, // 141: ateapi.WorkerStatus.hardware:type_name -> ateapi.HardwareIdentity + 142, // 142: ateapi.HardwareIdentity.attributes:type_name -> ateapi.HardwareIdentity.AttributesEntry + 42, // 143: ateapi.WorkerResources.resources:type_name -> ateapi.Resources + 18, // 144: ateapi.ActorAssignment.metadata:type_name -> ateapi.ResourceMetadata + 40, // 145: ateapi.ActorAssignment.actor:type_name -> ateapi.ObjectRef + 42, // 146: ateapi.ActorAssignment.resources:type_name -> ateapi.Resources + 40, // 147: ateapi.RegisterWorkerRequest.worker:type_name -> ateapi.ObjectRef + 121, // 148: ateapi.RegisterWorkerRequest.capacity:type_name -> ateapi.WorkerResources + 120, // 149: ateapi.RegisterWorkerRequest.hardware:type_name -> ateapi.HardwareIdentity + 118, // 150: ateapi.RegisterWorkerResponse.worker:type_name -> ateapi.Worker + 40, // 151: ateapi.MintAteomActorCertificateRequest.actor:type_name -> ateapi.ObjectRef + 40, // 152: ateapi.RequestActorSuspendRequest.worker:type_name -> ateapi.ObjectRef + 40, // 153: ateapi.RequestActorSuspendRequest.actor:type_name -> ateapi.ObjectRef + 20, // 154: ateapi.RequestActorSuspendResponse.actor:type_name -> ateapi.Actor + 18, // 155: ateapi.AccessPolicy.metadata:type_name -> ateapi.ResourceMetadata + 130, // 156: ateapi.AccessPolicy.bindings:type_name -> ateapi.Binding + 129, // 157: ateapi.CreateGlobalAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy + 129, // 158: ateapi.UpdateGlobalAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy + 40, // 159: ateapi.GetAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef + 40, // 160: ateapi.CreateAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef + 129, // 161: ateapi.CreateAtespaceAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy + 40, // 162: ateapi.UpdateAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef + 129, // 163: ateapi.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy + 40, // 164: ateapi.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef + 106, // 165: ateapi.DeleteAtespaceAccessPolicyRequest.options:type_name -> ateapi.DeleteOptions + 74, // 166: ateapi.Control.GetActor:input_type -> ateapi.GetActorRequest + 75, // 167: ateapi.Control.CreateActor:input_type -> ateapi.CreateActorRequest + 76, // 168: ateapi.Control.UpdateActor:input_type -> ateapi.UpdateActorRequest + 77, // 169: ateapi.Control.SuspendActor:input_type -> ateapi.SuspendActorRequest + 79, // 170: ateapi.Control.PauseActor:input_type -> ateapi.PauseActorRequest + 81, // 171: ateapi.Control.ResumeActor:input_type -> ateapi.ResumeActorRequest + 83, // 172: ateapi.Control.RevertActor:input_type -> ateapi.RevertActorRequest + 85, // 173: ateapi.Control.DeleteActor:input_type -> ateapi.DeleteActorRequest + 86, // 174: ateapi.Control.GetActorEgressPolicy:input_type -> ateapi.GetActorEgressPolicyRequest + 87, // 175: ateapi.Control.CreateActorEgressPolicy:input_type -> ateapi.CreateActorEgressPolicyRequest + 88, // 176: ateapi.Control.UpdateActorEgressPolicy:input_type -> ateapi.UpdateActorEgressPolicyRequest + 89, // 177: ateapi.Control.DeleteActorEgressPolicy:input_type -> ateapi.DeleteActorEgressPolicyRequest + 91, // 178: ateapi.Control.MintActorJWT:input_type -> ateapi.MintActorJWTRequest + 93, // 179: ateapi.Control.MintActorCertificate:input_type -> ateapi.MintActorCertificateRequest + 97, // 180: ateapi.Control.CreateTag:input_type -> ateapi.CreateTagRequest + 90, // 181: ateapi.Control.GetTag:input_type -> ateapi.GetTagRequest + 95, // 182: ateapi.Control.ListTags:input_type -> ateapi.ListTagsRequest + 98, // 183: ateapi.Control.UpdateTag:input_type -> ateapi.UpdateTagRequest + 99, // 184: ateapi.Control.DeleteTag:input_type -> ateapi.DeleteTagRequest + 100, // 185: ateapi.Control.CreateExternalVolume:input_type -> ateapi.CreateExternalVolumeRequest + 101, // 186: ateapi.Control.GetExternalVolume:input_type -> ateapi.GetExternalVolumeRequest + 102, // 187: ateapi.Control.ListExternalVolumes:input_type -> ateapi.ListExternalVolumesRequest + 104, // 188: ateapi.Control.UpdateExternalVolume:input_type -> ateapi.UpdateExternalVolumeRequest + 105, // 189: ateapi.Control.DeleteExternalVolume:input_type -> ateapi.DeleteExternalVolumeRequest + 109, // 190: ateapi.Control.ListWorkers:input_type -> ateapi.ListWorkersRequest + 111, // 191: ateapi.Control.GetWorker:input_type -> ateapi.GetWorkerRequest + 112, // 192: ateapi.Control.CreateWorker:input_type -> ateapi.CreateWorkerRequest + 113, // 193: ateapi.Control.UpdateWorker:input_type -> ateapi.UpdateWorkerRequest + 114, // 194: ateapi.Control.DeleteWorker:input_type -> ateapi.DeleteWorkerRequest + 115, // 195: ateapi.Control.DrainWorker:input_type -> ateapi.DrainWorkerRequest + 107, // 196: ateapi.Control.ListWorkerActorAssignments:input_type -> ateapi.ListWorkerActorAssignmentsRequest + 116, // 197: ateapi.Control.ListActors:input_type -> ateapi.ListActorsRequest + 64, // 198: ateapi.Control.CreateAtespace:input_type -> ateapi.CreateAtespaceRequest + 65, // 199: ateapi.Control.GetAtespace:input_type -> ateapi.GetAtespaceRequest + 66, // 200: ateapi.Control.ListAtespaces:input_type -> ateapi.ListAtespacesRequest + 68, // 201: ateapi.Control.DeleteAtespace:input_type -> ateapi.DeleteAtespaceRequest + 69, // 202: ateapi.Control.CreateActorTemplate:input_type -> ateapi.CreateActorTemplateRequest + 70, // 203: ateapi.Control.GetActorTemplate:input_type -> ateapi.GetActorTemplateRequest + 71, // 204: ateapi.Control.ListActorTemplates:input_type -> ateapi.ListActorTemplatesRequest + 73, // 205: ateapi.Control.DeleteActorTemplate:input_type -> ateapi.DeleteActorTemplateRequest + 131, // 206: ateapi.Control.GetGlobalAccessPolicy:input_type -> ateapi.GetGlobalAccessPolicyRequest + 132, // 207: ateapi.Control.CreateGlobalAccessPolicy:input_type -> ateapi.CreateGlobalAccessPolicyRequest + 133, // 208: ateapi.Control.UpdateGlobalAccessPolicy:input_type -> ateapi.UpdateGlobalAccessPolicyRequest + 134, // 209: ateapi.Control.GetAtespaceAccessPolicy:input_type -> ateapi.GetAtespaceAccessPolicyRequest + 135, // 210: ateapi.Control.CreateAtespaceAccessPolicy:input_type -> ateapi.CreateAtespaceAccessPolicyRequest + 136, // 211: ateapi.Control.UpdateAtespaceAccessPolicy:input_type -> ateapi.UpdateAtespaceAccessPolicyRequest + 137, // 212: ateapi.Control.DeleteAtespaceAccessPolicy:input_type -> ateapi.DeleteAtespaceAccessPolicyRequest + 123, // 213: ateapi.WorkerService.RegisterWorker:input_type -> ateapi.RegisterWorkerRequest + 125, // 214: ateapi.WorkerService.MintAteomActorCertificate:input_type -> ateapi.MintAteomActorCertificateRequest + 127, // 215: ateapi.WorkerService.RequestActorSuspend:input_type -> ateapi.RequestActorSuspendRequest + 20, // 216: ateapi.Control.GetActor:output_type -> ateapi.Actor + 20, // 217: ateapi.Control.CreateActor:output_type -> ateapi.Actor + 20, // 218: ateapi.Control.UpdateActor:output_type -> ateapi.Actor + 78, // 219: ateapi.Control.SuspendActor:output_type -> ateapi.SuspendActorResponse + 80, // 220: ateapi.Control.PauseActor:output_type -> ateapi.PauseActorResponse + 82, // 221: ateapi.Control.ResumeActor:output_type -> ateapi.ResumeActorResponse + 84, // 222: ateapi.Control.RevertActor:output_type -> ateapi.RevertActorResponse + 20, // 223: ateapi.Control.DeleteActor:output_type -> ateapi.Actor + 21, // 224: ateapi.Control.GetActorEgressPolicy:output_type -> ateapi.EgressPolicy + 21, // 225: ateapi.Control.CreateActorEgressPolicy:output_type -> ateapi.EgressPolicy + 21, // 226: ateapi.Control.UpdateActorEgressPolicy:output_type -> ateapi.EgressPolicy + 21, // 227: ateapi.Control.DeleteActorEgressPolicy:output_type -> ateapi.EgressPolicy + 92, // 228: ateapi.Control.MintActorJWT:output_type -> ateapi.MintActorJWTResponse + 94, // 229: ateapi.Control.MintActorCertificate:output_type -> ateapi.MintActorCertificateResponse + 35, // 230: ateapi.Control.CreateTag:output_type -> ateapi.Tag + 35, // 231: ateapi.Control.GetTag:output_type -> ateapi.Tag + 96, // 232: ateapi.Control.ListTags:output_type -> ateapi.ListTagsResponse + 35, // 233: ateapi.Control.UpdateTag:output_type -> ateapi.Tag + 35, // 234: ateapi.Control.DeleteTag:output_type -> ateapi.Tag + 36, // 235: ateapi.Control.CreateExternalVolume:output_type -> ateapi.ExternalVolume + 36, // 236: ateapi.Control.GetExternalVolume:output_type -> ateapi.ExternalVolume + 103, // 237: ateapi.Control.ListExternalVolumes:output_type -> ateapi.ListExternalVolumesResponse + 36, // 238: ateapi.Control.UpdateExternalVolume:output_type -> ateapi.ExternalVolume + 36, // 239: ateapi.Control.DeleteExternalVolume:output_type -> ateapi.ExternalVolume + 110, // 240: ateapi.Control.ListWorkers:output_type -> ateapi.ListWorkersResponse + 118, // 241: ateapi.Control.GetWorker:output_type -> ateapi.Worker + 118, // 242: ateapi.Control.CreateWorker:output_type -> ateapi.Worker + 118, // 243: ateapi.Control.UpdateWorker:output_type -> ateapi.Worker + 118, // 244: ateapi.Control.DeleteWorker:output_type -> ateapi.Worker + 118, // 245: ateapi.Control.DrainWorker:output_type -> ateapi.Worker + 108, // 246: ateapi.Control.ListWorkerActorAssignments:output_type -> ateapi.ListWorkerActorAssignmentsResponse + 117, // 247: ateapi.Control.ListActors:output_type -> ateapi.ListActorsResponse + 39, // 248: ateapi.Control.CreateAtespace:output_type -> ateapi.Atespace + 39, // 249: ateapi.Control.GetAtespace:output_type -> ateapi.Atespace + 67, // 250: ateapi.Control.ListAtespaces:output_type -> ateapi.ListAtespacesResponse + 39, // 251: ateapi.Control.DeleteAtespace:output_type -> ateapi.Atespace + 41, // 252: ateapi.Control.CreateActorTemplate:output_type -> ateapi.ActorTemplate + 41, // 253: ateapi.Control.GetActorTemplate:output_type -> ateapi.ActorTemplate + 72, // 254: ateapi.Control.ListActorTemplates:output_type -> ateapi.ListActorTemplatesResponse + 41, // 255: ateapi.Control.DeleteActorTemplate:output_type -> ateapi.ActorTemplate + 129, // 256: ateapi.Control.GetGlobalAccessPolicy:output_type -> ateapi.AccessPolicy + 129, // 257: ateapi.Control.CreateGlobalAccessPolicy:output_type -> ateapi.AccessPolicy + 129, // 258: ateapi.Control.UpdateGlobalAccessPolicy:output_type -> ateapi.AccessPolicy + 129, // 259: ateapi.Control.GetAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy + 129, // 260: ateapi.Control.CreateAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy + 129, // 261: ateapi.Control.UpdateAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy + 129, // 262: ateapi.Control.DeleteAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy + 124, // 263: ateapi.WorkerService.RegisterWorker:output_type -> ateapi.RegisterWorkerResponse + 126, // 264: ateapi.WorkerService.MintAteomActorCertificate:output_type -> ateapi.MintAteomActorCertificateResponse + 128, // 265: ateapi.WorkerService.RequestActorSuspend:output_type -> ateapi.RequestActorSuspendResponse + 216, // [216:266] is the sub-list for method output_type + 166, // [166:216] is the sub-list for method input_type + 166, // [166:166] is the sub-list for extension type_name + 166, // [166:166] is the sub-list for extension extendee + 0, // [0:166] is the sub-list for field type_name } func init() { file_ateapi_proto_init() } @@ -9253,8 +10153,8 @@ func file_ateapi_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_ateapi_proto_rawDesc), len(file_ateapi_proto_rawDesc)), - NumEnums: 10, - NumMessages: 120, + NumEnums: 13, + NumMessages: 130, NumExtensions: 0, NumServices: 2, }, diff --git a/pkg/proto/ateapipb/ateapi.proto b/pkg/proto/ateapipb/ateapi.proto index 28bc6bae54..4217771fa4 100644 --- a/pkg/proto/ateapipb/ateapi.proto +++ b/pkg/proto/ateapipb/ateapi.proto @@ -94,6 +94,21 @@ service Control { // and become unrecoverable, so do not delete a tag while such Actors exist. rpc DeleteTag(DeleteTagRequest) returns (Tag) {} + // Create an ExternalVolume, provisioning it or registering an existing volume. + rpc CreateExternalVolume(CreateExternalVolumeRequest) returns (ExternalVolume) {} + + // Get an ExternalVolume. + rpc GetExternalVolume(GetExternalVolumeRequest) returns (ExternalVolume) {} + + // List ExternalVolumes. + rpc ListExternalVolumes(ListExternalVolumesRequest) returns (ListExternalVolumesResponse) {} + + // Update an ExternalVolume's delete trigger. + rpc UpdateExternalVolume(UpdateExternalVolumeRequest) returns (ExternalVolume) {} + + // Delete an ExternalVolume and its storage. Rejected while any Actor references it. + rpc DeleteExternalVolume(DeleteExternalVolumeRequest) returns (ExternalVolume) {} + // List Workers. rpc ListWorkers(ListWorkersRequest) returns (ListWorkersResponse) {} @@ -983,6 +998,157 @@ message Tag { ObjectRef source_actor = 4; } +// DeleteTrigger is what removes an ExternalVolume and its storage. +// TODO: add an ATESPACE trigger that removes the volume with its atespace. +enum DeleteTrigger { + DELETE_TRIGGER_UNSPECIFIED = 0; + // Only an explicit DeleteExternalVolume removes the volume. + DELETE_TRIGGER_MANUAL = 1; + // The volume is removed when the last actor referencing it is deleted. + DELETE_TRIGGER_LAST_ACTOR = 2; +} + +// AccessMode is how many resumed actors may hold the volume at once. +enum AccessMode { + ACCESS_MODE_UNSPECIFIED = 0; + // At most one resumed actor holds the volume. + ACCESS_MODE_READ_WRITE_ONCE = 1; + // Any number of resumed actors hold the volume, on any node. + ACCESS_MODE_READ_WRITE_MANY = 2; +} + +// ExternalVolumeState is where an ExternalVolume is in its own lifecycle. +enum ExternalVolumeState { + EXTERNAL_VOLUME_STATE_UNSPECIFIED = 0; + // The name is reserved but no volume handle is known yet. + EXTERNAL_VOLUME_STATE_PENDING = 1; + // The volume has a handle and can be referenced. + EXTERNAL_VOLUME_STATE_READY = 2; +} + +// ExternalVolume is an atespace-scoped CSI volume whose lifetime is independent +// of any actor. Identity is (atespace, name); the storage-level ID is derived +// from the record's UID. +message ExternalVolume { + // Common resource metadata: atespace, name, uid, version, timestamps. + // + // +k8s:required + // +k8s:subfield(atespace)=+k8s:required + ResourceMetadata metadata = 1; + + // delete_trigger decides what removes the volume. Defaults to LAST_ACTOR when + // provisioned and MANUAL when registered. + // + // +k8s:optional + // +k8s:minimum=1 + // +k8s:maximum=2 # keep this in sync with the DeleteTrigger enum + // +k8s:mutable + DeleteTrigger delete_trigger = 2; + + // storage_class_name names the StorageClass to provision from, or documents + // the class of a registered volume. + // + // +k8s:optional + // +k8s:format=k8s-long-name + // +k8s:update=NoModify + // +k8s:update=NoUnset + string storage_class_name = 3; + + // volume_id is the storage system's volume ID. Supplied to register an + // existing volume, otherwise stamped once provisioning completes. Bounded and + // checked for control characters only. + // + // +k8s:optional + // +k8s:maxLength=256 + // +k8s:update=NoModify + // +k8s:update=NoUnset + // +k8s:customValidation # no control characters + string volume_id = 4; + + // volume_type is the CSI driver name. Required alongside volume_id when no + // StorageClass is named; otherwise taken from the class's provisioner. + // + // +k8s:optional + // +k8s:maxLength=253 + // +k8s:update=NoModify + // +k8s:update=NoUnset + // +k8s:customValidation + string volume_type = 5; + + // volume_context is driver metadata needed by the node plugin for mounting. + // Attachment metadata is per-node and deliberately not recorded here. + // + // +k8s:optional + // +k8s:maxProperties=32 + // +k8s:eachKey=+k8s:maxLength=128 + // +k8s:eachVal=+k8s:maxLength=256 + map volume_context = 6; + + // status is set by the control plane; it is ignored on write. + // + // +k8s:optional + ExternalVolumeStatus status = 7; + + // capacity to provision, as a Kubernetes resource.Quantity string (e.g. + // "10Gi"). Required when provisioning, forbidden alongside volume_id. + // + // +k8s:optional + // +k8s:maxLength=64 + // +k8s:update=NoModify + // +k8s:update=NoUnset + // +k8s:customValidation # must parse as a resource.Quantity + string capacity = 8; + + // access_mode is fixed at create and defaults to READ_WRITE_ONCE. + // TODO: accept READ_WRITE_MANY once concurrent holders are supported. + // + // +k8s:optional + // +k8s:minimum=1 + // +k8s:maximum=2 # keep this in sync with the AccessMode enum + // +k8s:update=NoModify + // +k8s:update=NoUnset + AccessMode access_mode = 9; +} + +// ExternalVolumeStatus is the part of an ExternalVolume the control plane owns. +message ExternalVolumeStatus { + // state is where the volume is in its lifecycle. + // + // +k8s:optional + // +k8s:minimum=1 + // +k8s:maximum=2 # keep this in sync with the ExternalVolumeState enum + ExternalVolumeState state = 1; + + // refs are the actors referencing the volume, resumed or not. + // TODO: move references to their own table before lifting the bound. + // + // +k8s:optional + // +k8s:maxItems=256 + // +k8s:listType=map + // +k8s:listMapKey=actor_uid + repeated ActorRef refs = 2; +} + +// ActorRef is one actor's reference to an ExternalVolume. +message ActorRef { + // actor_uid identifies the actor, so a recreated namesake does not inherit it. + // + // +k8s:required + // +k8s:maxLength=253 + string actor_uid = 1; + + // actor_name is the actor's name, for readers. + // + // +k8s:required + // +k8s:format=k8s-short-name + string actor_name = 2; + + // active is true while the actor is resumed and holds the volume mounted. + // + // +k8s:optional + bool active = 3; +} + // Atespace is the isolation boundary an Actor is created into. Global-scoped: // metadata.atespace is always empty; the atespace's identity is metadata.name. message Atespace { @@ -1930,6 +2096,82 @@ message DeleteTagRequest { DeleteOptions options = 2; } +// Request to create an ExternalVolume. +// +// +k8s:customValidation # exactly one of storage_class_name and volume_id +message CreateExternalVolumeRequest { + // The volume to create. Name a storage class to provision a new volume, or + // supply a volume ID to register one that already exists. status is ignored. + // + // +k8s:required + ExternalVolume external_volume = 1; +} + +// GetExternalVolumeRequest identifies one ExternalVolume. +message GetExternalVolumeRequest { + // The volume to get. + // + // +k8s:required + // +k8s:subfield(atespace)=+k8s:required + ObjectRef external_volume = 1; +} + +// ListExternalVolumesRequest selects a page of ExternalVolumes. +message ListExternalVolumesRequest { + // The atespace to list from. Empty lists across all atespaces. + // + // +k8s:optional + // +k8s:format=k8s-short-name + string atespace = 1; + + // Requested page size; values above 1000 are coerced to 1000. + // + // +k8s:optional + // +k8s:minimum=1 + int32 page_size = 2; + + // Pagination token from a previous ListExternalVolumes response. + // + // +k8s:optional + // +k8s:maxLength=256 + string page_token = 3; +} + +// ListExternalVolumesResponse is one page of ExternalVolumes. +message ListExternalVolumesResponse { + // The volumes in this page. + repeated ExternalVolume external_volumes = 1; + + // Pagination token for the next page. Empty on the last page. + string next_page_token = 2; +} + +// Request to update the mutable fields of an ExternalVolume. +message UpdateExternalVolumeRequest { + // The volume to update. metadata.atespace and metadata.name identify it; + // metadata.version and metadata.uid are required preconditions. + // + // +k8s:required + // +k8s:opaqueType # updates are handled in 2 steps, do not descend + // +k8s:subfield(metadata)=+k8s:required + // +k8s:customValidation # TODO: when we get nested subfields, require metadata.atespace + ExternalVolume external_volume = 1; +} + +// DeleteExternalVolumeRequest identifies one ExternalVolume to delete. +message DeleteExternalVolumeRequest { + // The volume to delete. + // + // +k8s:required + // +k8s:subfield(atespace)=+k8s:required + ObjectRef external_volume = 1; + + // Optional per-delete preconditions. + // + // +k8s:optional + DeleteOptions options = 2; +} + // DeleteOptions are the optional guards a Delete request may carry. message DeleteOptions { // Delete only if the resource is still at this version, that is, unchanged diff --git a/pkg/proto/ateapipb/ateapi_grpc.pb.go b/pkg/proto/ateapipb/ateapi_grpc.pb.go index 549fdb2550..dc0af894aa 100644 --- a/pkg/proto/ateapipb/ateapi_grpc.pb.go +++ b/pkg/proto/ateapipb/ateapi_grpc.pb.go @@ -52,6 +52,11 @@ const ( Control_ListTags_FullMethodName = "/ateapi.Control/ListTags" Control_UpdateTag_FullMethodName = "/ateapi.Control/UpdateTag" Control_DeleteTag_FullMethodName = "/ateapi.Control/DeleteTag" + Control_CreateExternalVolume_FullMethodName = "/ateapi.Control/CreateExternalVolume" + Control_GetExternalVolume_FullMethodName = "/ateapi.Control/GetExternalVolume" + Control_ListExternalVolumes_FullMethodName = "/ateapi.Control/ListExternalVolumes" + Control_UpdateExternalVolume_FullMethodName = "/ateapi.Control/UpdateExternalVolume" + Control_DeleteExternalVolume_FullMethodName = "/ateapi.Control/DeleteExternalVolume" Control_ListWorkers_FullMethodName = "/ateapi.Control/ListWorkers" Control_GetWorker_FullMethodName = "/ateapi.Control/GetWorker" Control_CreateWorker_FullMethodName = "/ateapi.Control/CreateWorker" @@ -136,6 +141,16 @@ type ControlClient interface { // tag that have not yet been suspended still point at that external snapshot // and become unrecoverable, so do not delete a tag while such Actors exist. DeleteTag(ctx context.Context, in *DeleteTagRequest, opts ...grpc.CallOption) (*Tag, error) + // Create an ExternalVolume, provisioning it or registering an existing volume. + CreateExternalVolume(ctx context.Context, in *CreateExternalVolumeRequest, opts ...grpc.CallOption) (*ExternalVolume, error) + // Get an ExternalVolume. + GetExternalVolume(ctx context.Context, in *GetExternalVolumeRequest, opts ...grpc.CallOption) (*ExternalVolume, error) + // List ExternalVolumes. + ListExternalVolumes(ctx context.Context, in *ListExternalVolumesRequest, opts ...grpc.CallOption) (*ListExternalVolumesResponse, error) + // Update an ExternalVolume's delete trigger. + UpdateExternalVolume(ctx context.Context, in *UpdateExternalVolumeRequest, opts ...grpc.CallOption) (*ExternalVolume, error) + // Delete an ExternalVolume and its storage. Rejected while any Actor references it. + DeleteExternalVolume(ctx context.Context, in *DeleteExternalVolumeRequest, opts ...grpc.CallOption) (*ExternalVolume, error) // List Workers. ListWorkers(ctx context.Context, in *ListWorkersRequest, opts ...grpc.CallOption) (*ListWorkersResponse, error) // Get a Worker. @@ -389,6 +404,56 @@ func (c *controlClient) DeleteTag(ctx context.Context, in *DeleteTagRequest, opt return out, nil } +func (c *controlClient) CreateExternalVolume(ctx context.Context, in *CreateExternalVolumeRequest, opts ...grpc.CallOption) (*ExternalVolume, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ExternalVolume) + err := c.cc.Invoke(ctx, Control_CreateExternalVolume_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *controlClient) GetExternalVolume(ctx context.Context, in *GetExternalVolumeRequest, opts ...grpc.CallOption) (*ExternalVolume, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ExternalVolume) + err := c.cc.Invoke(ctx, Control_GetExternalVolume_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *controlClient) ListExternalVolumes(ctx context.Context, in *ListExternalVolumesRequest, opts ...grpc.CallOption) (*ListExternalVolumesResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListExternalVolumesResponse) + err := c.cc.Invoke(ctx, Control_ListExternalVolumes_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *controlClient) UpdateExternalVolume(ctx context.Context, in *UpdateExternalVolumeRequest, opts ...grpc.CallOption) (*ExternalVolume, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ExternalVolume) + err := c.cc.Invoke(ctx, Control_UpdateExternalVolume_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *controlClient) DeleteExternalVolume(ctx context.Context, in *DeleteExternalVolumeRequest, opts ...grpc.CallOption) (*ExternalVolume, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ExternalVolume) + err := c.cc.Invoke(ctx, Control_DeleteExternalVolume_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *controlClient) ListWorkers(ctx context.Context, in *ListWorkersRequest, opts ...grpc.CallOption) (*ListWorkersResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ListWorkersResponse) @@ -678,6 +743,16 @@ type ControlServer interface { // tag that have not yet been suspended still point at that external snapshot // and become unrecoverable, so do not delete a tag while such Actors exist. DeleteTag(context.Context, *DeleteTagRequest) (*Tag, error) + // Create an ExternalVolume, provisioning it or registering an existing volume. + CreateExternalVolume(context.Context, *CreateExternalVolumeRequest) (*ExternalVolume, error) + // Get an ExternalVolume. + GetExternalVolume(context.Context, *GetExternalVolumeRequest) (*ExternalVolume, error) + // List ExternalVolumes. + ListExternalVolumes(context.Context, *ListExternalVolumesRequest) (*ListExternalVolumesResponse, error) + // Update an ExternalVolume's delete trigger. + UpdateExternalVolume(context.Context, *UpdateExternalVolumeRequest) (*ExternalVolume, error) + // Delete an ExternalVolume and its storage. Rejected while any Actor references it. + DeleteExternalVolume(context.Context, *DeleteExternalVolumeRequest) (*ExternalVolume, error) // List Workers. ListWorkers(context.Context, *ListWorkersRequest) (*ListWorkersResponse, error) // Get a Worker. @@ -798,6 +873,21 @@ func (UnimplementedControlServer) UpdateTag(context.Context, *UpdateTagRequest) func (UnimplementedControlServer) DeleteTag(context.Context, *DeleteTagRequest) (*Tag, error) { return nil, status.Error(codes.Unimplemented, "method DeleteTag not implemented") } +func (UnimplementedControlServer) CreateExternalVolume(context.Context, *CreateExternalVolumeRequest) (*ExternalVolume, error) { + return nil, status.Error(codes.Unimplemented, "method CreateExternalVolume not implemented") +} +func (UnimplementedControlServer) GetExternalVolume(context.Context, *GetExternalVolumeRequest) (*ExternalVolume, error) { + return nil, status.Error(codes.Unimplemented, "method GetExternalVolume not implemented") +} +func (UnimplementedControlServer) ListExternalVolumes(context.Context, *ListExternalVolumesRequest) (*ListExternalVolumesResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ListExternalVolumes not implemented") +} +func (UnimplementedControlServer) UpdateExternalVolume(context.Context, *UpdateExternalVolumeRequest) (*ExternalVolume, error) { + return nil, status.Error(codes.Unimplemented, "method UpdateExternalVolume not implemented") +} +func (UnimplementedControlServer) DeleteExternalVolume(context.Context, *DeleteExternalVolumeRequest) (*ExternalVolume, error) { + return nil, status.Error(codes.Unimplemented, "method DeleteExternalVolume not implemented") +} func (UnimplementedControlServer) ListWorkers(context.Context, *ListWorkersRequest) (*ListWorkersResponse, error) { return nil, status.Error(codes.Unimplemented, "method ListWorkers not implemented") } @@ -1230,6 +1320,96 @@ func _Control_DeleteTag_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Control_CreateExternalVolume_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateExternalVolumeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServer).CreateExternalVolume(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Control_CreateExternalVolume_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServer).CreateExternalVolume(ctx, req.(*CreateExternalVolumeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Control_GetExternalVolume_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetExternalVolumeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServer).GetExternalVolume(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Control_GetExternalVolume_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServer).GetExternalVolume(ctx, req.(*GetExternalVolumeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Control_ListExternalVolumes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListExternalVolumesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServer).ListExternalVolumes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Control_ListExternalVolumes_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServer).ListExternalVolumes(ctx, req.(*ListExternalVolumesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Control_UpdateExternalVolume_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateExternalVolumeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServer).UpdateExternalVolume(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Control_UpdateExternalVolume_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServer).UpdateExternalVolume(ctx, req.(*UpdateExternalVolumeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Control_DeleteExternalVolume_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteExternalVolumeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServer).DeleteExternalVolume(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Control_DeleteExternalVolume_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServer).DeleteExternalVolume(ctx, req.(*DeleteExternalVolumeRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Control_ListWorkers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListWorkersRequest) if err := dec(in); err != nil { @@ -1727,6 +1907,26 @@ var Control_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeleteTag", Handler: _Control_DeleteTag_Handler, }, + { + MethodName: "CreateExternalVolume", + Handler: _Control_CreateExternalVolume_Handler, + }, + { + MethodName: "GetExternalVolume", + Handler: _Control_GetExternalVolume_Handler, + }, + { + MethodName: "ListExternalVolumes", + Handler: _Control_ListExternalVolumes_Handler, + }, + { + MethodName: "UpdateExternalVolume", + Handler: _Control_UpdateExternalVolume_Handler, + }, + { + MethodName: "DeleteExternalVolume", + Handler: _Control_DeleteExternalVolume_Handler, + }, { MethodName: "ListWorkers", Handler: _Control_ListWorkers_Handler, diff --git a/tools/apitool/internal/model/model.go b/tools/apitool/internal/model/model.go index bc299ef4b9..d9a6b381f2 100644 --- a/tools/apitool/internal/model/model.go +++ b/tools/apitool/internal/model/model.go @@ -558,6 +558,7 @@ var resourceNames = []string{ "Tag", "ActorTemplate", "Atespace", + "ExternalVolume", "Worker", }