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", }